/* 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); } }