mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 05:10:16 +03:00
## What this does Consolidates the frontend's colour/theme system into a small, well-defined token layer and reworks the theme picker. The goal was a minimal, scalable set of semantic tokens that the editor **and** the Processor/portal (and Storybook) all share, plus a theme model that's easy to reason about. ## Token architecture (`core/theme/`) A four-file layer, imported once via `index.css`: | File | Role | |---|---| | `primitives.css` | The raw palette — the **only** place literal colours live (neutral ramps `--p-gray-*`/`--p-zinc-*` + status hues). | | `colors.css` | ~21 semantic `--c-*` tokens (surfaces, text, borders, primary, status) mapped from primitives per theme. **Reference these.** | | `compat.css` | Legacy names (`--bg-*`, `--text-*`, `--color-*`) aliased onto `--c-*` via `:root:root` so ~200 existing files keep working. | | `dimensions.css` | All non-colour tokens (spacing, radius, z-index, type, motion) — single source, resolving prior collisions. | A blocking linter (`scripts/lint/theme-lint.mjs`, run in `frontend:lint`) enforces "literals only in `primitives.css`" within `core/theme/`, and has a non-blocking WCAG contrast report. See `core/theme/README.md`. ## Theme model - **Mode** (`light` / `dark` / `system`) and **accent** are independent. Each mode has its own accent (`lightPrimary` / `darkPrimary`). - The editor is always `data-app-theme="custom"`; `ThemeProvider` injects the accent as `--user-primary` and sets `data-accent`. - **Two accent states:** - A **colour** (preset or custom hex) → tints every surface that hue (whole-app theming). - The **`default`** sentinel → neutral surfaces (white/grey light, zinc black/grey dark) with blue buttons, no tint. (`data-accent="default"` opts surfaces out of the tint.) - Accent contrast guardrails (`utils/customPrimary.ts`): lightness clamps so an accent can't collapse into the base, a contrast-picked on-primary foreground, and an accent-as-foreground variant so accent text is never dark-on-dark. ## Theme picker (Settings → General) - 3×5 grid: a distinct **Default** icon chip (not a colour) + 14 curated accents, in a dropdown per mode. - **Custom** colour via the shared `ColorInput`, with a live gamut clamp (`clampValue`) that refuses white/grey/black — the picker handle sticks at the boundary and preserves the working hue at achromatic extremes. - "Restore theme to default" resets both modes. ## Other - Dark mode is a true neutral zinc (no navy "midnight" tint); the Mantine dark ramp and Tailwind dark channels were neutralised to match. - Pre-paint inline script in `index.html` applies theme + accent before first paint (no FOUC); portal and editor now share the same `preferences.theme` source of truth. - High-visibility surfaces migrated to tokens (FAB, landing upload buttons, portal hero banners); scattered per-component colour swaps were intentionally **left for a follow-up** to keep this PR focused. ## Testing - `task frontend:check:all` (typecheck all variants + eslint + prettier + colour-lint) green. - Verified light/dark, default vs tinted accents, and the custom clamp via computed styles in the dev preview. > Note: the `prerender-og` build step failing in the e2e/deploy jobs is unrelated to this diff — it's in `vite.config.ts` (untouched here) and builds cleanly locally.
52 lines
1.7 KiB
HTML
52 lines
1.7 KiB
HTML
<!doctype html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<base href="%BASE_URL%" />
|
|
<link rel="icon" href="modern-logo/favicon.ico" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="theme-color" content="#000000" />
|
|
<meta
|
|
name="description"
|
|
content="The Free Adobe Acrobat alternative (10M+ Downloads)"
|
|
/>
|
|
<link rel="apple-touch-icon" href="modern-logo/logo192.png" />
|
|
<link rel="manifest" href="manifest.json" />
|
|
|
|
<title>Stirling PDF</title>
|
|
|
|
<!-- Apply theme before first paint (no FOUC); mirrors ThemeProvider, which then refines it. -->
|
|
<script>
|
|
(function () {
|
|
try {
|
|
var p = JSON.parse(
|
|
localStorage.getItem("stirlingpdf_preferences") || "{}",
|
|
);
|
|
var mode = p.theme || "system";
|
|
var scheme =
|
|
mode === "light"
|
|
? "light"
|
|
: mode === "dark"
|
|
? "dark"
|
|
: window.matchMedia &&
|
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
? "dark"
|
|
: "light";
|
|
var r = document.documentElement;
|
|
r.setAttribute("data-theme", scheme);
|
|
r.setAttribute("data-app-theme", "custom");
|
|
r.setAttribute("data-accent", "default");
|
|
r.setAttribute("data-mantine-color-scheme", scheme);
|
|
} catch (e) {
|
|
/* first visit / unavailable storage: ThemeProvider handles it */
|
|
}
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
<div id="root"></div>
|
|
<script type="module" src="src/index.tsx"></script>
|
|
</body>
|
|
</html>
|