/* Shared by every page: colour tokens, type, reset, the site header (.nav), the footer and buttons.
   Page styles: site.css (home, docs, legal, learn), map.css (map), benchmark.css (scoreboard).
   Dark (deep European blue) by default; light under [data-theme=light]. Each page sets data-theme before first paint
   from localStorage 'rn.theme', ?theme= or the OS setting (js/theme.js keeps it); the media query below only covers
   pages without JS. Rain teal (--accent) is the one accent; --link is the blue of links in running text. */
:root {
  --bg: #0b1833; --bg-2: #0e1e3f; --surface: rgba(14, 30, 63, 0.86); --surface-solid: #11234a; --surface-2: rgba(170, 195, 255, 0.06);
  --border: rgba(170, 195, 255, 0.14); --text: #e8edf8; --text-dim: #a6b3d1; --text-faint: #7d8bb2;
  --accent: #3fcfbf; --accent-ink: #062a2a; --link: #9cbcff; --warn: #e8b06a; --dry: #6fcf9a; --prob: #8fb4e8;
  --code-bg: #081329;
  --logo-a: #3987e5; --logo-b: #b05cc4; /* the brand mark's gradient (the hero's --s1 to purple) */
  --font: 'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  /* --text-faint is the palest text colour: still 4.5:1 or more on --bg, --bg-2 and --surface-solid in both themes */
  --r: 12px; --gutter: 16px; --gutter-l: max(var(--gutter), env(safe-area-inset-left)); --gutter-r: max(var(--gutter), env(safe-area-inset-right)); --gap: 10px; --nav-h: 60px; /* nav-h: height of the header */
  --wrap: 1120px;
  --blur: saturate(1.2) blur(14px);
  --shadow: 0 8px 28px rgba(2, 8, 24, 0.35);
  color-scheme: dark;
}
:root[data-theme='light'] {
  --bg: #f3f6fb; --bg-2: #e8eef8; --surface: rgba(255, 255, 255, 0.9); --surface-solid: #ffffff; --surface-2: rgba(12, 40, 110, 0.05);
  --border: rgba(12, 40, 110, 0.14); --text: #0c1a3a; --text-dim: #45557b; --text-faint: #5a6789;
  --accent: #087d72; --accent-ink: #ffffff; --link: #1f48b8; --warn: #a8641c; --dry: #2a8f5c; --prob: #2c5fb3;
  --code-bg: #0c1a3a; --logo-a: #2a78d6; --logo-b: #b05cc4;
  --shadow: 0 8px 28px rgba(12, 30, 80, 0.12);
  color-scheme: light;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme]) {
    --bg: #f3f6fb; --bg-2: #e8eef8; --surface: rgba(255, 255, 255, 0.9); --surface-solid: #ffffff; --surface-2: rgba(12, 40, 110, 0.05);
    --border: rgba(12, 40, 110, 0.14); --text: #0c1a3a; --text-dim: #45557b; --text-faint: #5a6789;
    --accent: #087d72; --accent-ink: #ffffff; --link: #1f48b8; --warn: #a8641c; --dry: #2a8f5c; --prob: #2c5fb3;
    --code-bg: #0c1a3a; --logo-a: #2a78d6; --logo-b: #b05cc4;
    color-scheme: light;
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; }
/* no double-tap zoom (iOS Safari): a double tap is two taps, not a zoom; pinch-zoom and scrolling stay (the viewport
   meta does not forbid scaling). Set on the document and on what is tapped; the map's own gestures are JS (a double tap
   on the map zooms the MAP) and the time bar's track says touch-action: none itself. */
html { touch-action: manipulation; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
a, button, summary, label, input, select, textarea, [role='button'], [tabindex] { touch-action: manipulation; }
/* iOS Safari zooms the page when a field under 16 px gets focus: on touch screens fields are 16 px or more */
@media (pointer: coarse) { input, textarea, select { font-size: max(16px, 1em); } }
body { background: var(--bg); color: var(--text); font: 400 16px/1.6 var(--font); -webkit-font-smoothing: antialiased; }
/* a page shorter than the screen (the 404 page, a newsletter confirmation) still ends with its footer at the bottom edge;
   main takes the room left (width 100%: a main centred by its own margins would otherwise shrink to its content) */
body:has(> .site-footer) { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
body:has(> .site-footer) > main { flex: 1 0 auto; width: 100%; }
body:has(> .site-footer) > .site-footer { flex: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
/* one focus ring everywhere, also on what the browser makes focusable itself (a code sample or table that scrolls sideways) */
button:focus-visible, a:focus-visible, input:focus-visible, summary:focus-visible, [tabindex]:focus-visible, pre:focus-visible, .table-wrap:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; }
a { color: inherit; text-decoration: underline; text-decoration-color: var(--text-faint); text-underline-offset: 3px; }
a:hover { color: var(--text); text-decoration-color: currentColor; }
code, pre, kbd { font-family: var(--mono); }
[hidden] { display: none !important; }
/* no lone last word: headings balance their lines, running text avoids a one-word last line (where supported) */
h1, h2, h3 { text-wrap: balance; }
p, li, dd, figcaption, caption, td { text-wrap: pretty; }
/* on a phone, running text fills the column: Safari evens out every line of a "pretty" paragraph, which left text blocks
   ending at three quarters of the width beside full-width buttons and the map (owner's iPhone, 2026-11-13) */
@media (max-width: 639px) { p, li, dd, figcaption, caption, td { text-wrap: wrap; } }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }
.skip { position: absolute; left: 8px; top: -60px; z-index: 20; padding: 8px 12px; border-radius: 8px; background: var(--accent); color: var(--accent-ink); }
.skip:focus { top: 8px; }

/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 42px; padding: 0 18px; border-radius: 10px;
       font-size: 15px; font-weight: 600; text-decoration: none; color: var(--text); border: 1px solid var(--border); background: var(--surface-2);
       transition: background-color .15s, border-color .15s; white-space: nowrap; }
