199 lines
10 KiB
Markdown
199 lines
10 KiB
Markdown
# Eternity Roundcube Skin
|
|
|
|
`Eternity` is a sharp editorial skin for Roundcube, built in the visual language of Eternity Project: paper-white surfaces, ink-black structure, acid-green actions, and orange signals. It extends Roundcube's maintained Elastic skin, retaining Elastic's responsive layout and interaction model while changing the visual treatment.
|
|
|
|
## Requirements
|
|
|
|
- Roundcube 1.6.x
|
|
- The bundled `elastic` skin must remain installed
|
|
- A web server able to serve static CSS files from Roundcube's `skins` directory
|
|
|
|
The skin has no build step and no PHP dependencies. Its font stacks use `Space Grotesk` and `DM Mono` when those fonts are available, then fall back to locally installed system fonts. This keeps the login screen usable without a third-party font request.
|
|
|
|
## Install
|
|
|
|
1. Copy the `eternity` directory into the Roundcube installation's `skins` directory:
|
|
|
|
```sh
|
|
cp -R eternity /var/www/roundcube/skins/
|
|
```
|
|
|
|
2. Ensure the web-server user can read the copied files:
|
|
|
|
```sh
|
|
chown -R www-data:www-data /var/www/roundcube/skins/eternity
|
|
find /var/www/roundcube/skins/eternity -type d -exec chmod 755 {} \;
|
|
find /var/www/roundcube/skins/eternity -type f -exec chmod 644 {} \;
|
|
```
|
|
|
|
3. Set the default skin in Roundcube's configuration. Add or update this line in `config/config.inc.php`:
|
|
|
|
```php
|
|
$config['skin'] = 'eternity';
|
|
```
|
|
|
|
4. Clear the browser cache, then load Roundcube. The login view, mailbox list, compose view, menus, controls, and status messages should all use the new palette.
|
|
|
|
## Eternity Wasteland
|
|
|
|
`eternity-wasteland` is the dark, warm-industrial Eternity variant. It uses the Wasteland palette: charcoal surfaces, parchment text, olive actions, rust-orange signals, and an orange technical grid.
|
|
|
|
Install it with the same procedure above, copying `eternity-wasteland` instead of `eternity`, then configure:
|
|
|
|
```php
|
|
$config['skin'] = 'eternity-wasteland';
|
|
```
|
|
|
|
### Login Theme Toggle
|
|
|
|
Wasteland opens in dark mode. Its login screen includes a **Dark mode** toggle that switches to the Eternity light palette without reloading the page. The choice is stored in the browser's `colorMode` cookie for one year and is applied on later visits to the login screen.
|
|
|
|
Clearing site cookies resets the Wasteland login screen to dark mode. This setting only changes the Wasteland login page; choose the desired Roundcube interface skin in **Settings > Preferences > User Interface > Interface skin** after signing in.
|
|
|
|
## Eternity Wasteland v2
|
|
|
|
`eternity-wasteland-v2` adapts the Daylight and Wasteland theme system from `docker-ep-blog-web-server/themes`. It opens in the paper-white Daylight palette and provides a **WASTELAND** control on the login screen. Selecting it switches the page to the warm charcoal Wasteland palette; the control then reads **DAYLIGHT** to switch back.
|
|
|
|
The login preference is stored in browser local storage as `ep-theme`. Clearing site storage resets the v2 login screen to Daylight. It is independent from the original `eternity-wasteland` skin's `colorMode` cookie.
|
|
|
|
Install it with the same procedure above, copying `eternity-wasteland-v2` and configuring:
|
|
|
|
```php
|
|
$config['skin'] = 'eternity-wasteland-v2';
|
|
```
|
|
|
|
## Docker Install
|
|
|
|
### Docker Compose (persistent)
|
|
|
|
Place this repository alongside the Compose file, then bind-mount the skin into the Roundcube service. The official `roundcube/roundcubemail` image exposes its application at `/var/www/html`.
|
|
|
|
```yaml
|
|
services:
|
|
roundcube:
|
|
volumes:
|
|
- ./ep-roundcube-skin/eternity-wasteland:/var/www/html/skins/eternity-wasteland:ro
|
|
- ./roundcube-config/config.inc.php:/var/roundcube/config/config.inc.php:ro
|
|
```
|
|
|
|
Create `./roundcube-config/config.inc.php` if it does not already exist and include the skin setting with the rest of the deployment configuration:
|
|
|
|
```php
|
|
<?php
|
|
|
|
$config['skin'] = 'eternity-wasteland';
|
|
```
|
|
|
|
The configuration mount location can vary for non-official images. Check the image documentation or run `docker compose exec roundcube sh -c 'find / -path "*/config.inc.php" 2>/dev/null'` to identify the active configuration file. Restart the service after changing either mount:
|
|
|
|
```sh
|
|
docker compose up -d --force-recreate roundcube
|
|
```
|
|
|
|
### Existing Running Container
|
|
|
|
Use this method to test the skin on a container that is already running. Replace `roundcube` with the container name or ID shown by `docker ps`.
|
|
|
|
1. Copy the skin from this repository into the container:
|
|
|
|
```sh
|
|
docker cp ./eternity-wasteland roundcube:/var/www/html/skins/eternity-wasteland
|
|
```
|
|
|
|
2. Confirm Roundcube can see the skin files:
|
|
|
|
```sh
|
|
docker exec roundcube sh -c 'test -f /var/www/html/skins/eternity-wasteland/meta.json && test -f /var/www/html/skins/eternity-wasteland/styles/styles.css'
|
|
```
|
|
|
|
3. Add `$config['skin'] = 'eternity-wasteland';` to the active `config.inc.php` in the container, then restart it:
|
|
|
|
```sh
|
|
docker restart roundcube
|
|
```
|
|
|
|
This live-container approach is not persistent: `docker compose up --force-recreate`, `docker rm`, or an image update removes the copied skin and in-container configuration change. Once the skin is confirmed, add the two bind mounts from the Compose example so both survive container recreation.
|
|
|
|
After either deployment method, hard-refresh the browser or clear its cache. If the old appearance remains, inspect the browser network panel to confirm that `/skins/eternity-wasteland/styles/styles.css` returns HTTP 200.
|
|
|
|
If instead the page looks entirely unstyled — login credential fields stacked in the wrong place, an oversized logo, or mailbox toolbars/tabs scattered and hard to read — `styles/styles.css` is loading but its `@import` of `../../elastic/styles/styles.css` is not, so none of Elastic's layout rules apply. Confirm that file exists and is readable:
|
|
|
|
```sh
|
|
docker exec roundcube sh -c 'test -f /var/www/html/skins/elastic/styles/styles.css && echo FOUND || echo MISSING'
|
|
```
|
|
|
|
If it is `MISSING`, the Elastic skin was installed from source without its LESS files being compiled (Elastic ships as `.less` sources and requires `make css-elastic` / `bin/updatecss.sh` to produce `styles/styles.css`). Reinstall Elastic from an official Roundcube release tarball, which ships the compiled CSS, rather than a bare git checkout.
|
|
|
|
### Verify A Running Container
|
|
|
|
Run these commands on the Docker host, replacing `roundcube` with the container name or ID from `docker ps`. They distinguish an installation issue from an activation issue:
|
|
|
|
```sh
|
|
docker exec roundcube sh -c 'for file in /var/www/html/skins/eternity-wasteland/meta.json /var/www/html/skins/eternity-wasteland/styles/styles.css /var/www/html/skins/elastic/styles/styles.css; do test -f "$file" && echo "FOUND $file" || echo "MISSING $file"; done'
|
|
docker exec roundcube sh -c 'grep -RIn "\$config\[.skin.\]" /var/roundcube/config /var/www/html/config 2>/dev/null || true'
|
|
```
|
|
|
|
The first command must report all three paths as `FOUND`. The second must show `eternity-wasteland` as the configured skin. On the official image, the equivalent persistent environment setting is:
|
|
|
|
```yaml
|
|
environment:
|
|
ROUNDCUBEMAIL_SKIN: eternity-wasteland
|
|
```
|
|
|
|
Roundcube can store a skin preference for each user. A user who previously selected another appearance may continue to receive that preference instead of the newly configured default. Sign out and test in a private browser window or select **Eternity** from Roundcube's **Settings > Preferences > User Interface > Interface skin**, when the preference is available.
|
|
|
|
For a browser-level check, open this URL directly, replacing the hostname with the Roundcube site:
|
|
|
|
```text
|
|
https://webmail.example.com/skins/eternity-wasteland/styles/styles.css
|
|
```
|
|
|
|
It must return CSS beginning with `@import url("../../elastic/styles/styles.css");`. A `404` means the skin is not mounted at the path served by the container. If it returns `200` but Roundcube still looks unchanged, inspect the mailbox page source: it must include a stylesheet URL containing `/skins/eternity-wasteland/styles/styles.css`. If it instead contains `/skins/elastic/`, the active configuration or the user's stored preference still selects Elastic.
|
|
|
|
## Structure
|
|
|
|
```text
|
|
eternity/
|
|
meta.json Skin registration and Elastic inheritance
|
|
styles/styles.css Visual overrides for Elastic
|
|
eternity-wasteland/
|
|
images/logo.svg High-contrast Wasteland login mark
|
|
meta.json Skin registration and Elastic inheritance
|
|
styles/styles.css Dark and light Wasteland visual overrides
|
|
templates/login.html Login form with the theme toggle
|
|
watermark.html Wasteland login background
|
|
eternity-wasteland-v2/
|
|
images/logo.svg Daylight login mark with a dark-mode CSS treatment
|
|
meta.json Skin registration and Elastic inheritance
|
|
styles/styles.css Source-theme Daylight and Wasteland visual overrides
|
|
templates/login.html Login form with the Daylight/Wasteland control
|
|
watermark.html Login background that follows ep-theme
|
|
```
|
|
|
|
`styles/styles.css` imports Elastic before applying Eternity's overrides. Do not remove the import: the base skin provides the complete component layout and image assets.
|
|
|
|
## Customize
|
|
|
|
The visual palette is declared at the top of `eternity/styles/styles.css`:
|
|
|
|
| Token | Value | Role |
|
|
| --- | --- | --- |
|
|
| `--ink` | `#11212b` | Primary text, borders, and primary controls |
|
|
| `--paper` | `#f1f1e9` | Page and surface background |
|
|
| `--acid` | `#c7ef4b` | Primary hover, selection, and success state |
|
|
| `--orange` | `#ff6b35` | Links, secondary hover, quota, and error signal |
|
|
| `--line` | `#b9c5bc` | Quiet dividers |
|
|
| `--muted` | `#59706b` | Secondary text |
|
|
|
|
Change these variables to retheme the interface while preserving the semantic states. Test login, inbox, compose, contacts, settings, search, and mobile navigation after any update to Roundcube or Elastic.
|
|
|
|
## Upgrade Notes
|
|
|
|
This is an Elastic child skin. When updating Roundcube, keep the `eternity` directory in place and confirm that the upstream Elastic stylesheet remains at `skins/elastic/styles/styles.css`. Recopy the skin after deployments that replace the whole Roundcube `skins` directory.
|
|
|
|
The skin intentionally uses direct CSS selectors for stable Roundcube surfaces and CSS custom properties for broad Elastic integration. If a future Roundcube release renames markup, inspect that release's Elastic stylesheet and update the matching override selector here.
|
|
|
|
## License
|
|
|
|
Licensed under the GNU Affero General Public License, version 3 or later. See [LICENSE](LICENSE).
|