/* ─── 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 { /* 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); /* Nav active state */ --color-nav-active: var(--c-nav-active); /* PDF viewer */ --color-pdf-bg: var(--c-pdf-bg); --color-pdf-ctrl: var(--c-pdf-ctrl); --color-pdf-text: var(--c-pdf-text); /* Static brand tokens (not themed) */ --color-brand-navy: var(--palette-navy); --color-brand-mint: var(--palette-mint); } /* ─── 4. Light mode (default) ─────────────────────────────────────────────── */ :root { --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 — WCAG AA ✓; use only on surface, not canvas */ --c-accent: #a1dcd8; --c-accent-bg: rgba(161, 220, 216, 0.15); --c-primary: #012851; --c-primary-fg: #ffffff; --c-nav-active: rgba(180, 185, 255, 0.15); --c-pdf-bg: #ebebeb; --c-pdf-ctrl: #d8d8d8; --c-pdf-text: #333333; } /* ─── 5. Dark mode ─────────────────────────────────────────────────────────── */ @media (prefers-color-scheme: dark) { :root:not([data-theme='light']) { --c-canvas: #0d0d0d; --c-surface: #1a1a1a; --c-overlay: #242424; --c-muted: #252525; --c-line: #3d3d3d; --c-line-2: #2e2e2e; --c-ink: #f0efe9; --c-ink-2: #9ca3af; /* gray-400 — 7.5:1 on dark surface — WCAG AAA ✓ */ --c-ink-3: #8b97a5; /* gray-450 — 6.5:1 on dark surface — WCAG AA ✓ */ --c-accent: #00c7b1; --c-accent-bg: rgba(0, 199, 177, 0.12); --c-primary: #a1dcd8; --c-primary-fg: #012851; --c-nav-active: rgba(180, 185, 255, 0.12); --c-pdf-bg: #1e1e1e; --c-pdf-ctrl: #2a2a2a; --c-pdf-text: #d1d1d1; } } /* Manual dark override — takes precedence over media query */ :root[data-theme='dark'] { --c-canvas: #0d0d0d; --c-surface: #1a1a1a; --c-overlay: #242424; --c-muted: #252525; --c-line: #3d3d3d; --c-line-2: #2e2e2e; --c-ink: #f0efe9; --c-ink-2: #9ca3af; --c-ink-3: #6b7280; --c-accent: #00c7b1; --c-accent-bg: rgba(0, 199, 177, 0.12); --c-primary: #a1dcd8; --c-primary-fg: #012851; --c-nav-active: rgba(180, 185, 255, 0.12); --c-pdf-bg: #1e1e1e; --c-pdf-ctrl: #2a2a2a; --c-pdf-text: #d1d1d1; } /* ─── 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); } }