css: remove dark mode, unify token system, eliminate all hardcoded colors

- Remove @media (prefers-color-scheme: dark) block from variables.css
- Delete colors.css (dead reference doc, never loaded)
- Add semantic tokens to variables.css:
    --header-gradient-fade, --header-shadow-strong/soft, --header-nav-active-border
    --search-error-bg/border/color
    --sys-bg-surface/deep/panel, --sys-border/border-deep/border-hover
    --sys-text-dim/bright/body, --sys-overlay, --sys-syntax-* (7 highlight tokens)
    --success/warning/error/blue/yellow/green -muted-bg/border/hover alpha overlays
    --danger-border-muted
- Replace all hardcoded hex/rgba in common.css, main.css, search.css, admin.css, system.css
- Fix --border-color typo -> --border-primary in search.css
- Fix view-toggle__btn active color: --text-primary -> --accent-foreground
- Admin and public share identical token set, no separate admin theme
- Update README.md
This commit is contained in:
Pontoporeia
2026-04-06 16:16:11 +02:00
parent e73fcfd0c8
commit 6a1b41ac93
9 changed files with 183 additions and 212 deletions

View File

@@ -11,6 +11,8 @@ Pending tasks have been split into topic files under [`todo/`](todo/README.md):
## Recently completed (this session)
- [x] CSS cleanup — removed dark-mode `@media (prefers-color-scheme: dark)` block from `variables.css`; deleted dead `colors.css` reference file; added all missing semantic tokens to `variables.css` (`--header-*`, `--search-error-*`, `--sys-*` dark-terminal tokens, `--*-muted-bg/border/hover` alpha overlay tokens); replaced every hardcoded hex/rgba in `common.css`, `main.css`, `search.css`, `admin.css`, `system.css` with `var()` references; fixed `--border-color` typo → `--border-primary` in `search.css`; fixed `view-toggle__btn` active color to use `--accent-foreground`; updated `README.md`; admin and public now share identical token set with zero duplication
- [x] `pages-edit.php` — replaced EasyMDE (333 KB: 320 KB JS + 13 KB CSS) with OverType (118 KB, single JS file, no CSS); removed `easymde.min.js` and `easymde.min.css` from `public/assets/`; vendored `overtype.min.js`; replaced `<textarea name="content">` + 60-line EasyMDE toolbar/SVG init block with `<input type="hidden" name="content">` + `<div id="editor">` mount target + 6-line OverType init; `onChange` callback keeps the hidden input in sync for form submission; net saving: ~215 KB, ~54 lines of JS
- [x] `templates/header.php` + `admin.css` — extracted last remaining inline `style=` from any shared template: `style="vertical-align:middle;margin-right:0.4em"` on the admin-nav public-site SVG icon moved to `.admin-body header nav > a svg` rule in `admin.css`; `templates/header.php` now contains zero `style=` attributes; only the dynamic gradient (`hsl(<?= $hue ?>)`) in `public/index.php` and the PHP-runtime `--disk-pct`/`--disk-color` custom properties in `system.php` remain (both legitimately dynamic)

View File

@@ -2,34 +2,20 @@
## File Structure
- **variables.css** - CSS custom properties (variables) for colors and theme values
- **colors.css** - Reference documentation of all color values used in the project
- **common.css** - Shared styles: reset, header/nav, search bar, accessibility utilities
- **main.css** - Home page styles
- **admin.css** - Admin section styles
- **system.css** - System page styles
- **search.css** - Search/Directory page styles
- **apropos.css** - About page styles
- **tfe.css** - Individual thesis page styles
- **easymde.min.css** - EasyMDE editor styles (minified, third-party)
- **modern-normalize.min.css** - Modern normalize reset (minified, third-party)
- **variables.css** — all CSS custom properties (single source of truth for every color/token)
- **common.css** — reset, header/nav, search bar, accessibility utilities (loaded on all pages)
- **main.css** — home page
- **search.css** — search/directory page
- **tfe.css** — individual thesis page
- **apropos.css** — about + licence pages
- **system.css** — admin system dashboard (dark terminal panels)
- **admin.css** — admin section (loaded alongside `common.css` on every admin page)
- **modern-normalize.min.css** — third-party reset (minified, do not edit)
## Imports
## Rules
All CSS files automatically import `variables.css` to access CSS custom properties.
## Variables
### Shared Variables (public pages)
- `--purple`, `--purple-dark`, `--purple-light` - Purple palette
- `--black`, `--white` - Base colors
- `--grey-light` - Light grey background
- `--border-color` - Border color
- `--text-muted` - Muted text color
### Admin Variables
- `--admin-bg`, `--admin-bg-alt` - Background colors
- `--admin-border` - Border color
- `--admin-text`, `--admin-text-muted` - Text colors
- `--admin-purple` - Accent color
- `--admin-input-bg` - Input background
- Every color value lives in `variables.css` as a CSS custom property.
- No hardcoded hex, rgb(), or rgba() in any other file.
- All files `@import url("./variables.css")` at the top.
- Admin and public share the same token names — no separate admin theme.
- No dark-mode media query. The system page uses `--sys-*` tokens (intentionally dark terminal aesthetic).

