/* ==========================================================================
   BERIFFA Design System: tokens (tokens/tokens.css)
   Generated by scripts/build-tokens.mjs from tokens/tokens.json. Do not edit by hand: change tokens.json and run node scripts/build-tokens.mjs.

   Dark is BERIFFA's primary theme (beriffa.com is dark). Light is the warm
   paper counterpart, chosen and checked separately.

   Theme switching (both themes carry every token, so nested scopes work too)
     <html>                       follows the OS (prefers-color-scheme)
     <html data-theme="dark">     dark      (or class="dark")
     <html data-theme="light">    light     (or class="light")
   The bare :root block is the light theme. Dark arrives through
     @media (prefers-color-scheme: dark) :root:not([data-theme="light"]):not(.light)
     :root[data-theme="dark"], [data-theme="dark"], .dark
   so a page that must stay light on a dark OS sets data-theme="light" or
   class="light". A theme attribute or class on any element re-themes that
   subtree.

   Fonts are not declared here: load ../fonts/fonts.css (Geist and Geist Mono,
   SIL OFL 1.1) or self-host the same files, for example with next/font.

   Colour: no chromatic accent. Accent roles are ink. Status colours are quiet
   and always travel with a shape and a word. Contrast proof: tokens/contrast.md.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Theme-independent scales
   -------------------------------------------------------------------------- */
