/* * Design tokens. Components consume only these variables — never raw * values — so pond-level font settings (ADR 0016) and future theming stay * one-line changes. The look is deliberately plain and professional. */ :root { /* Native controls/scrollbars follow the active theme; the dark block below flips this together with the palette (issue #180). */ color-scheme: light; /* Font slots per ADR 0016; the real self-hosted fonts arrive with issue #66. */ --font-heading: 'Roboto', system-ui, -apple-system, 'Segoe UI', sans-serif; --font-body: 'Roboto', system-ui, -apple-system, 'Segoe UI', sans-serif; --font-mono: 'Fira Code', ui-monospace, SFMono-Regular, Menlo, monospace; --font-weight-heading: 400; --font-weight-body: 300; --font-weight-mono: 400; /* Color palette: calm neutrals with one pond-green accent. */ --color-text: #1f2933; --color-text-muted: #616e7c; --color-bg: #ffffff; --color-bg-subtle: #f5f7fa; /* Elevated panels (modals, cards) — several rules already referenced this * token with a #fff fallback; the fallback-less ones dropped their * background entirely (#120). */ --color-surface: #ffffff; /* Muted pill/badge surfaces (member seats, count pills, neutral badges). Was a fallback-only value scattered through base.css before #180. */ --color-surface-muted: #e2e8f0; --color-border: #d9e2ec; /* Boundaries of interactive controls (inputs, selects) need 3:1 against both backgrounds (WCAG 1.4.11) — #d9e2ec is only ~1.3:1. */ --color-border-input: #7d8a97; --color-accent: #2f6f4f; --color-accent-contrast: #ffffff; --color-danger: #ab091e; /* Text sitting ON a danger background (buttons, notification badge) — paired with --color-danger the same way --color-accent-contrast is paired with --color-accent; the two must flip together per theme. */ --color-danger-contrast: #ffffff; --color-danger-strong: #8a0718; --color-ok: #14803c; /* Favorite stars and tree icons (issue #132) — a readable gold. ICON use only: 3.25:1 passes the 3:1 non-text minimum but NOT the 4.5:1 required for text (audit A11Y-024c). */ --color-favorite: #b8860b; /* Status badges (admin system page): pastel surface + strong text, each pair ≥ 4.5:1 in both themes (asserted by theme-contrast.test.ts). */ --color-badge-ok-bg: #d6f2df; --color-badge-ok-text: #1d6f42; --color-badge-error-bg: #fbe3e0; --color-badge-error-text: #a02818; --color-badge-warn-bg: #fdf0d4; --color-badge-warn-text: #8a5a00; /* Separation ring for user-colored label chips/swatches — invisible on light, a faint light outline on dark where arbitrary label colors can melt into the background. */ --color-chip-outline: transparent; /* Spacing scale (rem-based). */ --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-6: 1.5rem; --space-8: 2rem; --radius: 6px; --topbar-height: 3rem; --sidebar-width: 16rem; } /* * Dark palette (issue #180). public/theme-init.js and theme/theme.ts always * resolve the user's Light/Dark/System choice to a CONCRETE data-theme on * — there is deliberately no @media fallback here, so this single * selector is the whole contract for later theming stages (ADR 0018). * Every pair is contrast-asserted by theme-contrast.test.ts; border-input * and favorite pass ≥ 3:1 against both palettes and stay unchanged. */ :root[data-theme='dark'] { color-scheme: dark; --color-text: #e2e8f0; --color-text-muted: #a7b3c0; --color-bg: #10161d; --color-bg-subtle: #161d26; --color-surface: #1b2430; --color-surface-muted: #26303c; --color-border: #323e4d; --color-accent: #5cb88a; --color-accent-contrast: #10161d; --color-danger: #f87171; --color-danger-contrast: #10161d; --color-danger-strong: #fa8f8f; --color-ok: #4ade80; --color-badge-ok-bg: #1b3d2b; --color-badge-ok-text: #8fdcb0; --color-badge-error-bg: #43181d; --color-badge-error-text: #f3a8a8; --color-badge-warn-bg: #3c3113; --color-badge-warn-text: #e3c06b; --color-chip-outline: rgba(255, 255, 255, 0.18); }