View File

@@ -300,7 +300,7 @@
}
[role="status"][data-type="success"] {
background: rgba(92, 214, 157, 0.12);
background: var(--success-muted-bg);
border-color: var(--success);
color: var(--text-primary);
}
@@ -354,7 +354,7 @@
}
.admin-maintenance-bar--active {
background: rgba(251, 202, 81, 0.1);
background: var(--warning-muted-bg);
border-color: var(--warning);
color: var(--text-primary);
}
@@ -503,12 +503,12 @@
}
.status-published {
background: rgba(76, 175, 80, 0.12);
background: var(--green-muted-bg);
color: var(--accent-green);
}
.status-pending {
background: rgba(251, 202, 81, 0.12);
background: var(--warning-muted-bg);
color: var(--warning);
}
@@ -523,17 +523,17 @@
}
.status-access--libre {
background: rgba(76, 175, 80, 0.12);
background: var(--green-muted-bg);
color: var(--accent-green);
}
.status-access--interne {
background: rgba(65, 173, 255, 0.12);
background: var(--blue-muted-bg);
color: var(--accent-blue);
}
.status-access--interdit {
background: rgba(242, 90, 90, 0.12);
background: var(--error-muted-bg);
color: var(--error);
}
@@ -560,30 +560,30 @@
}
.admin-btn-view {
background: rgba(65, 173, 255, 0.12);
background: var(--blue-muted-bg);
color: var(--accent-blue);
border-color: rgba(65, 173, 255, 0.3);
border-color: var(--blue-muted-border);
}
.admin-btn-view:hover {
background: rgba(65, 173, 255, 0.22);
background: var(--blue-muted-bg-hover);
}
.admin-btn-edit {
background: rgba(243, 156, 18, 0.12);
background: var(--yellow-muted-bg);
color: var(--accent-yellow);
border-color: rgba(243, 156, 18, 0.3);
border-color: var(--yellow-muted-border);
}
.admin-btn-edit:hover {
background: rgba(243, 156, 18, 0.22);
background: var(--yellow-muted-bg-hover);
}
.admin-btn-publish {
background: rgba(76, 175, 80, 0.12);
background: var(--green-muted-bg);
color: var(--accent-green);
border-color: rgba(76, 175, 80, 0.3);
border-color: var(--green-muted-border);
}
.admin-btn-publish:hover {
background: rgba(76, 175, 80, 0.22);
background: var(--green-muted-bg-hover);
}
.admin-btn-unpublish {
@@ -701,7 +701,7 @@
/* ── Danger zone (account page) ─────────────────────────────────────────── */
.admin-danger-zone {
border: 1px solid rgba(242, 90, 90, 0.35);
border: 1px solid var(--danger-border-muted);
border-radius: 4px;
padding: 1.25rem 1.5rem;
display: flex;

View File

@@ -1,39 +0,0 @@
/* ============================================================
COLOR VALUES REFERENCE
============================================================ */
/* Background colors */
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--bg-tertiary: #e8e8e8;
--bg-active: #d0d0d0;
/* Text colors */
--text-primary: #111111;
--text-secondary: #666666;
--text-tertiary: #999999;
/* Border colors */
--border-primary: #ddd;
--border-secondary: #ccc;
/* Status colors */
--success: #5cd69d;
--error: #f25a5a;
--warning: #fbca51;
/* Accent colors */
--accent-primary: #9557b5;
--accent-secondary: #683d7f;
--accent-foreground: #ffffff;
--accent-muted: rgba(149, 87, 181, 0.12);
--accent-blue: #41adff;
--accent-green: #4caf50;
--accent-yellow: #f39c12;
--accent-red: #f25a5a;
/* Gradient colors */
--gradient-start: #3C856C;
--gradient-2: #60ECB4;
--gradient-3: #E390FF;
--gradient-4: #9557B5;

View File

@@ -48,7 +48,7 @@ header {
var(--gradient-3) 40%,
var(--gradient-4) 60%,
var(--gradient-4) 88%,
rgba(149, 87, 181, 0) 96%
var(--header-gradient-fade) 96%
);
}
@@ -91,7 +91,7 @@ header nav ul a {
/* Subtle shadow on all header text to improve legibility against the gradient */
header nav > a,
header nav ul a {
text-shadow: 0 0 16px rgba(119, 70, 145, 1), 0 0 32px rgba(119, 70, 145, 0.8);
text-shadow: 0 0 16px var(--header-shadow-strong), 0 0 32px var(--header-shadow-soft);
}
header nav ul a:hover {
@@ -100,7 +100,7 @@ header nav ul a:hover {
header nav ul a[aria-current="page"] {
opacity: 1;
border-bottom: 1px solid rgba(255, 255, 255, 0.6);
border-bottom: 1px solid var(--header-nav-active-border);
padding-bottom: 1px;
}

View File

@@ -107,7 +107,7 @@
}
.card__gradient-author {
color: #ffffff;
color: var(--accent-foreground);
font-size: 0.75rem;
opacity: .85;
margin-bottom: .25rem;
@@ -115,7 +115,7 @@
}
.card__gradient-title {
color: #ffffff;
color: var(--accent-foreground);
font-size: 0.85rem;
font-weight: 600;
display: -webkit-box;

View File

@@ -36,7 +36,7 @@
.repertoire-col {
border-right: none;
border-bottom: 1px solid var(--border-color);
border-bottom: 1px solid var(--border-primary);
padding: 1rem 0 1.25rem;
}
@@ -191,7 +191,7 @@
.view-toggle__btn.active,
.view-toggle__btn:hover {
background: var(--accent-primary);
color: var(--text-primary);
color: var(--accent-foreground);
}
/* Search controls bar */

View File

@@ -8,7 +8,7 @@
.sys-tabs {
display: flex;
gap: 0;
border-bottom: 1px solid #555;
border-bottom: 1px solid var(--sys-border);
margin-bottom: 1.75rem;
}
.sys-tab {
@@ -16,14 +16,14 @@
padding: .55rem 1.1rem;
font-size: .84rem;
font-weight: 500;
color: #969696;
color: var(--sys-text-dim);
text-decoration: none;
border-bottom: 2px solid transparent;
margin-bottom: -1px;
transition: color .15s, border-color .15s;
}
.sys-tab:hover {
color: #e8e8e8;
color: var(--sys-text-bright);
}
.sys-tab.active {
color: var(--accent-primary);
@@ -32,8 +32,8 @@
/* ── Status section (always-visible panel above tabs) ─────────────────── */
.sys-status-section {
background: #1a1a1a;
border: 1px solid #555;
background: var(--sys-bg-panel);
border: 1px solid var(--sys-border);
border-radius: 6px;
padding: 1rem 1.25rem 1.25rem;
margin-bottom: 1.75rem;
@@ -46,8 +46,8 @@
}
.sys-status-toggle {
background: none;
border: 1px solid #555;
color: #969696;
border: 1px solid var(--sys-border);
color: var(--sys-text-dim);
border-radius: 3px;
font-size: .72rem;
font-family: inherit;
@@ -57,8 +57,8 @@
transition: color .15s, border-color .15s;
}
.sys-status-toggle:hover {
color: #e8e8e8;
border-color: #888;
color: var(--sys-text-bright);
border-color: var(--sys-border-hover);
}
.sys-status-meta {
display: grid;
@@ -66,7 +66,7 @@
gap: 1.5rem 2rem;
margin-top: 1.5rem;
padding-top: 1.25rem;
border-top: 1px solid #333;
border-top: 1px solid var(--sys-border-deep);
}
@media (max-width: 700px) {
.sys-status-meta { grid-template-columns: 1fr; }
@@ -80,8 +80,8 @@
margin-bottom: 2.5rem;
}
.srv-card {
background: #242424;
border: 1px solid #555;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
border-radius: 5px;
padding: 1rem 1.25rem;
}
@@ -95,12 +95,12 @@
font-size: .82rem;
text-transform: uppercase;
letter-spacing: .07em;
color: #969696;
color: var(--sys-text-dim);
font-weight: 500;
}
.srv-card__detail {
font-size: .8rem;
color: #969696;
color: var(--sys-text-dim);
margin-top: .25rem;
font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
}
@@ -113,8 +113,8 @@
font-size: .82rem;
text-transform: uppercase;
letter-spacing: .1em;
color: #969696;
border-bottom: 1px solid #555;
color: var(--sys-text-dim);
border-bottom: 1px solid var(--sys-border);
padding-bottom: .4rem;
margin: 0 0 1rem;
font-weight: 500;
@@ -138,8 +138,8 @@
/* Flush variant: no bottom margin — used inside sys-status-meta cell */
.php-grid--flush { margin-bottom: 0; }
.php-item {
background: #242424;
border: 1px solid #555;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
border-radius: 4px;
padding: .5rem .75rem;
}
@@ -147,18 +147,18 @@
font-size: .75rem;
text-transform: uppercase;
letter-spacing: .06em;
color: #969696;
color: var(--sys-text-dim);
}
.php-item__val {
font-size: .92rem;
font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
color: #e8e8e8;
color: var(--sys-text-bright);
margin-top: .15rem;
}
/* ── Disk bar ──────────────────────────────────────────────────────────── */
.disk-bar-wrap {
background: #555;
background: var(--sys-border);
border-radius: 3px;
height: 6px;
margin-top: .5rem;
@@ -176,7 +176,7 @@
display: flex;
justify-content: space-between;
font-size: .78rem;
color: #969696;
color: var(--sys-text-dim);
margin-top: .25rem;
}
@@ -198,8 +198,8 @@
-45deg,
transparent,
transparent 6px,
rgba(255,255,255,.03) 6px,
rgba(255,255,255,.03) 12px
var(--sys-overlay) 6px,
var(--sys-overlay) 12px
);
border-radius: 4px;
animation: sys-panel-shimmer 1s linear infinite;
@@ -223,9 +223,9 @@
color: var(--text-secondary);
}
.log-toolbar select {
background: #242424;
border: 1px solid #555;
color: #e8e8e8;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
color: var(--sys-text-bright);
border-radius: 4px;
padding: .4rem .7rem;
font-size: .85rem;
@@ -235,7 +235,7 @@
.log-meta {
font-size: .78rem;
color: #969696;
color: var(--sys-text-dim);
font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
margin-bottom: .75rem;
display: flex;
@@ -245,11 +245,11 @@
.log-meta span::before { content: attr(data-label) ": "; opacity: .6; }
.log-unavailable {
background: #242424;
border: 1px solid #555;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
border-radius: 4px;
padding: 1.5rem;
color: #969696;
color: var(--sys-text-dim);
font-size: .88rem;
}
.log-unavail-path {
@@ -264,13 +264,13 @@
opacity: .7;
}
.log-empty {
color: #969696;
color: var(--sys-text-dim);
font-size: .88rem;
padding: 1rem 0;
}
.log-output {
background: #0d0d0d;
border: 1px solid #555;
background: var(--sys-bg-deep);
border: 1px solid var(--sys-border);
border-radius: 4px;
padding: 1rem;
overflow-x: auto;
@@ -286,13 +286,13 @@
white-space: pre;
padding: .05rem .1rem;
border-radius: 2px;
color: #bbb;
color: var(--sys-text-body);
}
.log-line + .log-line { border-top: 1px solid rgba(255,255,255,.03); }
.log-crit { color: #ff7070; background: rgba(242, 90, 90, 0.12); }
.log-line + .log-line { border-top: 1px solid var(--sys-overlay); }
.log-crit { color: var(--sys-syntax-crit); background: var(--error-muted-bg); }
.log-error { color: var(--error); }
.log-warn { color: var(--warning); }
.log-notice { color: #a0c8ff; }
.log-notice { color: var(--sys-syntax-notice); }
.log-line::before {
content: attr(data-n);
display: inline-block;
@@ -303,21 +303,21 @@
user-select: none;
}
.log-count-badge {
background: #242424;
border: 1px solid #555;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
border-radius: 3px;
font-size: .76rem;
padding: .15rem .5rem;
color: #969696;
color: var(--sys-text-dim);
font-family: ui-monospace, monospace;
}
.log-copy-btn {
position: absolute;
top: .6rem;
right: .6rem;
background: #242424;
border: 1px solid #555;
color: #969696;
background: var(--sys-bg-surface);
border: 1px solid var(--sys-border);
color: var(--sys-text-dim);
border-radius: 4px;
font-size: .76rem;
padding: .25rem .6rem;
@@ -327,7 +327,7 @@
z-index: 2;
}
.log-copy-btn:hover {
color: #e8e8e8;
color: var(--sys-text-bright);
border-color: var(--accent-primary);
}
.log-copy-btn.copied {
@@ -337,7 +337,7 @@
.sys-refresh-note {
font-size: .78rem;
color: #969696;
color: var(--sys-text-dim);
margin-bottom: 1.25rem;
}
.sys-refresh-note a {
@@ -359,14 +359,14 @@
line-height: 1.6;
}
.sys-cache-badge--hit {
background: rgba(251, 202, 81, 0.12);
background: var(--warning-muted-bg);
color: var(--warning);
border: 1px solid rgba(251, 202, 81, 0.35);
border: 1px solid var(--warning-muted-border);
}
.sys-cache-badge--miss {
background: rgba(92, 214, 157, 0.12);
background: var(--success-muted-bg);
color: var(--success);
border: 1px solid rgba(92, 214, 157, 0.35);
border: 1px solid var(--success-muted-border);
}
/* ── Nginx config viewer ───────────────────────────────────────────────── */
@@ -380,18 +380,18 @@
vertical-align: middle;
}
.nginx-source-badge--live {
background: rgba(92, 214, 157, 0.15);
background: var(--success-muted-bg);
color: var(--success);
border: 1px solid rgba(92, 214, 157, 0.35);
border: 1px solid var(--success-muted-border);
}
.nginx-source-badge--local {
background: rgba(251, 202, 81, 0.12);
background: var(--warning-muted-bg);
color: var(--warning);
border: 1px solid rgba(251, 202, 81, 0.35);
border: 1px solid var(--warning-muted-border);
}
/* Nginx syntax highlight layers inside .log-output */
.nginx-comment { color: #666; font-style: italic; }
.nginx-directive { color: #7eb8f7; }
.nginx-block { color: #d4a0ff; font-weight: 600; }
.nginx-value { color: #e2c08d; }
.nginx-location { color: #79dac8; }
.nginx-comment { color: var(--sys-syntax-comment); font-style: italic; }
.nginx-directive { color: var(--sys-syntax-directive); }
.nginx-block { color: var(--sys-syntax-block); font-weight: 600; }
.nginx-value { color: var(--sys-syntax-value); }
.nginx-location { color: var(--sys-syntax-location); }

View File

@@ -2,20 +2,28 @@
CSS VARIABLES (CUSTOM PROPERTIES)
============================================================ */
/* ── Light mode (default) ─────────────────────────────────────────────── */
:root {
/* Backgrounds */
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--bg-tertiary: #e8e8e8;
--bg-active: #d0d0d0;
/* Text */
--text-primary: #111111;
--text-secondary: #666666;
--text-tertiary: #999999;
--border-primary: #ddd;
--border-secondary: #ccc;
/* Borders */
--border-primary: #dddddd;
--border-secondary: #cccccc;
/* Status */
--success: #5cd69d;
--error: #f25a5a;
--warning: #fbca51;
/* Accent */
--accent-primary: #9557b5;
--accent-secondary: #683d7f;
--accent-foreground: #ffffff;
@@ -24,46 +32,60 @@
--accent-green: #4caf50;
--accent-yellow: #f39c12;
--accent-red: #f25a5a;
--gradient-start: #3C856C;
--gradient-2: #60ECB4;
--gradient-3: #E390FF;
--gradient-4: #9557B5;
/* Search error block (public only, overridden in dark mode) */
--search-error-bg: #fff0f0;
--search-error-border: #c00;
--search-error-color: #c00;
}
/* Gradient (header) */
--gradient-start: #3c856c;
--gradient-2: #60ecb4;
--gradient-3: #e390ff;
--gradient-4: #9557b5;
/* ── Dark mode — public pages only (.admin-body keeps light vars) ─────── */
@media (prefers-color-scheme: dark) {
body:not(.admin-body) {
--bg-primary: #111111;
--bg-secondary: #1a1a1a;
--bg-tertiary: #252525;
--bg-active: #333333;
--text-primary: #eeeeee;
--text-secondary: #aaaaaa;
--text-tertiary: #777777;
--border-primary: #333333;
--border-secondary: #444444;
/* Accent hue lightened for contrast on dark bg (4.5:1 against #111) */
--accent-primary: #b87fd4;
--accent-secondary: #9557b5;
--accent-foreground: #111111;
--accent-muted: rgba(184, 127, 212, 0.15);
/* Status colours — slightly muted on dark */
--success: #4db886;
--error: #e05555;
--warning: #d4a830;
/* Header decorative */
--header-gradient-fade: rgba(149, 87, 181, 0);
--header-shadow-strong: rgba(119, 70, 145, 1);
--header-shadow-soft: rgba(119, 70, 145, 0.8);
--header-nav-active-border: rgba(255, 255, 255, 0.6);
/* Search error block */
--search-error-bg: #2a1515;
--search-error-border: #e05555;
--search-error-color: #e05555;
}
--search-error-bg: #fff0f0;
--search-error-border: #cc0000;
--search-error-color: #cc0000;
/* System / terminal panel (dark surfaces) */
--sys-bg-surface: #242424;
--sys-bg-deep: #0d0d0d;
--sys-bg-panel: #1a1a1a;
--sys-border: #555555;
--sys-border-deep: #333333;
--sys-border-hover: #888888;
--sys-text-dim: #969696;
--sys-text-bright: #e8e8e8;
--sys-text-body: #bbbbbb;
--sys-overlay: rgba(255, 255, 255, 0.03);
/* System syntax highlight */
--sys-syntax-comment: #666666;
--sys-syntax-directive: #7eb8f7;
--sys-syntax-block: #d4a0ff;
--sys-syntax-value: #e2c08d;
--sys-syntax-location: #79dac8;
--sys-syntax-notice: #a0c8ff;
--sys-syntax-crit: #ff7070;
/* Muted alpha overlays — derived from semantic tokens */
--success-muted-bg: rgba(92, 214, 157, 0.12);
--success-muted-border: rgba(92, 214, 157, 0.35);
--warning-muted-bg: rgba(251, 202, 81, 0.12);
--warning-muted-border: rgba(251, 202, 81, 0.35);
--error-muted-bg: rgba(242, 90, 90, 0.12);
--error-muted-border: rgba(242, 90, 90, 0.35);
--blue-muted-bg: rgba(65, 173, 255, 0.12);
--blue-muted-border: rgba(65, 173, 255, 0.30);
--blue-muted-bg-hover: rgba(65, 173, 255, 0.22);
--yellow-muted-bg: rgba(243, 156, 18, 0.12);
--yellow-muted-border: rgba(243, 156, 18, 0.30);
--yellow-muted-bg-hover:rgba(243, 156, 18, 0.22);
--green-muted-bg: rgba(76, 175, 80, 0.12);
--green-muted-border: rgba(76, 175, 80, 0.30);
--green-muted-bg-hover: rgba(76, 175, 80, 0.22);
--danger-border-muted: rgba(242, 90, 90, 0.35);
}