@import 'tailwindcss'; /* CountryAtlas design tokens. Editorial, calm, data-dense. Raw values live on :root / .dark; Tailwind utilities read them through `@theme inline`, so `bg-paper`, `text-ink-2`, `border-rule`, `text-up`, `fill-series-1` … follow the theme. Series/sequential colours are the validated dataviz palette (skills/dataviz references/palette.md), re-validated against these surfaces on 2026-09-11 (see apps/web/README.md → Design tokens). */ @custom-variant dark (&:where(.dark, .dark *)); :root { color-scheme: light; --paper: #fbfaf7; /* page plane */ --surface: #ffffff; /* chart surface, sheets, dialogs */ --surface-2: #f3f1ec; /* hover wash, chips */ --ink: #1a1917; --ink-2: #5c5a55; --ink-3: #8a877f; --rule: #e6e3dc; --rule-strong: #c9c6bd; --accent: #1c5cab; --accent-ink: #ffffff; --accent-soft: #e8f0fb; --up: #006300; --down: #b02a2a; --warn: #9a6a00; --nodata: #d9d6ce; --forecast: #8a877f; --series-1: #2a78d6; --series-2: #eb6834; --series-3: #1baf7a; --series-4: #eda100; --series-5: #e87ba4; --series-6: #008300; --series-7: #4a3aa7; --series-8: #e34948; --seq-1: #cde2fb; --seq-2: #9ec5f4; --seq-3: #6da7ec; --seq-4: #3987e5; --seq-5: #256abf; --seq-6: #184f95; --seq-7: #0d366b; /* Direction of change (neutral semantics: increase / decrease, NOT good / bad). Teal ↔ sienna diverging ramp. */ --inc: #0f7b8a; --dec: #b4632d; --div-1: #8c4a12; /* strong decrease */ --div-2: #c98a4e; --div-3: #e8c9a6; --div-4: #ece9e1; /* no change */ --div-5: #a6d4d9; --div-6: #4fa2ad; --div-7: #0b5f6b; /* strong increase */ /* Second sequential ramp (warm) for a second map layer / category maps */ --seq2-1: #fbe4d0; --seq2-2: #f5c39c; --seq2-3: #eb9a63; --seq2-4: #d97636; --seq2-5: #b55b21; --seq2-6: #8a4416; --seq2-7: #5c2d0c; --map-water: #f4f2ec; --map-stroke: #ffffff; --shadow-sheet: 0 -8px 32px rgba(26, 25, 23, 0.12); --shadow-pop: 0 4px 24px rgba(26, 25, 23, 0.14); } .dark { color-scheme: dark; --paper: #151513; --surface: #1c1c1a; --surface-2: #24241f; --ink: #f2f0ea; --ink-2: #c9c6bd; --ink-3: #8a877f; --rule: #2c2b28; --rule-strong: #3a3935; --accent: #5598e7; --accent-ink: #0d1b2e; --accent-soft: #17304f; --up: #0ca30c; --down: #e66767; --warn: #e0a100; --nodata: #33322f; --forecast: #8a877f; --series-1: #3987e5; --series-2: #d95926; --series-3: #199e70; --series-4: #c98500; --series-5: #d55181; --series-6: #008300; --series-7: #9085e9; --series-8: #e66767; --seq-1: #0d366b; --seq-2: #184f95; --seq-3: #256abf; --seq-4: #3987e5; --seq-5: #6da7ec; --seq-6: #9ec5f4; --seq-7: #cde2fb; --inc: #4fb6c2; --dec: #e0955f; --div-1: #d58a4a; --div-2: #a86a37; --div-3: #5e4530; --div-4: #2a2926; --div-5: #234f55; --div-6: #2e8791; --div-7: #63c3cf; --seq2-1: #3a2410; --seq2-2: #5c3512; --seq2-3: #8a4a16; --seq2-4: #b8641f; --seq2-5: #d98a3c; --seq2-6: #eeb277; --seq2-7: #f8dcb8; --map-water: #101010; --map-stroke: #1c1c1a; --shadow-sheet: 0 -8px 32px rgba(0, 0, 0, 0.5); --shadow-pop: 0 4px 24px rgba(0, 0, 0, 0.55); } @theme inline { --color-paper: var(--paper); --color-surface: var(--surface); --color-surface-2: var(--surface-2); --color-ink: var(--ink); --color-ink-2: var(--ink-2); --color-ink-3: var(--ink-3); --color-rule: var(--rule); --color-rule-strong: var(--rule-strong); --color-accent: var(--accent); --color-accent-ink: var(--accent-ink); --color-accent-soft: var(--accent-soft); --color-up: var(--up); --color-down: var(--down); --color-warn: var(--warn); --color-nodata: var(--nodata); --color-forecast: var(--forecast); --color-series-1: var(--series-1); --color-series-2: var(--series-2); --color-series-3: var(--series-3); --color-series-4: var(--series-4); --color-series-5: var(--series-5); --color-series-6: var(--series-6); --color-series-7: var(--series-7); --color-series-8: var(--series-8); --color-seq-1: var(--seq-1); --color-seq-2: var(--seq-2); --color-seq-3: var(--seq-3); --color-seq-4: var(--seq-4); --color-seq-5: var(--seq-5); --color-seq-6: var(--seq-6); --color-seq-7: var(--seq-7); --color-inc: var(--inc); --color-dec: var(--dec); --color-div-1: var(--div-1); --color-div-2: var(--div-2); --color-div-3: var(--div-3); --color-div-4: var(--div-4); --color-div-5: var(--div-5); --color-div-6: var(--div-6); --color-div-7: var(--div-7); --color-map-water: var(--map-water); /* Container widths: editorial pages ~1280, wide tables 1400, explorers = viewport. */ --container-editorial: 80rem; --container-wide: 87.5rem; --font-ui: var(--font-ui), ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; --font-display: var(--font-display), 'Iowan Old Style', 'Palatino Linotype', Georgia, serif; --font-mono: ui-monospace, 'SF Mono', Menlo, Consolas, monospace; /* Typographic scale (rem). Body 15px on mobile, 16px from md. */ --text-2xs: 0.6875rem; --text-2xs--line-height: 1rem; --text-xs: 0.75rem; --text-xs--line-height: 1.1rem; --text-sm: 0.875rem; --text-sm--line-height: 1.3rem; --text-base: 1rem; --text-base--line-height: 1.55rem; --text-lg: 1.125rem; --text-lg--line-height: 1.6rem; --text-xl: 1.3125rem; --text-xl--line-height: 1.75rem; --text-2xl: 1.625rem; --text-2xl--line-height: 2rem; --text-3xl: 2rem; --text-3xl--line-height: 2.3rem; --text-4xl: 2.5rem; --text-4xl--line-height: 2.75rem; --text-5xl: 3.25rem; --text-5xl--line-height: 3.4rem; --shadow-sheet: var(--shadow-sheet); --shadow-pop: var(--shadow-pop); --radius-xs: 2px; --radius-sm: 4px; --radius-md: 6px; } @layer base { html { font-family: var(--font-ui); background: var(--paper); color: var(--ink); -webkit-text-size-adjust: 100%; text-rendering: optimizeLegibility; scroll-padding-top: 6.5rem; } html, body { /* Never scroll horizontally; individual scrollers opt in with overflow-x-auto. */ overflow-x: clip; max-width: 100%; } body { font-size: 15px; line-height: 1.55; min-height: 100dvh; background: var(--paper); color: var(--ink); } @media (min-width: 48rem) { body { font-size: 16px; } } h1, h2, h3 { text-wrap: balance; } p { text-wrap: pretty; } a { text-underline-offset: 0.15em; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; } ::selection { background: var(--accent-soft); color: var(--ink); } svg { display: block; } button { cursor: pointer; } [hidden] { display: none !important; } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } } @utility tnum { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: 'tnum' 1, 'lnum' 1; } @utility pnum { font-variant-numeric: proportional-nums lining-nums; } @utility display { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.01em; } @utility eyebrow { font-size: var(--text-2xs); line-height: 1rem; letter-spacing: 0.08em; text-transform: uppercase; font-weight: 600; color: var(--ink-3); } @utility hairline { border-top: 1px solid var(--rule); } @utility tap { min-height: 44px; min-width: 44px; } @utility scrollbar-none { scrollbar-width: none; &::-webkit-scrollbar { display: none; } } @utility safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); } @utility no-data-hatch { background-color: var(--nodata); background-image: repeating-linear-gradient(135deg, transparent 0 3px, rgba(26, 25, 23, 0.14) 3px 4px); } @utility link-quiet { color: inherit; text-decoration: none; &:hover { color: var(--accent); } } @utility container-x { padding-left: 1rem; padding-right: 1rem; @media (min-width: 40rem) { padding-left: 1.5rem; padding-right: 1.5rem; } } @utility container-editorial { max-width: var(--container-editorial); margin-left: auto; margin-right: auto; } @utility container-wide { max-width: var(--container-wide); margin-left: auto; margin-right: auto; } /* Break out of the centred container to the viewport edges. */ @utility full-bleed { width: 100vw; margin-left: calc(50% - 50vw); margin-right: calc(50% - 50vw); } /* Horizontal ticker strip: snap-scrolling figures on one rule, no scrollbar. */ @utility ticker { display: flex; overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; &::-webkit-scrollbar { display: none; } & > * { scroll-snap-align: start; flex: 0 0 auto; } } /* Small data badges (quality, freshness, direction). Text + glyph always accompany the colour. */ @utility badge { display: inline-flex; align-items: center; gap: 0.25rem; border-radius: 2px; padding: 1px 6px; font-size: var(--text-2xs); line-height: 1rem; font-weight: 500; letter-spacing: 0.02em; border: 1px solid var(--rule); color: var(--ink-2); } /* Range inputs (year slider): large thumb, hairline track, accent fill via CSS var --pct set by the component. */ .ca-range { -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer; } .ca-range:focus-visible { outline: none; } .ca-range::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: var(--rule-strong); } .ca-range::-moz-range-track { height: 4px; border-radius: 2px; background: var(--rule-strong); } .ca-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 22px; height: 22px; margin-top: -9px; border-radius: 50%; background: var(--accent); border: 3px solid var(--surface); box-shadow: 0 0 0 1px var(--rule-strong); } .ca-range::-moz-range-thumb { width: 22px; height: 22px; border-radius: 50%; background: var(--accent); border: 3px solid var(--surface); box-shadow: 0 0 0 1px var(--rule-strong); } .ca-range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--accent-soft), 0 0 0 4px var(--accent); } .ca-range:disabled { opacity: 0.4; cursor: default; } /* Chart chrome shared by the SVG kit (class names instead of inline styles so theme swaps repaint). */ .ca-chart text { font-family: var(--font-ui); font-variant-numeric: tabular-nums; fill: var(--ink-3); font-size: 11px; } .ca-chart .axis line, .ca-chart .grid line { stroke: var(--rule); stroke-width: 1; shape-rendering: crispEdges; } .ca-chart .baseline { stroke: var(--rule-strong); } .ca-chart .series-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; } .ca-chart .forecast { stroke-dasharray: 4 4; } .ca-chart .ring { stroke: var(--surface); stroke-width: 2; } .ca-chart .label { fill: var(--ink-2); font-size: 11px; } .ca-chart .label-strong { fill: var(--ink); font-weight: 600; } .ca-hatch { fill: url(#ca-nodata-hatch); } /* Motion tokens */ @keyframes ca-sheet-up { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } } @keyframes ca-fade { from { opacity: 0; } to { opacity: 1; } } .animate-sheet { animation: ca-sheet-up 220ms cubic-bezier(0.2, 0.8, 0.2, 1); } .animate-fade { animation: ca-fade 160ms ease-out; }