.btn:hover { border-color: var(--text-faint); color: var(--text); }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.btn.primary:hover { background: color-mix(in srgb, var(--accent) 88%, var(--text)); color: var(--accent-ink); }
.btn.small { min-height: 34px; padding: 0 12px; font-size: 14px; border-radius: 8px; }

/* ---------- brand mark: a pixel raindrop, 12 x 14 cells at 2 px each (crisp at any pixel ratio), in the hero's
   blue-to-purple; drawn by scripts/brand_assets.py (which also writes favicon.svg and apple-touch-icon.png) ---------- */
.mark { width: 24px; height: 28px; flex: none; display: block; }
.mark stop:first-child { stop-color: var(--logo-a); }
.mark stop:last-child { stop-color: var(--logo-b); }

/* ---------- site header (one markup for every page: partials/header.html) ---------- */
.nav { position: sticky; z-index: 6; top: 0; height: var(--nav-h); display: flex; align-items: center; gap: 4px;
       padding: 0 max(var(--gutter-r), calc((100% - var(--wrap)) / 2 + var(--gutter))) 0 max(var(--gutter-l), calc((100% - var(--wrap)) / 2 + var(--gutter))); font-size: 14.5px; white-space: nowrap; isolation: isolate;
       transition: transform 0.25s ease, opacity 0.25s ease; }
/* the bar's glass is a child layer, not the nav's own background: iOS Safari 26 tints its status bar from the
   background of fixed/sticky elements at the screen edge */
.nav::before { content: ''; position: absolute; z-index: -1; inset: 0; background: color-mix(in srgb, var(--bg) 88%, transparent);
               border-bottom: 1px solid var(--border); backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur); }
.nav .brand { display: inline-flex; align-items: center; gap: 9px; margin-right: auto; font-weight: 600; font-size: 16px; color: var(--text); text-decoration: none;
              min-height: 40px; }
.nav .brand span { letter-spacing: -0.005em; }
.nav-links { display: flex; align-items: center; gap: 2px; margin: 0; padding: 0; list-style: none; }
.nav-links a { display: block; padding: 6px 10px; border-radius: 8px; color: var(--text-dim); text-decoration: none; }
.nav-links a:hover { color: var(--text); background: var(--surface-2); }
.nav-links a[aria-current='page'] { color: var(--text); box-shadow: inset 0 -2px 0 var(--accent); border-radius: 0; }
.nav .theme { margin: 0 6px 0 8px; }
/* the account entry: "Sign in" after the links, set apart from them (nav.js hides it once signed in, when the button
   says "Dashboard"); in the phone menu it is the last line */
.nav-links .nav-account { margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--border); }
.nav-links .nav-account a { color: var(--text); font-weight: 500; }
.nav-links .nav-account[hidden] { display: none; }
.nav .cta { min-height: 36px; padding: 0 14px; font-size: 14px; border-radius: 9px; }
.menu-btn { display: none; }
.nav-handle { display: none; }
/* scrolling pages: the header slides away while scrolling down, back on scrolling up (nav.js) */
body.nav-away:not(.menu-open) .nav { transform: translateY(-100%); opacity: 0; }

.icon-btn { width: 34px; height: 34px; display: grid; place-items: center; border-radius: 9px; color: var(--text-dim); background: var(--surface-2); }
.icon-btn:hover { color: var(--text); }
.icon-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
:root[data-theme='light'] .i-moon, :root:not([data-theme='light']) .i-sun { display: none; }

