/* ─── 1. Fonts & Tailwind ──────────────────────────────────────────────────── */ /* Tinos = Times substitute | Montserrat = Gotham substitute (De Gruyter Brill CI) */ @import url('https://fonts.googleapis.com/css2?family=Tinos:ital,wght@0,400;0,700;1,400;1,700&family=Montserrat:wght@400;500;600;700&display=swap'); @import 'tailwindcss'; /* ─── 2. Raw palette — never used directly in components ──────────────────── */ @theme { /* Breakpoints */ --breakpoint-xs: 375px; /* Brand palette constants */ --palette-navy: #012851; --palette-mint: #a1dcd8; --palette-turquoise: #00c7b1; --palette-sand: #f0efe9; /* Typography */ --font-sans: 'Montserrat', ui-sans-serif, system-ui, sans-serif; --font-serif: 'Tinos', 'Times New Roman', Georgia, serif; --text-huge: 4rem; } /* ─── 3. Semantic tokens — Tailwind utilities backed by CSS variables ──────── */ /* @theme inline makes Tailwind generate utility classes (bg-surface, text-ink, border-line, etc.) whose values are CSS custom properties, not hardcoded hex. Changing --c-surface on :root is all it takes to retheme the whole UI. */ @theme inline { /* Surfaces */ --color-canvas: var(--c-canvas); --color-surface: var(--c-surface); --color-overlay: var(--c-overlay); --color-muted: var(--c-muted); /* Borders */ --color-line: var(--c-line); --color-line-2: var(--c-line-2); /* Text */ --color-ink: var(--c-ink); --color-ink-2: var(--c-ink-2); --color-ink-3: var(--c-ink-3); /* Accent (mint ↔ turquoise) */ --color-accent: var(--c-accent); --color-accent-bg: var(--c-accent-bg); /* Primary interactive (navy ↔ mint) */ --color-primary: var(--c-primary); --color-primary-fg: var(--c-primary-fg); /* PDF viewer */ --color-pdf-bg: var(--c-pdf-bg); --color-pdf-ctrl: var(--c-pdf-ctrl); --color-pdf-text: var(--c-pdf-text); /* Header surface — independent from canvas/surface for per-mode control */ --color-header: var(--c-header); /* Turquoise — transcription mode accent */ --color-turquoise: var(--c-turquoise); --color-turquoise-fg: var(--c-turquoise-fg); /* Focus ring — keyboard focus indicator, mode-aware (navy in light, mint in dark) */ --color-focus-ring: var(--c-focus-ring); /* Danger — destructive action color */ --color-danger: var(--c-danger); --color-danger-fg: var(--c-danger-fg); /* Warning — amber, WCAG AA on white */ --color-warning: #b45309; --color-warning-fg: #ffffff; /* Static brand tokens (not themed) */ --color-brand-navy: var(--palette-navy); --color-brand-mint: var(--palette-mint); } /* ─── 4. Light mode (default) ─────────────────────────────────────────────── */ :root { /* 1px accent bar + 64px nav = 65px total sticky header height */ --header-height: 65px; --c-canvas: #f0efe9; --c-surface: #ffffff; --c-overlay: #ffffff; --c-muted: #f5f4ef; --c-line: #e4e2d7; --c-line-2: #eeede8; --c-ink: #012851; --c-ink-2: #4b5563; /* gray-600 — 7.6:1 on white, 6.6:1 on canvas — WCAG AA ✓ */ --c-ink-3: #6b7280; /* gray-500 — 4.8:1 on white, ~4.6:1 on canvas — WCAG AA ✓ */ /* ⚠ accent — decorative use only (borders, icon tints, bg fills) Light mode: #a1dcd8 on white = 1.52:1 — WCAG FAIL. Never use as text colour. For interactive text labels use text-primary or text-ink instead. */ --c-accent: #a1dcd8; --c-accent-bg: rgba(161, 220, 216, 0.15); --c-primary: #012851; --c-primary-fg: #ffffff; /* Header is brand-navy in light mode; same in dark mode for contrast compliance */ --c-header: #012851; --c-turquoise: #00c7b1; --c-turquoise-fg: #ffffff; /* Focus ring: brand-navy in light mode — 14:1 on white, ~11:1 on sand */ --c-focus-ring: #012851; --c-pdf-bg: #ebebeb; --c-pdf-ctrl: #d8d8d8; --c-pdf-text: #333333; /* Danger — destructive actions (5.1:1 on white — WCAG AA ✓) */ --c-danger: #c0392b; --c-danger-fg: #ffffff; /* Tag color tokens — decorative dot colors on tag chips */ --c-tag-sage: #5a8a6a; --c-tag-sienna: #a0522d; --c-tag-amber: #c17a00; --c-tag-slate: #607080; --c-tag-violet: #7a4f9a; --c-tag-rose: #c0446e; --c-tag-cobalt: #3060b0; --c-tag-moss: #4a7a3a; --c-tag-sand: #9a8040; --c-tag-coral: #c05540; /* PersonType badge — institution (navy-tinted blue) */ --c-badge-institution-bg: #e8eff7; --c-badge-institution-text: #1a4971; --c-badge-institution-border: #c4d5e8; /* PersonType badge — group (muted purple) */ --c-badge-group-bg: #f0e8f5; --c-badge-group-text: #5a2d6f; --c-badge-group-border: #d8c5e3; /* PersonType badge — unknown (amber warning) */ --c-badge-unknown-bg: #fdf4e3; --c-badge-unknown-text: #7a5a0a; --c-badge-unknown-border: #f0ddb3; } /* ─── 5. Dark mode ─────────────────────────────────────────────────────────── */ /* Navy-tinted dark palette derived from brand-navy (#012851). KEEP THESE TWO BLOCKS IN SYNC — they cover the same design intent via different activation paths (system preference vs. manual toggle). */ @media (prefers-color-scheme: dark) { :root:not([data-theme='light']) { color-scheme: dark; --c-canvas: #010e1e; --c-surface: #011526; --c-overlay: #011e38; --c-muted: #011a30; --c-line: #0d3358; --c-line-2: #092843; --c-ink: #f0efe9; --c-ink-2: #9ca3af; /* 7.5:1 on #011526 — WCAG AAA ✓ */ --c-ink-3: #8b97a5; /* 7.1:1 on #011526 — WCAG AAA ✓ */ --c-accent: #00c7b1; --c-accent-bg: rgba(0, 199, 177, 0.12); --c-primary: #a1dcd8; --c-primary-fg: #012851; /* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */ --c-header: #012851; --c-turquoise: #00c7b1; --c-turquoise-fg: #012851; /* Focus ring: brand-mint in dark mode — 9.2:1 on canvas, 7.1:1 on surface */ --c-focus-ring: #a1dcd8; --c-pdf-bg: #010e1e; --c-pdf-ctrl: #011526; --c-pdf-text: #f0efe9; --c-badge-institution-bg: rgba(30, 80, 140, 0.25); --c-badge-institution-text: #8bb8e0; --c-badge-institution-border: rgba(30, 80, 140, 0.4); --c-badge-group-bg: rgba(90, 45, 111, 0.25); --c-badge-group-text: #c9a0dc; --c-badge-group-border: rgba(90, 45, 111, 0.4); --c-badge-unknown-bg: rgba(122, 90, 10, 0.25); --c-badge-unknown-text: #e0c060; --c-badge-unknown-border: rgba(122, 90, 10, 0.4); /* Danger — destructive actions (4.7:1 on #011526 — WCAG AA ✓) */ --c-danger: #e55347; --c-danger-fg: #ffffff; /* Tag color tokens — lighter for visibility on dark backgrounds */ --c-tag-sage: #7abf8a; --c-tag-sienna: #cc7050; --c-tag-amber: #f0aa30; --c-tag-slate: #8a9db0; --c-tag-violet: #b07ad0; --c-tag-rose: #f07090; --c-tag-cobalt: #6090e0; --c-tag-moss: #70b060; --c-tag-sand: #c0a060; --c-tag-coral: #f07060; } } /* Manual dark override — takes precedence over media query */ /* KEEP IN SYNC with the @media block above */ :root[data-theme='dark'] { color-scheme: dark; --c-canvas: #010e1e; --c-surface: #011526; --c-overlay: #011e38; --c-muted: #011a30; --c-line: #0d3358; --c-line-2: #092843; --c-ink: #f0efe9; --c-ink-2: #9ca3af; /* 7.5:1 on #011526 — WCAG AAA ✓ */ --c-ink-3: #8b97a5; /* 7.1:1 on #011526 — WCAG AAA ✓ */ --c-accent: #00c7b1; --c-accent-bg: rgba(0, 199, 177, 0.12); --c-primary: #a1dcd8; --c-primary-fg: #012851; /* Header at brand-navy: 4.99:1 with ink-3 (WCAG AA ✓), visually above canvas */ --c-header: #012851; --c-turquoise: #00c7b1; --c-turquoise-fg: #012851; /* Focus ring: brand-mint in dark mode — 9.2:1 on canvas, 7.1:1 on surface */ --c-focus-ring: #a1dcd8; --c-pdf-bg: #010e1e; --c-pdf-ctrl: #011526; --c-pdf-text: #f0efe9; --c-badge-institution-bg: rgba(30, 80, 140, 0.25); --c-badge-institution-text: #8bb8e0; --c-badge-institution-border: rgba(30, 80, 140, 0.4); --c-badge-group-bg: rgba(90, 45, 111, 0.25); --c-badge-group-text: #c9a0dc; --c-badge-group-border: rgba(90, 45, 111, 0.4); --c-badge-unknown-bg: rgba(122, 90, 10, 0.25); --c-badge-unknown-text: #e0c060; --c-badge-unknown-border: rgba(122, 90, 10, 0.4); /* Danger — destructive actions (4.7:1 on #011526 — WCAG AA ✓) */ --c-danger: #e55347; --c-danger-fg: #ffffff; /* Tag color tokens — lighter for visibility on dark backgrounds */ --c-tag-sage: #7abf8a; --c-tag-sienna: #cc7050; --c-tag-amber: #f0aa30; --c-tag-slate: #8a9db0; --c-tag-violet: #b07ad0; --c-tag-rose: #f07090; --c-tag-cobalt: #6090e0; --c-tag-moss: #70b060; --c-tag-sand: #c0a060; --c-tag-coral: #f07060; } /* ─── 6. Icon inversion — De Gruyter icons are black SVGs loaded as ──── */ /* In dark mode, invert all brand icons so they read as white on dark surfaces. Exclude .invert icons (already inverted for placement on dark backgrounds) so they don't get double-inverted back to black. */ @media (prefers-color-scheme: dark) { :root:not([data-theme='light']) img[src*='degruyter-icons']:not(.invert) { filter: invert(1); } } :root[data-theme='dark'] img[src*='degruyter-icons']:not(.invert) { filter: invert(1); } /* ─── 7. @mention chip ─────────────────────────────────────────────────────── */ /* Rendered by renderBody() via {@html ...} in CommentThread.svelte. Must live in global CSS — Svelte scoped styles don't reach injected HTML. */ .mention { display: inline; color: var(--c-ink); background-color: var(--c-accent-bg); border-radius: 3px; padding: 0 3px; font-weight: 600; font-style: normal; cursor: default; transition: background-color 0.15s ease; } .mention:hover { background-color: color-mix(in srgb, var(--c-accent) 25%, transparent); } /* ─── 8. Base styles ───────────────────────────────────────────────────────── */ @layer base { html { overscroll-behavior: none; } body { background-color: var(--c-canvas); color: var(--c-ink); font-family: var(--font-serif); } h1, h2, h3, h4, h5, h6 { font-family: var(--font-sans); font-weight: 600; } /* Form controls — always use surface bg and ink text so they theme correctly */ input, textarea, select { background-color: var(--c-surface); color: var(--c-ink); } a:hover { text-decoration-color: var(--c-accent); text-decoration-thickness: 2px; text-underline-offset: 4px; } /* Fallback focus ring for any interactive element not styled with ring-focus-ring */ :focus-visible { outline: 2px solid var(--c-focus-ring); outline-offset: 2px; } } /* Ensure focus rings are visible in Windows High Contrast / forced-colors mode */ @media (forced-colors: active) { :focus-visible { outline: 3px solid ButtonText; } } @keyframes slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }