A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys, Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun VPN routing, and a web dashboard to manage it all. Free & open forever to self-host; optional paid hosted services fund it. See PROMISE.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
56 lines
2.3 KiB
Markdown
56 lines
2.3 KiB
Markdown
# Custom Themes
|
|
|
|
Drop a folder here named after your theme and refresh the browser — the
|
|
topbar dropdown will pick it up automatically.
|
|
|
|
## Minimum
|
|
|
|
```
|
|
frontend/themes/<your-name>/
|
|
theme.css (required) — palette inside a [data-theme="<your-name>"] block
|
|
meta.json (optional) — { "displayName": "Pretty Name", "author": "you" }
|
|
```
|
|
|
|
The folder name (`<your-name>`) becomes the `data-theme` value. Use
|
|
lowercase + dashes — no spaces, no slashes.
|
|
|
|
## Tokens
|
|
|
|
Copy `frontend/themes/example/theme.css` as a starting point. Every CSS
|
|
variable defined there is what `style.css` and friends consume — change
|
|
the values, keep the names.
|
|
|
|
The visible-essentials list (override these at minimum):
|
|
|
|
| Token | What it controls |
|
|
| ------------------ | -------------------------------------- |
|
|
| `--surface-bg` | Body background (gradient or solid) |
|
|
| `--text-primary` | Default text colour |
|
|
| `--accent` | Theme's signature colour (manage btn) |
|
|
| `--accent-rgb` | Same colour as r,g,b for rgba() mixes |
|
|
| `--text-rgb` | `255,255,255` (dark) or `0,0,0` (light)|
|
|
| `--bg-rgb` | The opposite of `--text-rgb` |
|
|
|
|
Status colours (`--status-success`, `--status-danger`, `--status-warning`,
|
|
`--status-info`) are usually safe to leave as the defaults — they're
|
|
brand-stable across themes.
|
|
|
|
## How discovery works
|
|
|
|
On page load the frontend calls `GET /api/themes/list`. The backend walks
|
|
this directory, returns one entry per folder containing a `theme.css`, and
|
|
the frontend (`js/system/theme-registry.js`) injects each entry's CSS
|
|
into `<head>` and adds it to the topbar dropdown. The currently-saved
|
|
theme is `<link>`-loaded synchronously by the inline bootstrap in
|
|
`index.html` so first paint has the right palette — no flash.
|
|
|
|
The built-in themes (`nebula`, `dark-blue`, `light`) live in this folder
|
|
too — their `meta.json` files set `"builtin": true` so a future UI can
|
|
distinguish them (e.g. a "reset to built-ins" affordance). If you delete
|
|
a built-in folder you'll remove it from the dropdown; the app survives
|
|
but the deleted theme is gone until you put it back.
|
|
|
|
The dropdown orders themes by:
|
|
1. `nebula`, `dark-blue`, `light` (built-ins, in that fixed order)
|
|
2. Everything else, sorted by display name.
|