/* the map: the same header, as a floating pill over the full-screen map (map.css places it) */
.map-page .nav { top: 8px; height: 44px; width: max-content; max-width: calc(100% - var(--gutter-l) - var(--gutter-r)); padding: 0 5px 0 14px; border-radius: 14px; font-size: 13.5px; }
.map-page .nav::before { border-radius: inherit; border: 1px solid var(--border); background: var(--surface); box-shadow: var(--shadow); }
.map-page .nav .brand { margin-right: 10px; font-size: 14.5px; }
.map-page .nav .cta, .map-page .nav .theme { min-height: 32px; height: 32px; }
.map-page .nav .theme { width: 32px; }
.map-page { --nav-h: 52px; }

/* narrow: the links fold into a menu under the header */
@media (max-width: 1000px) {
  .menu-btn { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 10px; border-radius: 9px; color: var(--text); background: var(--surface-2); font-size: 14px; }
  .menu-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
  .nav-links { display: none; position: absolute; top: calc(100% + 6px); right: var(--gutter-r); min-width: 220px; flex-direction: column; align-items: stretch;
               padding: 6px; border-radius: 12px; background: var(--surface-solid); border: 1px solid var(--border); box-shadow: var(--shadow); }
  .menu-open .nav-links { display: flex; }
  .nav-links a { padding: 10px 12px; font-size: 15px; }
  .nav-links a[aria-current='page'] { box-shadow: inset 3px 0 0 var(--accent); border-radius: 0 8px 8px 0; }
  .nav .theme { margin: 0 4px; }
  .nav .cta { margin-left: 4px; }
  .nav-links .nav-account { margin: 4px 0 0; padding: 4px 0 0; border-left: 0; border-top: 1px solid var(--border); }
}
@media (max-width: 759px) {
  :root { --gutter: 16px; --nav-h: 56px; }
  .map-page { --nav-h: 0px; }
  .nav .brand span { font-size: 15px; }
}
@media (max-width: 420px) {
  .nav .cta { padding: 0 10px; font-size: 13px; }
  .nav .brand span.long { display: none; }
  .menu-btn .lbl { display: none; }
}

/* ---------- footer (partials/footer.html) ---------- */
.site-footer { margin-top: 96px; border-top: 1px solid var(--border); background: var(--bg-2); font-size: 14.5px; color: var(--text-dim); }
.site-footer .inner { max-width: var(--wrap); margin: 0 auto; padding: 48px var(--gutter-r) 36px var(--gutter-l); }
/* link columns as wide as their longest link (no label wraps), the brand column takes the rest */
.site-footer .cols { display: grid; grid-template-columns: minmax(0, 1fr) repeat(4, max-content); gap: 28px 44px; }
.site-footer h2 { font-size: 14px; font-weight: 600; color: var(--text); margin: 0 0 6px; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; }
/* each link a tap target of 32 px or more: the list links, the Learn heading's link, the address, the brand */
.site-footer li a, .site-footer h2 a, .site-footer .about p a { display: inline-block; padding: 4.5px 0; }
.site-footer h2 a { padding: 5px 0; margin: -5px 0; }  /* 14 px type: 5 px each side for 32 px */
.site-footer .about p a { margin: -4.5px 0; }
.site-footer a { text-decoration: none; }
.site-footer a:hover { color: var(--text); text-decoration: underline; }
.site-footer .brand { display: inline-flex; align-items: center; gap: 9px; min-height: 32px; color: var(--text); font-weight: 600; font-size: 16px; }
.site-footer .about p { margin: 10px 0 0; max-width: 34ch; }
.site-footer .legal { margin-top: 36px; padding-top: 18px; border-top: 1px solid var(--border); display: flex; flex-wrap: wrap; gap: 6px 24px; font-size: 13px; color: var(--text-faint); }
@media (max-width: 860px) {
  /* two columns spanning the whole width: the first as wide as its longest link (so "Radar coverage in Europe" stays
     on one line at 390 and 360), the second takes the rest and may shrink (two max-content columns left the grid
     short of the right gutter, and past it at 320 px; two equal ones wrapped that link) */
  .site-footer .cols { grid-template-columns: max-content minmax(0, 1fr); gap: 28px 28px; }
  .site-footer .about { grid-column: 1 / -1; }
}
@media (max-width: 400px) { .site-footer .cols { column-gap: 16px; } }

/* phone hero (home): headline, badge, lede, buttons and facts share one left edge and one right edge: the two buttons
   split the row evenly (stacked when it is too narrow for both), the four facts sit in two columns, the second ending at the right gutter */
@media (max-width: 639px) {
  main .hero .actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 172px), 1fr)); }
  main .hero .facts { grid-template-columns: repeat(2, max-content); justify-content: space-between; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* the Turnstile widget (js/turnstile.js: the map token, the newsletter sign-up): invisible unless Cloudflare asks the visitor to click */
.ts-box { position: fixed; z-index: 20; left: 50%; top: 40%; transform: translateX(-50%); }