:root {
  /* Families: Geist and Geist Mono, and nothing else */
  --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;
  --font-numeric: tabular-nums; /* font-variant-numeric for every number that can change or sits in a column */
  --font-numeric-mono: tabular-nums slashed-zero; /* font-variant-numeric for every Geist Mono value */

  /* Type scale. Each style: family, size, line-height, weight, tracking, and a font shorthand.
     Display and headings: Geist 600, tight tracking: -0.025em at 32px and above, -0.015em at 20 to 31px, -0.01em on h3 (18px), 0 on h4. Sentence case. One display or h1 per page. Comfortable scale (Owner decision, 29 October 2026).
     Text: Geist 400 for reading, 500 for emphasis, labels and controls. Comfortable scale (Owner decision, 29 October 2026): no text below 13px; when in doubt choose the larger size.
     Mono: Geist Mono carries every literal value: codes, coordinates, timestamps, ASNs, prefixes, hostnames. Always tabular, slashed zero. No text below 13px; map-region (12px) is the one exception (Owner decision, 29 October 2026). */
  --type-display-family: var(--font-sans); /* Sign-in headline, editorial heroes (announcements, the design-system cover). One per page, balanced wrap, max 16ch per line. */
  --type-display-size: 3.5rem; /* 56px */
  --type-display-line: 1.071; /* 60px */
  --type-display-weight: 600;
  --type-display-tracking: -0.025em;
  --type-display-font: 600 3.5rem/1.071 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-display-compact-family: var(--font-sans); /* Display below 640px wide. */
  --type-display-compact-size: 2.5rem; /* 40px */
  --type-display-compact-line: 1.1; /* 44px */
  --type-display-compact-weight: 600;
  --type-display-compact-tracking: -0.025em;
  --type-display-compact-font: 600 2.5rem/1.1 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-h1-family: var(--font-sans); /* Page title, one per page, under a Geist Mono eyebrow. Balanced wrap. */
  --type-h1-size: 2.25rem; /* 36px */
  --type-h1-line: 1.111; /* 40px */
  --type-h1-weight: 600;
  --type-h1-tracking: -0.025em;
  --type-h1-font: 600 2.25rem/1.111 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-h1-compact-family: var(--font-sans); /* Page title below 640px wide. */
  --type-h1-compact-size: 1.875rem; /* 30px */
  --type-h1-compact-line: 1.2; /* 36px */
  --type-h1-compact-weight: 600;
  --type-h1-compact-tracking: -0.015em;
  --type-h1-compact-font: 600 1.875rem/1.2 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-section-title-family: var(--font-sans); /* Band title on a public marketing page (beriffa.com): one per band, under its Geist Mono eyebrow, at the old site's section scale (owner, 29 October 2026: "I want it closer to the old site"). Balanced wrap, max 24ch. Not for Atlas, the control panel or component sheets, which keep h2. */
  --type-section-title-size: 2.5rem; /* 40px */
  --type-section-title-line: 1.1; /* 44px */
  --type-section-title-weight: 600;
  --type-section-title-tracking: -0.025em;
  --type-section-title-font: 600 2.5rem/1.1 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-section-title-compact-family: var(--font-sans); /* Section title below 640px wide. */
  --type-section-title-compact-size: 1.875rem; /* 30px */
  --type-section-title-compact-line: 1.2; /* 36px */
  --type-section-title-compact-weight: 600;
  --type-section-title-compact-tracking: -0.015em;
  --type-section-title-compact-font: 600 1.875rem/1.2 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-stat-family: var(--font-sans); /* Headline count in a stat tile (42, 38, 99.982), tabular figures. The unit sits 6px to its right in Geist Mono `mono` (14px) text-3, or a short word follows in ui text-2. font-variant-numeric: tabular-nums. */
  --type-stat-size: 2.25rem; /* 36px */
  --type-stat-line: 1; /* 36px */
  --type-stat-weight: 600;
  --type-stat-tracking: -0.025em; /* font-variant-numeric: tabular-nums */
  --type-stat-font: 600 2.25rem/1 var(--font-sans); /* shorthand; set letter-spacing and font-variant-numeric: tabular-nums after it */

  --type-h2-family: var(--font-sans); /* Section heading on a page (Operations), component-sheet section title. */
  --type-h2-size: 1.375rem; /* 22px */
  --type-h2-line: 1.364; /* 30px */
  --type-h2-weight: 600;
  --type-h2-tracking: -0.015em;
  --type-h2-font: 600 1.375rem/1.364 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-h3-family: var(--font-sans); /* Panel and card title (BERIFFANET at a glance, Recent incidents), dialog title, chart title. */
  --type-h3-size: 1.125rem; /* 18px */
  --type-h3-line: 1.444; /* 26px */
  --type-h3-weight: 600;
  --type-h3-tracking: -0.01em;
  --type-h3-font: 600 1.125rem/1.444 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-h4-family: var(--font-sans); /* Sub-section and rail heads (Sites), callout, toast, empty-state, popover and field-group titles. */
  --type-h4-size: 1rem; /* 16px */
  --type-h4-line: 1.5; /* 24px */
  --type-h4-weight: 600;
  --type-h4-tracking: 0;
  --type-h4-font: 600 1rem/1.5 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-lede-family: var(--font-sans); /* The description under a page title, in text-2; its leading fact may be 500 in text-1. Max 66ch (measure-reading), pretty wrap. */
  --type-lede-size: 1.125rem; /* 18px */
  --type-lede-line: 1.556; /* 28px */
  --type-lede-weight: 400;
  --type-lede-tracking: 0;
  --type-lede-font: 400 1.125rem/1.556 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-reading-family: var(--font-sans); /* Long-form: runbooks, post-mortems, announcements, knowledge base. Max 66ch (measure-reading), pretty wrap. */
  --type-reading-size: 1.0625rem; /* 17px */
  --type-reading-line: 1.647; /* 28px */
  --type-reading-weight: 400;
  --type-reading-tracking: 0;
  --type-reading-font: 400 1.0625rem/1.647 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-body-family: var(--font-sans); /* Default text, descriptions, input and textarea values, lg and xl button labels (500), checkbox and radio labels, the command palette's input. */
  --type-body-size: 1rem; /* 16px */
  --type-body-line: 1.5; /* 24px */
  --type-body-weight: 400;
  --type-body-tracking: 0;
  --type-body-font: 400 1rem/1.5 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-ui-family: var(--font-sans); /* Navigation items, table cells, tabs, menu items, key-value rows, stat labels, md button labels (500). Active or selected state: 500. */
  --type-ui-size: 0.9375rem; /* 15px */
  --type-ui-line: 1.467; /* 22px */
  --type-ui-weight: 400;
  --type-ui-tracking: 0;
  --type-ui-font: 400 0.9375rem/1.467 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-small-family: var(--font-sans); /* Captions, hints, legends, meta lines, table headers (500), badge words (500), segmented controls, sm button labels (500). */
  --type-small-size: 0.875rem; /* 14px */
  --type-small-line: 1.429; /* 20px */
  --type-small-weight: 400;
  --type-small-tracking: 0;
  --type-small-font: 400 0.875rem/1.429 var(--font-sans); /* shorthand; set letter-spacing after it */

  --type-label-family: var(--font-mono); /* The tracked uppercase eyebrow: one per section, like a map sheet label (date line, NOT CONFIGURED, STAFF SIGN-IN). Uppercase. */
  --type-label-size: 0.8125rem; /* 13px */
  --type-label-line: 1.385; /* 18px */
  --type-label-weight: 500;
  --type-label-tracking: 0.1em; /* uppercase, font-variant-numeric: tabular-nums slashed-zero */
  --type-label-font: 500 0.8125rem/1.385 var(--font-mono); /* shorthand; set letter-spacing and uppercase, font-variant-numeric: tabular-nums slashed-zero after it */

  --type-mono-family: var(--font-mono); /* Literal values inside text and tables: hostnames, IPs, prefixes, ASNs, IDs (INC-0142), absolute times (14:18), code blocks. font-variant-numeric: tabular-nums slashed-zero. */
  --type-mono-size: 0.875rem; /* 14px */
  --type-mono-line: 1.429; /* 20px */
  --type-mono-weight: 400;
  --type-mono-tracking: 0; /* font-variant-numeric: tabular-nums slashed-zero */
  --type-mono-font: 400 0.875rem/1.429 var(--font-mono); /* shorthand; set letter-spacing and font-variant-numeric: tabular-nums slashed-zero after it */

  --type-mono-value-family: var(--font-mono); /* The value line of a routing tile (18/18, AS219271, 7/7), a literal in a dialog title. font-variant-numeric: tabular-nums slashed-zero. */
  --type-mono-value-size: 1rem; /* 16px */
  --type-mono-value-line: 1.5; /* 24px */
  --type-mono-value-weight: 400;
  --type-mono-value-tracking: 0; /* font-variant-numeric: tabular-nums slashed-zero */
  --type-mono-value-font: 400 1rem/1.5 var(--font-mono); /* shorthand; set letter-spacing and font-variant-numeric: tabular-nums slashed-zero after it */

  --type-mono-fact-family: var(--font-mono); /* One verified literal shown as a fact on a plate: AS219271 on the sign-in plate. At most one per plate, never a measured or invented figure. font-variant-numeric: tabular-nums slashed-zero. */
  --type-mono-fact-size: 1.75rem; /* 28px */
  --type-mono-fact-line: 1.286; /* 36px */
  --type-mono-fact-weight: 400;
  --type-mono-fact-tracking: 0; /* font-variant-numeric: tabular-nums slashed-zero */
  --type-mono-fact-font: 400 1.75rem/1.286 var(--font-mono); /* shorthand; set letter-spacing and font-variant-numeric: tabular-nums slashed-zero after it */

  --type-mono-small-family: var(--font-mono); /* Map site labels, chart ticks, graticule degrees, kbd keys, counts, legend counts, swatch and icon names, the sidebar build line, the lockup's ATLAS. Never for sentences. font-variant-numeric: tabular-nums slashed-zero. */
  --type-mono-small-size: 0.8125rem; /* 13px */
  --type-mono-small-line: 1.385; /* 18px */
  --type-mono-small-weight: 400;
  --type-mono-small-tracking: 0.02em; /* font-variant-numeric: tabular-nums slashed-zero */
  --type-mono-small-font: 400 0.8125rem/1.385 var(--font-mono); /* shorthand; set letter-spacing and font-variant-numeric: tabular-nums slashed-zero after it */

  --type-map-region-family: var(--font-mono); /* Ocean lettering on map plates that carry no health data (sign-in, editorial). Never on the operational map. The one style below 13px (Owner decision, 29 October 2026). Uppercase. */
  --type-map-region-size: 0.75rem; /* 12px */
  --type-map-region-line: 1.333; /* 16px */
  --type-map-region-weight: 500;
  --type-map-region-tracking: 0.2em; /* uppercase, font-variant-numeric: tabular-nums slashed-zero */
  --type-map-region-font: 500 0.75rem/1.333 var(--font-mono); /* shorthand; set letter-spacing and uppercase, font-variant-numeric: tabular-nums slashed-zero after it */

  /* Spacing. 4px base. Operational screens use 4 to 32px; editorial pages use the doubling ladder 48 / 96 / 192. */
  --space-0: 0; /* No gap. */
  --space-px: 1px; /* Hairline gaps between joined tiles. */
  --space-0-5: 2px; /* Uptime cell gap, icon nudge, segmented-control padding. */
  --space-1: 4px; /* Icon to label inside badges; tight inline gaps (dot and word). */
  --space-1-5: 6px; /* Badge padding, kbd padding, label to control. */
  --space-2: 8px; /* Icon to label in buttons, gap between buttons, tight stacks. */
  --space-3: 12px; /* Table cell padding, list row gaps, sm control padding. */
  --space-4: 16px; /* Dense panel padding, field gaps, the phone gutter. */
  --space-5: 20px; /* Panel body and stat tile padding (y); the panel, table and stat-tile inset below 640px (--b-pad-x). */
  --space-6: 24px; /* Gap between panels and page sections (operational); the panel, table and stat-tile inset (--b-pad-x). */
  --space-8: 32px; /* Page padding (desktop), gap between major groups. */
  --space-10: 40px; /* Page side padding (desktop), the sign-in sheet foot. */
  --space-12: 48px; /* Editorial section ladder, step 1. */
  --space-16: 64px; /* Page foot (the content column's bottom padding), editorial blocks. */
  --space-18: 72px; /* The sign-in sheet's side padding (Tailwind px-18), beside the map plate. */
  --space-24: 96px; /* Editorial section ladder, step 2. */
  --space-48: 192px; /* Editorial section ladder, step 3 (hero). */

  /* Sizes and layout. Control heights and layout measures, at the comfortable scale (Owner decision, 29 October 2026): controls 32, 36, 44 and 48px, rows 40 and 48px, header 64px, sidebar 272px (rail 64px). Pages fill the window (Owner decision, Full-width pages, 29 October 2026); text keeps its own measure. */
  --control-h-sm: 32px; /* Small buttons, inline actions, table-row controls, popover actions, pagination pages. Label in small (14px). */
  --control-h-md: 36px; /* Default buttons, inputs, selects, the header search, nav and menu items (operational). Label in ui (15px), value in body (16px). */
  --control-h-lg: 44px; /* Sign-in and editorial actions, page actions on mobile, the phone header's search button. */
  --control-h-xl: 48px; /* Touch targets: mobile primary actions and the sign-in Microsoft button (graft from Atlas). */
  --row-h-dense: 40px; /* Dense table rows (audit log, prefixes, server inventory). */
  --row-h: 48px; /* Default table and list rows. */
  --header-h: 64px; /* App header and the sidebar lockup row. */
  --sidebar-w: 272px; /* Expanded sidebar: the lockup, ui (15px) nav labels with 18px glyphs, counts. */
  --sidebar-w-rail: 64px; /* Collapsed icon rail (18px glyphs in 40px items). */
  --content-max: 100%; /* The page frame's width: all of the main area, padding included (Owner decision, Full-width pages, 29 October 2026: "Pages always fill the window."). The content column, the header row, page headers, panels, tables, grids and the map fill the window at every width with the same side gutters (space-10 on desktop, space-4 on phones); nothing is centred in a capped column (.b-shell__content, .b-header). Never set a smaller cap on a page; the one exception is the BERIFFA.com marketing pages (content-max-site). Text keeps a readable measure on its own (measure-reading, measure-wide); tables, stat grids, charts, the map and multi-column layouts use the width. */
  --content-max-site: 1400px; /* The BERIFFA.com marketing pages' frame: one centred column, padding included (Owner decision, "BERIFFA.com marketing pages keep the old site's width", 31 October 2026: asked how wide beriffa.com should be on large screens, the owner chose "Old width, panel full"). Every page under /[locale], the static 404 page and the Digest's public pages stop at 1400px and sit centred, as the old site's container did: the notice row's words, the header row, every band's content and the footer line up on that column with the page gutters (space-10) inside it, while band grounds, hairlines and the hero's globe backdrop still run to the window's edges. Put .b-site on the page's frame root; it sets --b-site-inline, the side padding (components/beriffa.css, section 23). Below 1400px the column is the window, so nothing changes. The control panel (/dash and its sign-in), Atlas, this system and the network map (/network/: full window, no site frame, as on the old site) keep content-max (100%). */
  --rail-w: 320px; /* Site list beside the map (its codes line holds seven site codes at 13px); metadata rails beside long-form. */
  --detail-rail-w: 400px; /* The detail rail: the right-hand key-value column of a detail page (server, service, incident, briefing; Atlas DetailLayout), beside a minmax(0, 1fr) main column with a space-6 gap (.b-detail-layout). It sits on bg-ground and holds panels; below 1280px it moves under the main column. Not for the site list beside the map (rail-w) or for a sheet. */
  --measure-reading: 66ch; /* Max line length for running text, at every window width (pages are full width, so the text caps itself, never the page): ledes and page descriptions (.b-lede, .b-page-header__description), reading prose (.b-reading: knowledge base pages, announcements, plain-text mail), list summaries, and any paragraph set on its own (.b-measure). A single column of short fields may use it too. Measured in the text's own font: about 700px at body (16px). */
  --measure-wide: 96ch; /* Max width for dense text and forms, at every window width (graft from Atlas): a form page's column (fields, fieldsets, hints and actions; two fields side by side in .b-field__row, about 500px each), callout, panel, fieldset and field text, key-value values, notes beside tables, and any block set on its own (.b-measure-wide). Empty-state and not-configured bodies keep their own 60ch and 64ch. Measured in the text's own font: about 1020px at body (16px), 955px at ui (15px). */

  /* Radii. Short ladder; outer radius = inner radius + padding. Map plates and data panels stay near-square. */
  --radius-0: 0; /* Map plate inside a panel edge, the inner edges of joined tiles. */
  --radius-xs: 2px; /* Uptime cells, chart bar ends, map label plates. */
  --radius-sm: 4px; /* Badges, kbd, checkbox, tooltips, segmented-control thumbs. */
  --radius-md: 6px; /* Buttons, inputs, selects, nav items, menu items. */
  --radius-lg: 10px; /* Panels, cards, joined tile groups, callouts, popovers. */
  --radius-xl: 14px; /* Dialogs, the command palette, toasts. */
  --radius-full: 999px; /* Avatars and count badges only; never buttons. */

  /* Borders. Line widths. Colours come from line-subtle, line, line-strong and line-control. */
  --border-hairline: 1px; /* Every structural line (line-subtle, line, line-strong). */
  --border-control: 1px; /* Input, select, checkbox and radio outline, in line-control. */
  --border-selected: 1.5px; /* Selection ring in accent (ink): selected tile or chip, the selected map site and the matching ring around the selected rail glyph. Also the error input ring, in bad-text. */
  --border-dashed: 1px dashed; /* Not-configured boxes, planned routes, maintenance markers. */
  --focus-width: 2px; /* Focus outline width. */
  --focus-offset: 2px; /* Gap between element and focus outline. */

  /* Motion durations. Motion durations. State changes are near-instant, arrivals slow and soft, nothing bounces. Every dur-* token drops to 0ms under prefers-reduced-motion (tokens.css does this); beat is a loop period and stays. */
  --dur-press: 80ms; /* Button press colour change. */
  --dur-state: 160ms; /* Hover, colour, border and focus transitions. */
  --dur-overlay: 200ms; /* Menus, popovers, tooltips opening (opacity plus a 4px rise). */
  --dur-panel: 280ms; /* Sidebar collapse, sheets, dialogs. */
  --dur-reveal: 640ms; /* First arrival of a panel or map layer (opacity plus an 8px rise), once per page load. */
  --dur-draw: 960ms; /* A backbone route drawing once along its arc (stroke-dashoffset), then holding. */
  --dur-ping: 900ms; /* One ring of the status ring: it expands from an Offline mark (opacity 0.6 to 0, scale 1 to 2.2). The status ring plays two, half a beat apart, then holds still (never loops). */
  --beat: 6s; /* Loop beat: every illustration loop is one beat, so loops on one screen stay phase-related. The status ring's two rings start half a beat apart (0s and 3s), so the last has faded at 3.9s. */

  /* Easing. Easing curves. Arrivals ease out, loops ease in and out, nothing overshoots. */
  --ease-standard: cubic-bezier(0.3, 0, 0.2, 1); /* State changes. */
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1); /* Arrivals and overlays opening. */
  --ease-in: cubic-bezier(0.5, 0, 0.9, 0.4); /* Overlays closing. */
  --ease-draw: cubic-bezier(0.3, 0.7, 0.2, 1); /* Route draw. */
  --ease-cycle: cubic-bezier(0.45, 0, 0.55, 1); /* Symmetric motion: the status ring's rings and packet travel. Nothing bounces. */

  /* Layers. Stacking layers, lowest first. */
  --z-sticky: 10; /* App header. */
  --z-sidebar: 20; /* Sidebar over content on tablet. */
  --z-overlay: 50; /* Menus, popovers, tooltips. */
  --z-dialog: 60; /* Dialogs, the command palette. */
  --z-toast: 70; /* Toasts. */
}

