mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-12 07:26:33 +02:00
180 lines
7.7 KiB
Markdown
180 lines
7.7 KiB
Markdown
# Themes
|
||
|
||
P4RS3LT0NGV3 uses a **token-based theme system**. Most UI reads CSS custom properties (`--accent-color`, `--button-bg`, etc.) from `body.theme-*` blocks, so new themes are mostly palette + typography work—not per-component rewrites.
|
||
|
||
## Built-in themes
|
||
|
||
| ID | Name | Notes |
|
||
|----|------|--------|
|
||
| `dark` | Dark | Default; blue accent |
|
||
| `light` | Light | Light surfaces; blue accent |
|
||
| `accessible` | Accessible | WCAG 2.1 AA high-contrast; system fonts; strong focus rings |
|
||
| `bt6` | BT6 | Black + blood red + gold; mono titles |
|
||
| `pliny` | Pliny | CRT green-on-black |
|
||
| `cyberpunk` | Cyberpunk | Magenta + cyan neon |
|
||
| `wildwest` | Wild West | Cream / sage / dusty rose (light `color-scheme`) |
|
||
|
||
Users pick a theme in **Advanced Settings** (utility dock → Settings tab). Press **`D`** to cycle themes. The choice is saved in `localStorage` under the key `theme`.
|
||
|
||
## Accessible theme
|
||
|
||
The **`accessible`** theme targets **[WCAG 2.1 Level AA](https://www.w3.org/TR/WCAG21/)** for color, contrast, focus, and motion.
|
||
|
||
| Requirement | Implementation |
|
||
|-------------|------------------|
|
||
| **1.4.3 Contrast (AA)** | `#000000` / `#595959` text on `#ffffff`; `#004080` accent; category active colors darkened for white labels |
|
||
| **1.4.11 Non-text contrast** | `2px` borders at `#555555` on inputs, buttons, and cards |
|
||
| **2.4.7 Focus visible** | `3px` `#004080` outline + `2px` offset on all interactive elements |
|
||
| **1.4.12 Text spacing** | `1rem` base size, `1.5` line-height, system UI fonts |
|
||
| **1.4.1 Use of color** | Active nav/tabs use underline + weight + border, not color alone |
|
||
| **2.3.3 Animation** | Logo glitch and decorative card effects disabled |
|
||
| **Transform cards** | Text **Options** / **Favorite** buttons; fixed preview contrast and row heights |
|
||
| **Translation picker** | Text **Favorite** (and **Remove** on custom langs); star/× icons hidden |
|
||
|
||
Decorative themes (Cyberpunk, Pliny, etc.) are unchanged. For audits, test with the **Accessible** theme selected and keyboard-only navigation.
|
||
|
||
## How it works
|
||
|
||
1. **`js/utils/theme.js`** — Registry (`themes` array), `applyTheme()`, `cycleTheme()`, persistence.
|
||
2. **`css/style.css`** — One `body.theme-<id> { … }` block per theme defining design tokens.
|
||
3. **`css/themes-atmosphere.css`** — Optional “premium” overrides for custom themes (nav, transform cards, backgrounds, fonts). Imported at the top of `style.css`.
|
||
4. **`index.template.html`** — Inline bootstrap script applies the saved theme **before** Vue mounts (avoids flash of wrong theme).
|
||
|
||
When a theme is applied, the body gets:
|
||
|
||
- `theme-<id>` — primary selector (e.g. `theme-bt6`)
|
||
- `dark-theme` or `light-theme` — legacy aliases still used by a few rules
|
||
|
||
Copy an existing `body.theme-*` block as a starting point—`body.theme-dark` and `body.theme-light` are the simplest references; custom themes often follow the BT6 / Pliny pattern.
|
||
|
||
## Adding a new theme
|
||
|
||
### 1. Register in `js/utils/theme.js`
|
||
|
||
```javascript
|
||
{ id: 'mytheme', name: 'My Theme', icon: 'fa-star' }
|
||
```
|
||
|
||
- **`id`** — lowercase, no spaces; becomes `body.theme-mytheme`.
|
||
- **`name`** — label in the dropdown.
|
||
- **`icon`** — optional Font Awesome class (not shown in dropdown today, but kept for future use).
|
||
|
||
### 2. Add tokens in `css/style.css`
|
||
|
||
Add a new block (copy from `body.theme-dark` or an existing custom theme):
|
||
|
||
```css
|
||
body.theme-mytheme {
|
||
--main-bg-color: #…;
|
||
--secondary-bg: #…;
|
||
--nav-bg: #…;
|
||
--utility-tab-bg: #…;
|
||
--text-color: #…;
|
||
--text-muted: #…;
|
||
--accent-color: #…;
|
||
--accent-color-rgb: R, G, B; /* comma-separated, no spaces */
|
||
--accent-hover: #…;
|
||
/* … accent-tint-*, surface-*, button-*, input-*, error-*, etc. */
|
||
--glitch-color: #…;
|
||
--glitch-color-rgb: R, G, B;
|
||
--switch-border: #…;
|
||
--switch-surface-glow: rgba(…);
|
||
--switch-track-bg: #…;
|
||
--switch-track-border: #…;
|
||
--switch-track-checked-bg: #…;
|
||
--switch-track-checked-glow: rgba(…);
|
||
--switch-thumb-bg: #…;
|
||
--switch-thumb-glow: rgba(…);
|
||
--switch-thumb-checked-bg: #…;
|
||
--switch-thumb-checked-glow: rgba(…);
|
||
color-scheme: dark; /* or light for pale themes */
|
||
}
|
||
```
|
||
|
||
**Required tokens** — At minimum, match what `body.theme-dark` defines: surfaces, text, accent (+ `-rgb`), buttons, inputs, focus/error/success, tooltips, switch tokens, and legacy aliases (`--text-primary`, `--border-color`, etc.) at the bottom of the block.
|
||
|
||
**Light themes** — Set `color-scheme: light` and ensure `--text-on-accent` contrasts on `--accent-color`. Wild West is the reference for a light custom theme.
|
||
|
||
**Optional theme tokens** (used by atmosphere CSS):
|
||
|
||
- `--theme-display-font`, `--theme-ui-font`, `--theme-mono-font`
|
||
- `--theme-secondary`, `--theme-secondary-rgb`
|
||
- `--theme-radius` — corner radius (`0` for sharp, `2px`–`6px` for rounded)
|
||
- Wild West also uses `--theme-cream`, `--theme-charcoal`, etc.
|
||
|
||
### 3. Optional atmosphere in `css/themes-atmosphere.css`
|
||
|
||
For a distinctive look beyond color swaps, add a section:
|
||
|
||
```css
|
||
body.theme-mytheme .app-root::before { /* background texture / tint */ }
|
||
body.theme-mytheme .transform-button { /* card chrome */ }
|
||
body.theme-mytheme .app-nav .tab-buttons button.active { /* nav active state */ }
|
||
```
|
||
|
||
If you add a custom theme here, also extend the shared selectors at the top of the file (`body[class*="theme-…"]`) so shell layering (`::before` / z-index) stays consistent.
|
||
|
||
**Style guidelines** (project convention):
|
||
|
||
- Use **flat colors** only—no CSS gradients unless explicitly requested.
|
||
- Toggle switches (`.switch.neon`) pick up colors from `--switch-*` tokens automatically.
|
||
- Avoid logo `::before` / `::after` decorations.
|
||
|
||
### 4. Fonts (if needed)
|
||
|
||
Google Fonts are imported at the top of `css/style.css`. Add families there, then reference them in your `--theme-*-font` tokens.
|
||
|
||
### 5. Select carets & dropdowns
|
||
|
||
Custom themes with non-default accents often need a `select` caret override. See existing blocks:
|
||
|
||
```css
|
||
body.theme-mytheme select:not(.settings-theme-select) { background-image: url("data:…"); }
|
||
body.theme-mytheme .settings-theme-select { … }
|
||
```
|
||
|
||
Wild West required extra care so theme dropdown carets do not tile—use `background-repeat: no-repeat` and longhand `background-*` when overriding selects.
|
||
|
||
### 6. Build & test
|
||
|
||
```bash
|
||
npm run build
|
||
npm test
|
||
```
|
||
|
||
Open `dist/index.html` (or `npm start`) and check:
|
||
|
||
- [ ] Advanced Settings theme dropdown lists your theme
|
||
- [ ] **`D`** cycles through it without errors
|
||
- [ ] Nav, main content, utility dock (desktop)
|
||
- [ ] Mobile: utility panel toggle in header; no overlapping FAB
|
||
- [ ] Transform grid, toggles, inputs, notifications
|
||
- [ ] Advanced Settings / OpenRouter model dropdown (if applicable)
|
||
- [ ] Reload persists choice
|
||
|
||
No change to `index.template.html` is required unless you rename the bootstrap script flow—the dropdown is driven by `themeOptions` from Vue, which reads `ThemeUtils.getThemes()`.
|
||
|
||
## File checklist
|
||
|
||
| File | Action |
|
||
|------|--------|
|
||
| `js/utils/theme.js` | Add `{ id, name, icon }` |
|
||
| `css/style.css` | Add `body.theme-<id> { … }` token block |
|
||
| `css/themes-atmosphere.css` | Optional component/atmosphere overrides |
|
||
| `css/style.css` `@import` | Already imports `themes-atmosphere.css` — no change |
|
||
| `README.md` | Add theme to user-facing list (optional) |
|
||
|
||
## Updating an existing theme
|
||
|
||
1. Edit the `body.theme-<id>` token block in `css/style.css`.
|
||
2. Adjust matching rules in `css/themes-atmosphere.css` if the theme has premium styling.
|
||
3. Rebuild and spot-check the same checklist above.
|
||
|
||
Token changes propagate everywhere that uses `var(--…)`; you rarely need to touch individual tools or templates.
|
||
|
||
## Related docs
|
||
|
||
- **User-facing overview**: `README.md` → User Experience
|
||
- **Project layout**: `CONTRIBUTING.md` → Project Structure
|
||
- **UI patterns**: `docs/UI-COMPONENTS.md`
|