| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /* Tailwind CSS v4 entry point (compiled by Trunk's `tailwind-css` pipeline).
- *
- * This token layer is the single source of truth for the UI theme:
- * typography scale, the 4px spacing grid, one accent family, semantic
- * danger/success pairs, and dark-friendly surface/ink tokens. Wave 4
- * components consume these tokens only - no ad-hoc hex values. */
- @import "tailwindcss";
- /* Explicit sources keep content detection deterministic regardless of the
- * working directory Trunk invokes the Tailwind CLI from. */
- @source "../index.html";
- @source "../src";
- /* ------------------------------------------------------------------ */
- /* Semantic surface tokens: dark is the product default. Light is an */
- /* explicit `:root[data-theme="light"]` override; there is deliberately */
- /* no `prefers-color-scheme` query - `bootstrap.js` writes the data */
- /* attribute from localStorage (default `dark`) before the app mounts. */
- /* ------------------------------------------------------------------ */
- :root {
- color-scheme: dark;
- --ui-canvas: oklch(0.165 0.012 255);
- --ui-raised: oklch(0.205 0.014 255);
- --ui-sunken: oklch(0.14 0.011 255);
- --ui-ink: oklch(0.955 0.004 255);
- --ui-ink-muted: oklch(0.705 0.014 255);
- --ui-line: oklch(0.3 0.014 255);
- --ui-line-strong: oklch(0.4 0.016 255);
- --ui-accent-ink: oklch(0.8 0.1 210);
- /* Dark action pair: dark ink on a bright accent stays high-contrast. */
- --ui-btn-bg: oklch(0.845 0.09 210);
- --ui-btn-bg-hover: oklch(0.9 0.065 210);
- --ui-btn-ink: oklch(0.24 0.045 210);
- /* Status colors: every pair is used with a glyph and text, never alone. */
- --ui-danger: oklch(0.808 0.114 19.6);
- --ui-danger-surface: oklch(0.258 0.092 26);
- --ui-danger-line: oklch(0.396 0.141 25.7);
- --ui-success: oklch(0.871 0.15 154.4);
- --ui-success-surface: oklch(0.266 0.065 152.9);
- --ui-success-line: oklch(0.448 0.119 151.3);
- --ui-accent-soft: oklch(0.24 0.045 210);
- --ui-accent-soft-ink: oklch(0.9 0.065 210);
- --ui-focus: oklch(0.845 0.09 210);
- }
- /* Light override: the only writer is the header `ThemeToggle` (and the
- * pre-mount init in `bootstrap.js`). Higher specificity than `:root`. */
- :root[data-theme="light"] {
- color-scheme: light;
- --ui-canvas: oklch(0.981 0.004 255);
- --ui-raised: oklch(1 0 0);
- --ui-sunken: oklch(0.955 0.005 255);
- --ui-ink: oklch(0.235 0.02 255);
- --ui-ink-muted: oklch(0.5 0.018 255);
- --ui-line: oklch(0.905 0.006 255);
- --ui-line-strong: oklch(0.835 0.009 255);
- --ui-accent-ink: oklch(0.47 0.105 210);
- /* Action pair: white on accent-700 clears AA (5.3:1); hover darkens. */
- --ui-btn-bg: oklch(0.47 0.105 210);
- --ui-btn-bg-hover: oklch(0.4 0.085 210);
- --ui-btn-ink: oklch(1 0 0);
- --ui-danger: oklch(0.505 0.17 27.5);
- --ui-danger-surface: oklch(0.971 0.013 17.4);
- --ui-danger-line: oklch(0.885 0.062 18.3);
- --ui-success: oklch(0.527 0.154 150);
- --ui-success-surface: oklch(0.982 0.018 155.8);
- --ui-success-line: oklch(0.925 0.084 156);
- --ui-accent-soft: oklch(0.972 0.018 210);
- --ui-accent-soft-ink: oklch(0.47 0.105 210);
- --ui-focus: oklch(0.47 0.105 210);
- }
- /* `inline` keeps utilities pointing at the live custom properties, so the
- * `data-theme` override above wins without a rebuild or a `.dark` class. */
- @theme inline {
- --color-canvas: var(--ui-canvas);
- --color-raised: var(--ui-raised);
- --color-sunken: var(--ui-sunken);
- --color-ink: var(--ui-ink);
- --color-muted: var(--ui-ink-muted);
- --color-line: var(--ui-line);
- --color-line-strong: var(--ui-line-strong);
- --color-accent-ink: var(--ui-accent-ink);
- --color-accent-soft: var(--ui-accent-soft);
- --color-accent-soft-ink: var(--ui-accent-soft-ink);
- --color-btn: var(--ui-btn-bg);
- --color-btn-hover: var(--ui-btn-bg-hover);
- --color-btn-ink: var(--ui-btn-ink);
- --color-danger: var(--ui-danger);
- --color-danger-surface: var(--ui-danger-surface);
- --color-danger-line: var(--ui-danger-line);
- --color-success: var(--ui-success);
- --color-success-surface: var(--ui-success-surface);
- --color-success-line: var(--ui-success-line);
- }
- @theme {
- /* Spacing: explicit 4px grid (Tailwind's default, pinned here on purpose). */
- --spacing: 0.25rem;
- /* Type: system-native stacks only - no CDN fonts (CSP-friendly, offline-safe). */
- --font-sans: "Avenir Next", "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
- --font-mono: ui-monospace, "SFMono-Regular", "JetBrains Mono", "Cascadia Code", Menlo, Consolas, monospace;
- /* Typography scale beyond Tailwind's defaults. */
- --text-display: 2.75rem;
- --text-display--line-height: 1.08;
- --text-display--letter-spacing: -0.03em;
- --text-title: 1.625rem;
- --text-title--line-height: 1.2;
- --text-title--letter-spacing: -0.02em;
- /* One accent family: signal cyan. */
- --color-accent-50: oklch(0.972 0.018 210);
- --color-accent-100: oklch(0.945 0.038 210);
- --color-accent-200: oklch(0.9 0.065 210);
- --color-accent-300: oklch(0.845 0.09 210);
- --color-accent-400: oklch(0.775 0.115 210);
- --color-accent-500: oklch(0.7 0.13 210);
- --color-accent-600: oklch(0.6 0.125 210);
- --color-accent-700: oklch(0.47 0.105 210);
- --color-accent-800: oklch(0.4 0.085 210);
- --color-accent-900: oklch(0.33 0.065 210);
- --color-accent-950: oklch(0.24 0.045 210);
- /* Shape and elevation. */
- --radius-card: 0.875rem;
- --shadow-card:
- 0 1px 2px oklch(0.2 0.02 255 / 0.06),
- 0 12px 32px -16px oklch(0.2 0.02 255 / 0.22);
- }
- @layer base {
- html {
- -webkit-text-size-adjust: 100%;
- }
- @media (prefers-reduced-motion: no-preference) {
- html {
- scroll-behavior: smooth;
- }
- }
- body {
- background-color: var(--color-canvas);
- color: var(--color-ink);
- font-family: var(--font-sans);
- -webkit-font-smoothing: antialiased;
- text-rendering: optimizeLegibility;
- }
- :focus-visible {
- outline: 2px solid var(--ui-focus);
- outline-offset: 2px;
- }
- ::selection {
- background-color: var(--color-accent-800);
- color: var(--color-accent-50);
- }
- :root[data-theme="light"] ::selection {
- background-color: var(--color-accent-200);
- color: var(--color-accent-950);
- }
- }
|