/* Below 640px wide the display and h1 and section-title styles take their -compact values. */
@media (max-width: 639.98px) {
  :root {
    --type-display-size: 2.5rem; /* 40px, display-compact */
    --type-display-line: 1.1; /* 44px */
    --type-display-weight: 600;
    --type-display-tracking: -0.025em;
    --type-display-font: 600 2.5rem/1.1 var(--font-sans);
    --type-h1-size: 1.875rem; /* 30px, h1-compact */
    --type-h1-line: 1.2; /* 36px */
    --type-h1-weight: 600;
    --type-h1-tracking: -0.015em;
    --type-h1-font: 600 1.875rem/1.2 var(--font-sans);
    --type-section-title-size: 1.875rem; /* 30px, section-title-compact */
    --type-section-title-line: 1.2; /* 36px */
    --type-section-title-weight: 600;
    --type-section-title-tracking: -0.015em;
    --type-section-title-font: 600 1.875rem/1.2 var(--font-sans);
  }
}

/* --------------------------------------------------------------------------
   Colour: LIGHT (warm paper). The bare :root, so a page with no theme set on a
   light OS, or data-theme="light" / class="light" anywhere, is light.
   -------------------------------------------------------------------------- */
:root, [data-theme="light"], .light {
  color-scheme: light;
  --bg-sea: #ece9e5; /* oklch(0.935 0.006 75) · Deepest ground. Dark: near-black warm graphite for the sidebar, the map field and the sign-in map zone. Light: the warm paper step below the page. Carries text-1, text-2, text-3 and every status text step. */
  --bg-ground: #f5f2ee; /* oklch(0.962 0.006 75) · Page canvas behind panels, and the header bar. Dark: warm graphite; light: warm paper. Carries text-1, text-2, text-3 and every status text step. */
  --bg-surface-1: #fdfcf9; /* oklch(0.991 0.004 91) · Panels, cards, table body, chart surface, joined tiles. One small lightness step above the ground in dark; the whitest paper in light. Carries every text token. */
  --bg-surface-2: #f1eeea; /* oklch(0.950 0.006 75) · One step from a panel: tab track, table head band, hovered and selected rows, active nav item, secondary button fill in dark. Carries every text token. */
  --bg-surface-3: #ffffff; /* oklch(1.000 0.000 0) · Overlays only: menus, popovers, tooltips, toasts and dialogs, always with shadow-overlay. In light it is white. Carries every text token. */
  --text-1: #181613; /* oklch(0.201 0.007 78) · Primary text, headings, stat numbers, values and active icons. Paper-white in dark (not #fff, to cut halation), ink in light. */
  --text-2: #44423f; /* oklch(0.380 0.006 78) · Secondary text: ledes, descriptions, nav labels, secondary cells, inactive icons, map state words. Also the ink that draws routes (accent). */
  --text-3: #615e5b; /* oklch(0.484 0.006 68) · Quietest text allowed: meta, timestamps, axis and tick labels, eyebrows, placeholders, legend counts. Tuned brighter in dark so quiet text never sinks. Not for use on washes. */
  --text-disabled: #94928e; /* oklch(0.660 0.006 85) · Disabled control labels only (WCAG-exempt); never the only carrier of information. Sits on bg-surface-2 (disabled button) or bg-input. */
  --line-subtle: #e9e6e2; /* oklch(0.926 0.006 75) · Table row rules and dividers inside a panel (decorative). */
  --line: #dcd9d5; /* oklch(0.887 0.006 75) · Panel outlines, section rules, header and sidebar edges, joined-tile gaps (decorative). */
  --line-strong: #c0bdb9; /* oklch(0.800 0.007 75) · Emphasised rules, chart baseline, secondary-button ring, kbd outline, Europe inset frame, text selection (decorative; a label always identifies the thing). */
  --line-control: #787572; /* oklch(0.564 0.006 68) · Boundaries that identify a control: input, select, checkbox and radio outlines, dashed not-configured boxes. */
  --bg-input: #ffffff; /* = --bg-surface-3 · oklch(1.000 0.000 0) · Fill of inputs, selects, textareas and unchecked checkboxes: bg-surface-2 in dark, white in light so a field reads as fresh paper. Carries text-1 values and text-3 placeholders. */
  --primary: #181613; /* = --text-1 · oklch(0.201 0.007 78) · Primary button fill and checked checkbox: paper-white in dark (beriffa.com's white button), ink in light. Hover grows a 2px ring of the same colour (shadow-ring-primary). */
  --on-primary: #fdfcf9; /* = --bg-surface-1 · oklch(0.991 0.004 91) · Label and icon on primary and primary-press. */
  --primary-press: #353230; /* oklch(0.320 0.006 56) · Primary fill while pressed. */
  --secondary: #fdfcf9; /* = --bg-surface-1 · oklch(0.991 0.004 91) · Secondary button fill (bg-surface-2 in dark, bg-surface-1 in light) with an inset line-strong ring. */
  --on-secondary: #181613; /* = --text-1 · oklch(0.201 0.007 78) · Label on secondary and secondary-hover. */
  --secondary-hover: #f1eeea; /* = --bg-surface-2 · oklch(0.950 0.006 75) · Secondary and ghost button hover fill. */
  --danger: #9e342e; /* oklch(0.480 0.142 27) · The system's one red fill: destructive buttons (Delete server, Revoke token) and, under the Owner decision "Attention in red", the incident and critical security surfaces: the alert button (b-button--alert, the incident contact's "Call now"), the filled critical notice (b-site-notice--filled) and the IncidentBand's glyph. Quiet red at 75% of Graphite chroma. Never a status mark of a monitored thing, never a link, never error text (errors use bad-text). */
  --on-danger: #ffffff; /* oklch(1.000 0.000 0) · Label on danger and danger-press: destructive and alert button labels, and the filled critical notice's words, glyph, link, close and focus ring. */
  --danger-press: #852824; /* oklch(0.420 0.128 27) · Danger fill while pressed (destructive and alert buttons); the filled critical notice's bottom line and its close button's hover. */
  --danger-wash: #f2ebea; /* = --bad-wash · oklch(0.945 0.008 27) · Tinted ground of the IncidentBand (b-incident, the incident contact; Owner decision "Attention in red"): a low red step over the page, as the old site's red-tinted panel, dark enough that the danger fill keeps its 3:1 edge on it (the alert button, the glyph). Text on it: text-1 (title, the incident number), text-2 (body, label, the e-mail link), bad-text (eyebrow). Its outline is bad-line. Used nowhere else. */
  --accent: #44423f; /* = --text-2 · oklch(0.380 0.006 78) · Ink as accent (= text-2): backbone routes on the map, the selected-site ring, the live tick. BERIFFA has no chromatic accent; emphasis is ink, weight and size. */
  --accent-text: #181613; /* = --text-1 · oklch(0.201 0.007 78) · Accent as text (= text-1): a selected route name or a selected row label. Never a hue, never links. */
  --on-accent: #f5f2ee; /* = --bg-ground · oklch(0.962 0.006 75) · Text on an accent (ink) fill, such as a selected route chip (= bg-ground). */
  --accent-wash: #f1eeea; /* = --bg-surface-2 · oklch(0.950 0.006 75) · Selected tile, chip or row ground for accent emphasis (= bg-surface-2). Text on it: text-1 or text-2. A ground change is never the only selection cue: selection adds the 1.5px ink ring (border-selected in accent). */
  --accent-line: #c0bdb9; /* = --line-strong · oklch(0.800 0.007 75) · Resting outline of an accent-emphasised tile or chip (= line-strong, decorative; the label carries meaning). When the tile or chip is selected the outline becomes the 1.5px ink ring (border-selected in accent, 3:1 or better). */
  --focus-ring: #181613; /* = --text-1 · oklch(0.201 0.007 78) · 2px keyboard focus outline at a 2px offset, so the local ground shows as the gap. Monochrome in both themes: no hue. */
  --ok: #5e9072; /* oklch(0.609 0.071 157) · Status OK mark (filled circle; dot, marker, strip cell, glyph): Operational, Reporting, Resolved. Always beside a word. Lightness ladder: brighter than info and bad, below warn in dark; the lightest mark in light, so a healthy strip is the quietest thing on paper. */
  --ok-text: #3e6851; /* oklch(0.479 0.060 159) · Status OK as text: the status word in tables, rails and badges. */
  --warn: #84653d; /* oklch(0.529 0.069 72) · Status WARN mark (filled triangle; dashed ring for Maintenance): Degraded, Delayed, Maintenance, SEV3, Identified. The lightest mark in dark; in light it sits between ok and info, so a degraded bucket darkens against the healthy mass. */
  --warn-text: #755b3d; /* oklch(0.490 0.056 70) · Status WARN as text. */
  --bad: #792f2a; /* oklch(0.409 0.105 27) · Status BAD mark (filled square): Down, Offline, SEV1, SEV2, Investigating. Also the notification count fill. The darkest status mark in both themes (louder on paper); on the map it is also the largest and the only one that rings. */
  --bad-text: #792f2a; /* = --bad · oklch(0.409 0.105 27) · Status BAD as text: lighter than the mark in dark, equal to bad in light. */
  --on-bad: #ffffff; /* oklch(1.000 0.000 0) · Count numerals on a bad fill (the notification badge, Geist Mono 13px 500). */
  --info: #395d85; /* oklch(0.470 0.078 252) · Status INFO mark (filled diamond; hollow diamond for Awaiting agent): Probe error, Awaiting agent, Monitoring. */
  --info-text: #3f638b; /* oklch(0.490 0.077 252) · Status INFO as text. */
  --neutral: #7c7a77; /* oklch(0.580 0.005 78) · Status NEUTRAL mark (hollow ring, achromatic): Not monitored, Paused, Awaiting data, SEV4; the no-data line in uptime strips. */
  --neutral-text: #615e5b; /* = --text-3 · oklch(0.484 0.006 68) · Status NEUTRAL as text (= text-3). */
  --ok-wash: #eef3ef; /* oklch(0.959 0.007 152) · Tinted ground for ok badges, callouts and flagged rows, at quiet chroma. Text on it: ok-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --ok-line: #b1cbbe; /* oklch(0.819 0.033 164) · Outline of ok badges and callouts (decorative; the word inside carries the meaning). */
  --warn-wash: #f5f2ec; /* oklch(0.962 0.009 85) · Tinted ground for warn badges, callouts and flagged rows, at quiet chroma. Text on it: warn-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --warn-line: #d4c7af; /* oklch(0.834 0.036 83) · Outline of warn badges and callouts (decorative; the word inside carries the meaning). */
  --bad-wash: #f2ebea; /* oklch(0.945 0.008 27) · Tinted ground for bad badges, callouts and flagged rows, at quiet chroma. Text on it: bad-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --bad-line: #c9a2a4; /* oklch(0.748 0.046 15) · Outline of bad badges and callouts (decorative; the word inside carries the meaning). */
  --info-wash: #edf0f2; /* oklch(0.953 0.004 236) · Tinted ground for info badges, callouts and flagged rows, at quiet chroma. Text on it: info-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --info-line: #acbdcd; /* oklch(0.790 0.029 247) · Outline of info badges and callouts (decorative; the word inside carries the meaning). */
  --neutral-wash: #f5f4f1; /* oklch(0.967 0.004 91) · Tinted ground for neutral badges, callouts and flagged rows, at quiet chroma. Text on it: neutral-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --neutral-line: #c9c8c5; /* oklch(0.833 0.004 91) · Outline of neutral badges and callouts (decorative; the word inside carries the meaning). */
  --chart-1: #56809a; /* oklch(0.579 0.061 236) · Series 1 (sky), the first series of every chart, 2px lines. Quiet chroma: identity comes from the legend, direct labels and the lightness step, never from hue alone. Status hues never stand in for a series. */
  --chart-2: #584977; /* oklch(0.441 0.076 298) · Series 2 (violet), the darker step beside series 1 in dark and light. */
  --chart-3: #99835a; /* oklch(0.620 0.063 83) · Series 3 (gold), the lighter step. */
  --chart-4: #7e444f; /* oklch(0.461 0.080 9) · Series 4 (rose), the darker step. A fifth series folds into Other or small multiples; no generated hues. */
  --chart-grid: #e9e6e2; /* oklch(0.926 0.006 75) · Chart gridlines (recessive, decorative). */
  --chart-axis: #c0bdb9; /* = --line-strong · oklch(0.800 0.007 75) · Chart baseline and zero line (= line-strong, decorative; ticks are labelled). */
  --map-sea: #f1efeb; /* oklch(0.953 0.006 85) · Map field (the sea): a sunk plate inside its panel, and the Europe inset ground. Carries text-1, text-2, text-3 and the status words. */
  --map-land: #bcb8b4; /* oklch(0.785 0.007 68) · Land dots of the dot-matrix map (decorative). */
  --map-graticule: #e2dfdb; /* oklch(0.905 0.006 75) · 30 degree graticule (10 degrees in the inset), decorative. */
  --map-outline: #cac7c3; /* oklch(0.831 0.006 75) · Equal Earth globe outline and dotted equator (decorative). */
  --map-label-bg: #f1efebdb; /* oklch(0.953 0.006 85) at 86% · 86% map-sea plate behind map labels, so codes stay legible over land dots and routes. Carries text-1 and text-2. */
  --scrim: #18161352; /* oklch(0.201 0.007 78) at 32% · Behind dialogs and the command palette. */
  --map-marker-offline: #792f2a; /* = --bad · oklch(0.409 0.105 27) · Map marker, Offline: FILLED SQUARE with a 2px map-sea halo; the only marker that may ring. */
  --map-marker-delayed: #84653d; /* = --warn · oklch(0.529 0.069 72) · Map marker, Delayed: FILLED TRIANGLE. */
  --map-marker-awaiting: #395d85; /* = --info · oklch(0.470 0.078 252) · Map marker, Awaiting agent: HOLLOW DIAMOND, 1.5px stroke. */
  --map-marker-maintenance: #84653d; /* = --warn · oklch(0.529 0.069 72) · Map marker, Maintenance: DASHED RING, 1.5px stroke, 2/2 dash. */
  --map-marker-reporting: #5e9072; /* = --ok · oklch(0.609 0.071 157) · Map marker, Reporting: small FILLED DOT, never labelled (a healthy network is quiet). */
  --map-marker-unmonitored: #7c7a77; /* = --neutral · oklch(0.580 0.005 78) · Map marker, Not monitored: HOLLOW RING, 1.5px stroke. */
  --map-marker-halo: #f1efeb; /* = --map-sea · oklch(0.953 0.006 85) · 2px ring under every marker so it lifts off the land dots and routes. */
  --map-route: #44423f; /* = --accent · oklch(0.380 0.006 78) · BERIFFANET backbone: 1.25px great-circle arcs in ink (text-2). Never a hue. */
  --map-route-planned: #615e5b; /* = --text-3 · oklch(0.484 0.006 68) · Planned capacity: 1px line, 3/3 dash, in the quietest ink; always explained in the legend. */
  --map-label: #44423f; /* = --text-2 · oklch(0.380 0.006 78) · State words beside exception markers, Geist Mono 13px (mono-small) on map-label-bg; the site code inside is text-1. */
  --map-selected: #44423f; /* = --accent · oklch(0.380 0.006 78) · 1.5px ink ring around the selected site. */
  --map-inset-frame: #c0bdb9; /* = --line-strong · oklch(0.800 0.007 75) · Frame of the Western Europe inset and its traced area on the world map (decorative; the inset title names it). */
  --globe-sea: #e9e6e2; /* = --line-subtle · oklch(0.926 0.006 75) · Globe (b-globe), the sea characters: the faint dotted ocean of the ASCII globe (":" on the lit side, "." further round), quieter than the land; with the land it gives the ball its round shape, as the old site's globe. Decorative and aria-hidden: the words beside the globe carry the meaning. Sits on the host ground (bg-ground, bg-sea, bg-surface-1); words may pass over it (they keep 4.5:1 over globe-land, the brighter of the two). */
  --globe-land: #dcd9d5; /* = --line · oklch(0.887 0.006 75) · Globe (b-globe), the land characters (the old site's ramp "+*#%@", dim to lit; lambert shading picks the character, so the lit side reads denser). A low-contrast backdrop, about the old site's 20% opacity: text-1, text-2 and text-3 keep 4.5:1 over it in both themes, so a hero's words stay readable where the globe passes behind them. Decorative. */
  --globe-node: #181613; /* = --text-1 · oklch(0.201 0.007 78) · Globe (b-globe), a place: the bullet character in the grid, the brightest thing in the globe (3:1 on the host ground). Its name sits beside it in globe-name. */
  --globe-name: #615e5b; /* = --text-3 · oklch(0.484 0.006 68) · Globe (b-globe), a place's name: Geist Mono capitals in the grid, one blank cell from its bullet, on blank cells (the globe's characters step aside), so it reads on the host ground at 4.5:1. */
  --uptime-ok: #5e9072; /* = --ok · oklch(0.609 0.071 157) · Uptime strip bucket with 100% successful checks: full height. */
  --uptime-warn: #84653d; /* = --warn · oklch(0.529 0.069 72) · Uptime strip bucket at 90 to 99.99%: 62% height. */
  --uptime-bad: #792f2a; /* = --bad · oklch(0.409 0.105 27) · Uptime strip bucket below 90%: 30% height. */
  --uptime-probe: #395d85; /* = --info · oklch(0.470 0.078 252) · Uptime strip bucket with probe errors only (our side failed): outlined and hatched, full height. */
  --uptime-empty: #7c7a77; /* = --neutral · oklch(0.580 0.005 78) · Uptime strip bucket with no data: a 2px flat line, never drawn as a pass. */
  --chart-label: #615e5b; /* = --text-3 · oklch(0.484 0.006 68) · Chart tick labels, Geist Mono 13px (mono-small), on bg-surface-1. */
  --chart-crosshair: #44423f; /* = --text-2 · oklch(0.380 0.006 78) · Hover crosshair, 1px dashed, on bg-surface-1 (3:1 or better). */
  --link: #181613; /* = --text-1 · oklch(0.201 0.007 78) · Inline link text: ink, underlined (never a hue). Same grounds and ratios as text-1: every ground, panel, overlay, input and wash. */
  --link-decoration: #787572; /* = --line-control · oklch(0.564 0.006 68) · Link underline at rest (offset 0.2em, 1px), the non-colour cue that text is a link, so it reaches 3:1 on every ground; becomes text-1 on hover. */
  --selection-bg: #c0bdb9; /* = --line-strong · oklch(0.800 0.007 75) · Text selection ground (an ink step, visible on every surface); selected text stays text-1. */
  --logo-tile: #fdfcf9; /* = --bg-surface-1 · oklch(0.991 0.004 91) · Neutral tile behind a published logo file whose ink is dark, so the file shows unchanged in every theme (the group brands' black PNG marks on BERIFFA.com): paper in dark, the panel white in light. Never recolour or invert the file instead. Carries the files' black ink only. */
  --shadow-overlay: 0 0 0 1px #dcd9d5, 0 12px 32px -10px #28221a2e, 0 2px 6px #28221a0f; /* The only drop shadow in the system: menus, popovers, the command palette, toasts, dialogs. A 1px line ring plus a soft fall. Panels are flat and separated by line. */
  --shadow-ring-primary: 0 0 0 2px #181613; /* Primary button hover: a 2px ring of the fill colour, so the button grows without moving. */
  --shadow-control: inset 0 0 0 1px #787572; /* Inset 1px line-control outline for inputs, selects and the search field (keeps outlined and filled controls the same size). */
}

