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
elasticskin must remain installed - A web server able to serve static CSS files from Roundcube's
skinsdirectory
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
-
Copy the
eternitydirectory into the Roundcube installation'sskinsdirectory:cp -R eternity /var/www/roundcube/skins/ -
Ensure the web-server user can read the copied files:
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 {} \; -
Set the default skin in Roundcube's configuration. Add or update this line in
config/config.inc.php:$config['skin'] = 'eternity'; -
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.
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.
services:
roundcube:
volumes:
- ./ep-roundcube-skin/eternity:/var/www/html/skins/eternity: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
$config['skin'] = 'eternity';
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:
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.
-
Copy the skin from this repository into the container:
docker cp ./eternity roundcube:/var/www/html/skins/eternity -
Confirm Roundcube can see the skin files:
docker exec roundcube sh -c 'test -f /var/www/html/skins/eternity/meta.json && test -f /var/www/html/skins/eternity/styles/styles.css' -
Add
$config['skin'] = 'eternity';to the activeconfig.inc.phpin the container, then restart it: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/styles/styles.css returns HTTP 200.
Structure
eternity/
meta.json Skin registration and Elastic inheritance
styles/styles.css Visual overrides for Elastic
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.