366 lines
11 KiB
CSS
366 lines
11 KiB
CSS
/* ─── 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 {
|
|
--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 <img> ──── */
|
|
/*
|
|
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;
|
|
}
|
|
}
|