/* --------------------------------------------------------------------------
   Colour: DARK (primary). Applies when the OS is dark and the page is not
   forced light, or wherever data-theme="dark" or class="dark" is set. These
   selectors outrank the bare :root above.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not(.light) {
    color-scheme: dark;
    --bg-sea: #0c0b09; /* oklch(0.150 0.005 85) · Deepest ground. Dark: near-black warm graphite for the sidebar, the map field and the sign-in map zone. Light: the warm paper step below the page. Carries text-1, text-2, text-3 and every status text step. */
    --bg-ground: #13110f; /* oklch(0.179 0.005 67) · Page canvas behind panels, and the header bar. Dark: warm graphite; light: warm paper. Carries text-1, text-2, text-3 and every status text step. */
    --bg-surface-1: #191816; /* oklch(0.209 0.004 85) · Panels, cards, table body, chart surface, joined tiles. One small lightness step above the ground in dark; the whitest paper in light. Carries every text token. */
    --bg-surface-2: #211f1d; /* oklch(0.241 0.005 68) · One step from a panel: tab track, table head band, hovered and selected rows, active nav item, secondary button fill in dark. Carries every text token. */
    --bg-surface-3: #282725; /* oklch(0.273 0.004 85) · Overlays only: menus, popovers, tooltips, toasts and dialogs, always with shadow-overlay. In light it is white. Carries every text token. */
    --text-1: #f1eeea; /* oklch(0.950 0.006 75) · Primary text, headings, stat numbers, values and active icons. Paper-white in dark (not #fff, to cut halation), ink in light. */
    --text-2: #c5c2be; /* oklch(0.815 0.006 75) · Secondary text: ledes, descriptions, nav labels, secondary cells, inactive icons, map state words. Also the ink that draws routes (accent). */
    --text-3: #a39f9b; /* oklch(0.705 0.007 68) · Quietest text allowed: meta, timestamps, axis and tick labels, eyebrows, placeholders, legend counts. Tuned brighter in dark so quiet text never sinks. Not for use on washes. */
    --text-disabled: #656360; /* oklch(0.501 0.005 78) · Disabled control labels only (WCAG-exempt); never the only carrier of information. Sits on bg-surface-2 (disabled button) or bg-input. */
    --line-subtle: #242220; /* oklch(0.253 0.005 68) · Table row rules and dividers inside a panel (decorative). */
    --line: #2d2b29; /* oklch(0.290 0.005 68) · Panel outlines, section rules, header and sidebar edges, joined-tile gaps (decorative). */
    --line-strong: #403e3c; /* oklch(0.365 0.004 68) · Emphasised rules, chart baseline, secondary-button ring, kbd outline, Europe inset frame, text selection (decorative; a label always identifies the thing). */
    --line-control: #767472; /* oklch(0.560 0.004 68) · Boundaries that identify a control: input, select, checkbox and radio outlines, dashed not-configured boxes. */
    --bg-input: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Fill of inputs, selects, textareas and unchecked checkboxes: bg-surface-2 in dark, white in light so a field reads as fresh paper. Carries text-1 values and text-3 placeholders. */
    --primary: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Primary button fill and checked checkbox: paper-white in dark (beriffa.com's white button), ink in light. Hover grows a 2px ring of the same colour (shadow-ring-primary). */
    --on-primary: #13110f; /* = --bg-ground · oklch(0.179 0.005 67) · Label and icon on primary and primary-press. */
    --primary-press: #d6d4d0; /* oklch(0.870 0.006 85) · Primary fill while pressed. */
    --secondary: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Secondary button fill (bg-surface-2 in dark, bg-surface-1 in light) with an inset line-strong ring. */
    --on-secondary: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Label on secondary and secondary-hover. */
    --secondary-hover: #282725; /* = --bg-surface-3 · oklch(0.273 0.004 85) · Secondary and ghost button hover fill. */
    --danger: #a9443c; /* oklch(0.521 0.135 27) · The system's one red fill: destructive buttons (Delete server, Revoke token) and, under the Owner decision "Attention in red", the incident and critical security surfaces: the alert button (b-button--alert, the incident contact's "Call now"), the filled critical notice (b-site-notice--filled) and the IncidentBand's glyph. Quiet red at 75% of Graphite chroma. Never a status mark of a monitored thing, never a link, never error text (errors use bad-text). */
    --on-danger: #ffffff; /* oklch(1.000 0.000 0) · Label on danger and danger-press: destructive and alert button labels, and the filled critical notice's words, glyph, link, close and focus ring. */
    --danger-press: #953831; /* oklch(0.470 0.127 27) · Danger fill while pressed (destructive and alert buttons); the filled critical notice's bottom line and its close button's hover. */
    --danger-wash: #201312; /* oklch(0.204 0.022 24) · Tinted ground of the IncidentBand (b-incident, the incident contact; Owner decision "Attention in red"): a low red step over the page, as the old site's red-tinted panel, dark enough that the danger fill keeps its 3:1 edge on it (the alert button, the glyph). Text on it: text-1 (title, the incident number), text-2 (body, label, the e-mail link), bad-text (eyebrow). Its outline is bad-line. Used nowhere else. */
    --accent: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · Ink as accent (= text-2): backbone routes on the map, the selected-site ring, the live tick. BERIFFA has no chromatic accent; emphasis is ink, weight and size. */
    --accent-text: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Accent as text (= text-1): a selected route name or a selected row label. Never a hue, never links. */
    --on-accent: #13110f; /* = --bg-ground · oklch(0.179 0.005 67) · Text on an accent (ink) fill, such as a selected route chip (= bg-ground). */
    --accent-wash: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Selected tile, chip or row ground for accent emphasis (= bg-surface-2). Text on it: text-1 or text-2. A ground change is never the only selection cue: selection adds the 1.5px ink ring (border-selected in accent). */
    --accent-line: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Resting outline of an accent-emphasised tile or chip (= line-strong, decorative; the label carries meaning). When the tile or chip is selected the outline becomes the 1.5px ink ring (border-selected in accent, 3:1 or better). */
    --focus-ring: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · 2px keyboard focus outline at a 2px offset, so the local ground shows as the gap. Monochrome in both themes: no hue. */
    --ok: #88b89b; /* oklch(0.740 0.066 158) · Status OK mark (filled circle; dot, marker, strip cell, glyph): Operational, Reporting, Resolved. Always beside a word. Lightness ladder: brighter than info and bad, below warn in dark; the lightest mark in light, so a healthy strip is the quietest thing on paper. */
    --ok-text: #99c7ab; /* oklch(0.789 0.063 158) · Status OK as text: the status word in tables, rails and badges. */
    --warn: #f6d69f; /* oklch(0.890 0.079 81) · Status WARN mark (filled triangle; dashed ring for Maintenance): Degraded, Delayed, Maintenance, SEV3, Identified. The lightest mark in dark; in light it sits between ok and info, so a degraded bucket darkens against the healthy mass. */
    --warn-text: #dec08e; /* oklch(0.822 0.074 80) · Status WARN as text. */
    --bad: #a95a55; /* oklch(0.560 0.104 25) · Status BAD mark (filled square): Down, Offline, SEV1, SEV2, Investigating. Also the notification count fill. The darkest status mark in both themes (louder on paper); on the map it is also the largest and the only one that rings. */
    --bad-text: #d7948f; /* oklch(0.731 0.082 24) · Status BAD as text: lighter than the mark in dark, equal to bad in light. */
    --on-bad: #ffffff; /* oklch(1.000 0.000 0) · Count numerals on a bad fill (the notification badge, Geist Mono 13px 500). */
    --info: #6488af; /* oklch(0.615 0.072 251) · Status INFO mark (filled diamond; hollow diamond for Awaiting agent): Probe error, Awaiting agent, Monitoring. */
    --info-text: #9bb7d7; /* oklch(0.769 0.055 252) · Status INFO as text. */
    --neutral: #82807d; /* oklch(0.601 0.005 78) · Status NEUTRAL mark (hollow ring, achromatic): Not monitored, Paused, Awaiting data, SEV4; the no-data line in uptime strips. */
    --neutral-text: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Status NEUTRAL as text (= text-3). */
    --ok-wash: #2a312c; /* oklch(0.305 0.013 154) · Tinted ground for ok badges, callouts and flagged rows, at quiet chroma. Text on it: ok-text (badge word), text-1 (callout title) or text-2 (callout body). */
    --ok-line: #4f6557; /* oklch(0.484 0.035 157) · Outline of ok badges and callouts (decorative; the word inside carries the meaning). */
    --warn-wash: #353026; /* oklch(0.311 0.019 85) · Tinted ground for warn badges, callouts and flagged rows, at quiet chroma. Text on it: warn-text (badge word), text-1 (callout title) or text-2 (callout body). */
    --warn-line: #6f6046; /* oklch(0.497 0.043 81) · Outline of warn badges and callouts (decorative; the word inside carries the meaning). */
    --bad-wash: #2d201f; /* oklch(0.259 0.020 24) · Tinted ground for bad badges, callouts and flagged rows, at quiet chroma. Text on it: bad-text (badge word), text-1 (callout title) or text-2 (callout body). */
    --bad-line: #593331; /* oklch(0.368 0.055 23) · Outline of bad badges and callouts (decorative; the word inside carries the meaning). */
    --info-wash: #262b30; /* oklch(0.286 0.012 248) · Tinted ground for info badges, callouts and flagged rows, at quiet chroma. Text on it: info-text (badge word), text-1 (callout title) or text-2 (callout body). */
    --info-line: #405061; /* oklch(0.424 0.035 250) · Outline of info badges and callouts (decorative; the word inside carries the meaning). */
    --neutral-wash: #252422; /* oklch(0.261 0.004 85) · Tinted ground for neutral badges, callouts and flagged rows, at quiet chroma. Text on it: neutral-text (badge word), text-1 (callout title) or text-2 (callout body). */
    --neutral-line: #464543; /* oklch(0.391 0.004 85) · Outline of neutral badges and callouts (decorative; the word inside carries the meaning). */
    --chart-1: #6c99b1; /* oklch(0.659 0.060 232) · Series 1 (sky), the first series of every chart, 2px lines. Quiet chroma: identity comes from the legend, direct labels and the lightness step, never from hue alone. Status hues never stand in for a series. */
    --chart-2: #6e5f8f; /* oklch(0.519 0.076 298) · Series 2 (violet), the darker step beside series 1 in dark and light. */
    --chart-3: #a49265; /* oklch(0.665 0.065 89) · Series 3 (gold), the lighter step. */
    --chart-4: #905862; /* oklch(0.526 0.075 8) · Series 4 (rose), the darker step. A fifth series folds into Other or small multiples; no generated hues. */
    --chart-grid: #23211f; /* oklch(0.249 0.005 68) · Chart gridlines (recessive, decorative). */
    --chart-axis: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Chart baseline and zero line (= line-strong, decorative; ticks are labelled). */
    --map-sea: #0c0b09; /* oklch(0.150 0.005 85) · Map field (the sea): a sunk plate inside its panel, and the Europe inset ground. Carries text-1, text-2, text-3 and the status words. */
    --map-land: #514f4d; /* oklch(0.429 0.004 68) · Land dots of the dot-matrix map (decorative). */
    --map-graticule: #1c1b19; /* oklch(0.222 0.004 85) · 30 degree graticule (10 degrees in the inset), decorative. */
    --map-outline: #2f2d2b; /* oklch(0.299 0.005 68) · Equal Earth globe outline and dotted equator (decorative). */
    --map-label-bg: #0c0b09db; /* oklch(0.150 0.005 85) at 86% · 86% map-sea plate behind map labels, so codes stay legible over land dots and routes. Carries text-1 and text-2. */
    --scrim: #060504a3; /* oklch(0.116 0.004 71) at 64% · Behind dialogs and the command palette. */
    --map-marker-offline: #a95a55; /* = --bad · oklch(0.560 0.104 25) · Map marker, Offline: FILLED SQUARE with a 2px map-sea halo; the only marker that may ring. */
    --map-marker-delayed: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Map marker, Delayed: FILLED TRIANGLE. */
    --map-marker-awaiting: #6488af; /* = --info · oklch(0.615 0.072 251) · Map marker, Awaiting agent: HOLLOW DIAMOND, 1.5px stroke. */
    --map-marker-maintenance: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Map marker, Maintenance: DASHED RING, 1.5px stroke, 2/2 dash. */
    --map-marker-reporting: #88b89b; /* = --ok · oklch(0.740 0.066 158) · Map marker, Reporting: small FILLED DOT, never labelled (a healthy network is quiet). */
    --map-marker-unmonitored: #82807d; /* = --neutral · oklch(0.601 0.005 78) · Map marker, Not monitored: HOLLOW RING, 1.5px stroke. */
    --map-marker-halo: #0c0b09; /* = --map-sea · oklch(0.150 0.005 85) · 2px ring under every marker so it lifts off the land dots and routes. */
    --map-route: #c5c2be; /* = --accent · oklch(0.815 0.006 75) · BERIFFANET backbone: 1.25px great-circle arcs in ink (text-2). Never a hue. */
    --map-route-planned: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Planned capacity: 1px line, 3/3 dash, in the quietest ink; always explained in the legend. */
    --map-label: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · State words beside exception markers, Geist Mono 13px (mono-small) on map-label-bg; the site code inside is text-1. */
    --map-selected: #c5c2be; /* = --accent · oklch(0.815 0.006 75) · 1.5px ink ring around the selected site. */
    --map-inset-frame: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Frame of the Western Europe inset and its traced area on the world map (decorative; the inset title names it). */
    --globe-sea: #2d2b29; /* = --line · oklch(0.290 0.005 68) · Globe (b-globe), the sea characters: the faint dotted ocean of the ASCII globe (":" on the lit side, "." further round), quieter than the land; with the land it gives the ball its round shape, as the old site's globe. Decorative and aria-hidden: the words beside the globe carry the meaning. Sits on the host ground (bg-ground, bg-sea, bg-surface-1); words may pass over it (they keep 4.5:1 over globe-land, the brighter of the two). */
    --globe-land: #363432; /* oklch(0.326 0.004 68) · Globe (b-globe), the land characters (the old site's ramp "+*#%@", dim to lit; lambert shading picks the character, so the lit side reads denser). A low-contrast backdrop, about the old site's 20% opacity: text-1, text-2 and text-3 keep 4.5:1 over it in both themes, so a hero's words stay readable where the globe passes behind them. Decorative. */
    --globe-node: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Globe (b-globe), a place: the bullet character in the grid, the brightest thing in the globe (3:1 on the host ground). Its name sits beside it in globe-name. */
    --globe-name: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Globe (b-globe), a place's name: Geist Mono capitals in the grid, one blank cell from its bullet, on blank cells (the globe's characters step aside), so it reads on the host ground at 4.5:1. */
    --uptime-ok: #88b89b; /* = --ok · oklch(0.740 0.066 158) · Uptime strip bucket with 100% successful checks: full height. */
    --uptime-warn: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Uptime strip bucket at 90 to 99.99%: 62% height. */
    --uptime-bad: #a95a55; /* = --bad · oklch(0.560 0.104 25) · Uptime strip bucket below 90%: 30% height. */
    --uptime-probe: #6488af; /* = --info · oklch(0.615 0.072 251) · Uptime strip bucket with probe errors only (our side failed): outlined and hatched, full height. */
    --uptime-empty: #82807d; /* = --neutral · oklch(0.601 0.005 78) · Uptime strip bucket with no data: a 2px flat line, never drawn as a pass. */
    --chart-label: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Chart tick labels, Geist Mono 13px (mono-small), on bg-surface-1. */
    --chart-crosshair: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · Hover crosshair, 1px dashed, on bg-surface-1 (3:1 or better). */
    --link: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Inline link text: ink, underlined (never a hue). Same grounds and ratios as text-1: every ground, panel, overlay, input and wash. */
    --link-decoration: #767472; /* = --line-control · oklch(0.560 0.004 68) · Link underline at rest (offset 0.2em, 1px), the non-colour cue that text is a link, so it reaches 3:1 on every ground; becomes text-1 on hover. */
    --selection-bg: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Text selection ground (an ink step, visible on every surface); selected text stays text-1. */
    --logo-tile: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Neutral tile behind a published logo file whose ink is dark, so the file shows unchanged in every theme (the group brands' black PNG marks on BERIFFA.com): paper in dark, the panel white in light. Never recolour or invert the file instead. Carries the files' black ink only. */
    --shadow-overlay: 0 0 0 1px #2d2b29, 0 12px 32px -8px #00000099, 0 2px 6px #00000059; /* The only drop shadow in the system: menus, popovers, the command palette, toasts, dialogs. A 1px line ring plus a soft fall. Panels are flat and separated by line. */
    --shadow-ring-primary: 0 0 0 2px #f1eeea; /* Primary button hover: a 2px ring of the fill colour, so the button grows without moving. */
    --shadow-control: inset 0 0 0 1px #767472; /* Inset 1px line-control outline for inputs, selects and the search field (keeps outlined and filled controls the same size). */
  }
}
:root[data-theme="dark"], [data-theme="dark"], .dark {
  color-scheme: dark;
  --bg-sea: #0c0b09; /* oklch(0.150 0.005 85) · Deepest ground. Dark: near-black warm graphite for the sidebar, the map field and the sign-in map zone. Light: the warm paper step below the page. Carries text-1, text-2, text-3 and every status text step. */
  --bg-ground: #13110f; /* oklch(0.179 0.005 67) · Page canvas behind panels, and the header bar. Dark: warm graphite; light: warm paper. Carries text-1, text-2, text-3 and every status text step. */
  --bg-surface-1: #191816; /* oklch(0.209 0.004 85) · Panels, cards, table body, chart surface, joined tiles. One small lightness step above the ground in dark; the whitest paper in light. Carries every text token. */
  --bg-surface-2: #211f1d; /* oklch(0.241 0.005 68) · One step from a panel: tab track, table head band, hovered and selected rows, active nav item, secondary button fill in dark. Carries every text token. */
  --bg-surface-3: #282725; /* oklch(0.273 0.004 85) · Overlays only: menus, popovers, tooltips, toasts and dialogs, always with shadow-overlay. In light it is white. Carries every text token. */
  --text-1: #f1eeea; /* oklch(0.950 0.006 75) · Primary text, headings, stat numbers, values and active icons. Paper-white in dark (not #fff, to cut halation), ink in light. */
  --text-2: #c5c2be; /* oklch(0.815 0.006 75) · Secondary text: ledes, descriptions, nav labels, secondary cells, inactive icons, map state words. Also the ink that draws routes (accent). */
  --text-3: #a39f9b; /* oklch(0.705 0.007 68) · Quietest text allowed: meta, timestamps, axis and tick labels, eyebrows, placeholders, legend counts. Tuned brighter in dark so quiet text never sinks. Not for use on washes. */
  --text-disabled: #656360; /* oklch(0.501 0.005 78) · Disabled control labels only (WCAG-exempt); never the only carrier of information. Sits on bg-surface-2 (disabled button) or bg-input. */
  --line-subtle: #242220; /* oklch(0.253 0.005 68) · Table row rules and dividers inside a panel (decorative). */
  --line: #2d2b29; /* oklch(0.290 0.005 68) · Panel outlines, section rules, header and sidebar edges, joined-tile gaps (decorative). */
  --line-strong: #403e3c; /* oklch(0.365 0.004 68) · Emphasised rules, chart baseline, secondary-button ring, kbd outline, Europe inset frame, text selection (decorative; a label always identifies the thing). */
  --line-control: #767472; /* oklch(0.560 0.004 68) · Boundaries that identify a control: input, select, checkbox and radio outlines, dashed not-configured boxes. */
  --bg-input: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Fill of inputs, selects, textareas and unchecked checkboxes: bg-surface-2 in dark, white in light so a field reads as fresh paper. Carries text-1 values and text-3 placeholders. */
  --primary: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Primary button fill and checked checkbox: paper-white in dark (beriffa.com's white button), ink in light. Hover grows a 2px ring of the same colour (shadow-ring-primary). */
  --on-primary: #13110f; /* = --bg-ground · oklch(0.179 0.005 67) · Label and icon on primary and primary-press. */
  --primary-press: #d6d4d0; /* oklch(0.870 0.006 85) · Primary fill while pressed. */
  --secondary: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Secondary button fill (bg-surface-2 in dark, bg-surface-1 in light) with an inset line-strong ring. */
  --on-secondary: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Label on secondary and secondary-hover. */
  --secondary-hover: #282725; /* = --bg-surface-3 · oklch(0.273 0.004 85) · Secondary and ghost button hover fill. */
  --danger: #a9443c; /* oklch(0.521 0.135 27) · The system's one red fill: destructive buttons (Delete server, Revoke token) and, under the Owner decision "Attention in red", the incident and critical security surfaces: the alert button (b-button--alert, the incident contact's "Call now"), the filled critical notice (b-site-notice--filled) and the IncidentBand's glyph. Quiet red at 75% of Graphite chroma. Never a status mark of a monitored thing, never a link, never error text (errors use bad-text). */
  --on-danger: #ffffff; /* oklch(1.000 0.000 0) · Label on danger and danger-press: destructive and alert button labels, and the filled critical notice's words, glyph, link, close and focus ring. */
  --danger-press: #953831; /* oklch(0.470 0.127 27) · Danger fill while pressed (destructive and alert buttons); the filled critical notice's bottom line and its close button's hover. */
  --danger-wash: #201312; /* oklch(0.204 0.022 24) · Tinted ground of the IncidentBand (b-incident, the incident contact; Owner decision "Attention in red"): a low red step over the page, as the old site's red-tinted panel, dark enough that the danger fill keeps its 3:1 edge on it (the alert button, the glyph). Text on it: text-1 (title, the incident number), text-2 (body, label, the e-mail link), bad-text (eyebrow). Its outline is bad-line. Used nowhere else. */
  --accent: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · Ink as accent (= text-2): backbone routes on the map, the selected-site ring, the live tick. BERIFFA has no chromatic accent; emphasis is ink, weight and size. */
  --accent-text: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Accent as text (= text-1): a selected route name or a selected row label. Never a hue, never links. */
  --on-accent: #13110f; /* = --bg-ground · oklch(0.179 0.005 67) · Text on an accent (ink) fill, such as a selected route chip (= bg-ground). */
  --accent-wash: #211f1d; /* = --bg-surface-2 · oklch(0.241 0.005 68) · Selected tile, chip or row ground for accent emphasis (= bg-surface-2). Text on it: text-1 or text-2. A ground change is never the only selection cue: selection adds the 1.5px ink ring (border-selected in accent). */
  --accent-line: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Resting outline of an accent-emphasised tile or chip (= line-strong, decorative; the label carries meaning). When the tile or chip is selected the outline becomes the 1.5px ink ring (border-selected in accent, 3:1 or better). */
  --focus-ring: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · 2px keyboard focus outline at a 2px offset, so the local ground shows as the gap. Monochrome in both themes: no hue. */
  --ok: #88b89b; /* oklch(0.740 0.066 158) · Status OK mark (filled circle; dot, marker, strip cell, glyph): Operational, Reporting, Resolved. Always beside a word. Lightness ladder: brighter than info and bad, below warn in dark; the lightest mark in light, so a healthy strip is the quietest thing on paper. */
  --ok-text: #99c7ab; /* oklch(0.789 0.063 158) · Status OK as text: the status word in tables, rails and badges. */
  --warn: #f6d69f; /* oklch(0.890 0.079 81) · Status WARN mark (filled triangle; dashed ring for Maintenance): Degraded, Delayed, Maintenance, SEV3, Identified. The lightest mark in dark; in light it sits between ok and info, so a degraded bucket darkens against the healthy mass. */
  --warn-text: #dec08e; /* oklch(0.822 0.074 80) · Status WARN as text. */
  --bad: #a95a55; /* oklch(0.560 0.104 25) · Status BAD mark (filled square): Down, Offline, SEV1, SEV2, Investigating. Also the notification count fill. The darkest status mark in both themes (louder on paper); on the map it is also the largest and the only one that rings. */
  --bad-text: #d7948f; /* oklch(0.731 0.082 24) · Status BAD as text: lighter than the mark in dark, equal to bad in light. */
  --on-bad: #ffffff; /* oklch(1.000 0.000 0) · Count numerals on a bad fill (the notification badge, Geist Mono 13px 500). */
  --info: #6488af; /* oklch(0.615 0.072 251) · Status INFO mark (filled diamond; hollow diamond for Awaiting agent): Probe error, Awaiting agent, Monitoring. */
  --info-text: #9bb7d7; /* oklch(0.769 0.055 252) · Status INFO as text. */
  --neutral: #82807d; /* oklch(0.601 0.005 78) · Status NEUTRAL mark (hollow ring, achromatic): Not monitored, Paused, Awaiting data, SEV4; the no-data line in uptime strips. */
  --neutral-text: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Status NEUTRAL as text (= text-3). */
  --ok-wash: #2a312c; /* oklch(0.305 0.013 154) · Tinted ground for ok badges, callouts and flagged rows, at quiet chroma. Text on it: ok-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --ok-line: #4f6557; /* oklch(0.484 0.035 157) · Outline of ok badges and callouts (decorative; the word inside carries the meaning). */
  --warn-wash: #353026; /* oklch(0.311 0.019 85) · Tinted ground for warn badges, callouts and flagged rows, at quiet chroma. Text on it: warn-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --warn-line: #6f6046; /* oklch(0.497 0.043 81) · Outline of warn badges and callouts (decorative; the word inside carries the meaning). */
  --bad-wash: #2d201f; /* oklch(0.259 0.020 24) · Tinted ground for bad badges, callouts and flagged rows, at quiet chroma. Text on it: bad-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --bad-line: #593331; /* oklch(0.368 0.055 23) · Outline of bad badges and callouts (decorative; the word inside carries the meaning). */
  --info-wash: #262b30; /* oklch(0.286 0.012 248) · Tinted ground for info badges, callouts and flagged rows, at quiet chroma. Text on it: info-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --info-line: #405061; /* oklch(0.424 0.035 250) · Outline of info badges and callouts (decorative; the word inside carries the meaning). */
  --neutral-wash: #252422; /* oklch(0.261 0.004 85) · Tinted ground for neutral badges, callouts and flagged rows, at quiet chroma. Text on it: neutral-text (badge word), text-1 (callout title) or text-2 (callout body). */
  --neutral-line: #464543; /* oklch(0.391 0.004 85) · Outline of neutral badges and callouts (decorative; the word inside carries the meaning). */
  --chart-1: #6c99b1; /* oklch(0.659 0.060 232) · Series 1 (sky), the first series of every chart, 2px lines. Quiet chroma: identity comes from the legend, direct labels and the lightness step, never from hue alone. Status hues never stand in for a series. */
  --chart-2: #6e5f8f; /* oklch(0.519 0.076 298) · Series 2 (violet), the darker step beside series 1 in dark and light. */
  --chart-3: #a49265; /* oklch(0.665 0.065 89) · Series 3 (gold), the lighter step. */
  --chart-4: #905862; /* oklch(0.526 0.075 8) · Series 4 (rose), the darker step. A fifth series folds into Other or small multiples; no generated hues. */
  --chart-grid: #23211f; /* oklch(0.249 0.005 68) · Chart gridlines (recessive, decorative). */
  --chart-axis: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Chart baseline and zero line (= line-strong, decorative; ticks are labelled). */
  --map-sea: #0c0b09; /* oklch(0.150 0.005 85) · Map field (the sea): a sunk plate inside its panel, and the Europe inset ground. Carries text-1, text-2, text-3 and the status words. */
  --map-land: #514f4d; /* oklch(0.429 0.004 68) · Land dots of the dot-matrix map (decorative). */
  --map-graticule: #1c1b19; /* oklch(0.222 0.004 85) · 30 degree graticule (10 degrees in the inset), decorative. */
  --map-outline: #2f2d2b; /* oklch(0.299 0.005 68) · Equal Earth globe outline and dotted equator (decorative). */
  --map-label-bg: #0c0b09db; /* oklch(0.150 0.005 85) at 86% · 86% map-sea plate behind map labels, so codes stay legible over land dots and routes. Carries text-1 and text-2. */
  --scrim: #060504a3; /* oklch(0.116 0.004 71) at 64% · Behind dialogs and the command palette. */
  --map-marker-offline: #a95a55; /* = --bad · oklch(0.560 0.104 25) · Map marker, Offline: FILLED SQUARE with a 2px map-sea halo; the only marker that may ring. */
  --map-marker-delayed: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Map marker, Delayed: FILLED TRIANGLE. */
  --map-marker-awaiting: #6488af; /* = --info · oklch(0.615 0.072 251) · Map marker, Awaiting agent: HOLLOW DIAMOND, 1.5px stroke. */
  --map-marker-maintenance: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Map marker, Maintenance: DASHED RING, 1.5px stroke, 2/2 dash. */
  --map-marker-reporting: #88b89b; /* = --ok · oklch(0.740 0.066 158) · Map marker, Reporting: small FILLED DOT, never labelled (a healthy network is quiet). */
  --map-marker-unmonitored: #82807d; /* = --neutral · oklch(0.601 0.005 78) · Map marker, Not monitored: HOLLOW RING, 1.5px stroke. */
  --map-marker-halo: #0c0b09; /* = --map-sea · oklch(0.150 0.005 85) · 2px ring under every marker so it lifts off the land dots and routes. */
  --map-route: #c5c2be; /* = --accent · oklch(0.815 0.006 75) · BERIFFANET backbone: 1.25px great-circle arcs in ink (text-2). Never a hue. */
  --map-route-planned: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Planned capacity: 1px line, 3/3 dash, in the quietest ink; always explained in the legend. */
  --map-label: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · State words beside exception markers, Geist Mono 13px (mono-small) on map-label-bg; the site code inside is text-1. */
  --map-selected: #c5c2be; /* = --accent · oklch(0.815 0.006 75) · 1.5px ink ring around the selected site. */
  --map-inset-frame: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Frame of the Western Europe inset and its traced area on the world map (decorative; the inset title names it). */
  --globe-sea: #2d2b29; /* = --line · oklch(0.290 0.005 68) · Globe (b-globe), the sea characters: the faint dotted ocean of the ASCII globe (":" on the lit side, "." further round), quieter than the land; with the land it gives the ball its round shape, as the old site's globe. Decorative and aria-hidden: the words beside the globe carry the meaning. Sits on the host ground (bg-ground, bg-sea, bg-surface-1); words may pass over it (they keep 4.5:1 over globe-land, the brighter of the two). */
  --globe-land: #363432; /* oklch(0.326 0.004 68) · Globe (b-globe), the land characters (the old site's ramp "+*#%@", dim to lit; lambert shading picks the character, so the lit side reads denser). A low-contrast backdrop, about the old site's 20% opacity: text-1, text-2 and text-3 keep 4.5:1 over it in both themes, so a hero's words stay readable where the globe passes behind them. Decorative. */
  --globe-node: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Globe (b-globe), a place: the bullet character in the grid, the brightest thing in the globe (3:1 on the host ground). Its name sits beside it in globe-name. */
  --globe-name: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Globe (b-globe), a place's name: Geist Mono capitals in the grid, one blank cell from its bullet, on blank cells (the globe's characters step aside), so it reads on the host ground at 4.5:1. */
  --uptime-ok: #88b89b; /* = --ok · oklch(0.740 0.066 158) · Uptime strip bucket with 100% successful checks: full height. */
  --uptime-warn: #f6d69f; /* = --warn · oklch(0.890 0.079 81) · Uptime strip bucket at 90 to 99.99%: 62% height. */
  --uptime-bad: #a95a55; /* = --bad · oklch(0.560 0.104 25) · Uptime strip bucket below 90%: 30% height. */
  --uptime-probe: #6488af; /* = --info · oklch(0.615 0.072 251) · Uptime strip bucket with probe errors only (our side failed): outlined and hatched, full height. */
  --uptime-empty: #82807d; /* = --neutral · oklch(0.601 0.005 78) · Uptime strip bucket with no data: a 2px flat line, never drawn as a pass. */
  --chart-label: #a39f9b; /* = --text-3 · oklch(0.705 0.007 68) · Chart tick labels, Geist Mono 13px (mono-small), on bg-surface-1. */
  --chart-crosshair: #c5c2be; /* = --text-2 · oklch(0.815 0.006 75) · Hover crosshair, 1px dashed, on bg-surface-1 (3:1 or better). */
  --link: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Inline link text: ink, underlined (never a hue). Same grounds and ratios as text-1: every ground, panel, overlay, input and wash. */
  --link-decoration: #767472; /* = --line-control · oklch(0.560 0.004 68) · Link underline at rest (offset 0.2em, 1px), the non-colour cue that text is a link, so it reaches 3:1 on every ground; becomes text-1 on hover. */
  --selection-bg: #403e3c; /* = --line-strong · oklch(0.365 0.004 68) · Text selection ground (an ink step, visible on every surface); selected text stays text-1. */
  --logo-tile: #f1eeea; /* = --text-1 · oklch(0.950 0.006 75) · Neutral tile behind a published logo file whose ink is dark, so the file shows unchanged in every theme (the group brands' black PNG marks on BERIFFA.com): paper in dark, the panel white in light. Never recolour or invert the file instead. Carries the files' black ink only. */
  --shadow-overlay: 0 0 0 1px #2d2b29, 0 12px 32px -8px #00000099, 0 2px 6px #00000059; /* The only drop shadow in the system: menus, popovers, the command palette, toasts, dialogs. A 1px line ring plus a soft fall. Panels are flat and separated by line. */
  --shadow-ring-primary: 0 0 0 2px #f1eeea; /* Primary button hover: a 2px ring of the fill colour, so the button grows without moving. */
  --shadow-control: inset 0 0 0 1px #767472; /* Inset 1px line-control outline for inputs, selects and the search field (keeps outlined and filled controls the same size). */
}

/* Reduced motion: every dur-* token drops to 0ms. Routes are drawn in full, the
   Offline marker keeps a static ring, and live values still update. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-press: 0ms;
    --dur-state: 0ms;
    --dur-overlay: 0ms;
    --dur-panel: 0ms;
    --dur-reveal: 0ms;
    --dur-draw: 0ms;
    --dur-ping: 0ms;
  }
}
