/* ==========================================================================
   FIBCOS — PRODUCT SYSTEM v3
   A digital product for exploring global Structural Alpha.

   Principles
   1. THE PRODUCT IS A SURFACE, NOT A DOCUMENT. Dark instrument canvas,
      layered surfaces, real controls. You operate it; you don't read it.
   2. THE WORLD IS THE INTERFACE. 44 markets sit at their true coordinates.
      Navigation is spatial before it is textual.
   3. DISCLOSE PROGRESSIVELY. Peek before you commit; expand before you
      navigate; switch views without losing your place.
   4. ONE ACCENT MEANS ONE THING. Alpha Mint marks Alpha position, current
      state and live selection. Nothing else may use it.

   Contents
   00 Tokens          08 Explorer (world map)
   01 Base            09 Data surfaces: stats, meters, tables
   02 Type            10 Charts
   03 Layout          11 Alpha Line
   04 App chrome      12 Reading & documents
   05 Command palette 13 Empty states
   06 Switcher & peek 14 Forms & filters
   07 Controls        15 Footer, utilities, motion
   ========================================================================== */

/* Typefaces — self-hosted so the site has no third-party dependency and
   renders identically behind a firewall or on a cPanel host. */
@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/sora-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/sora-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/sora-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/manrope-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/manrope-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/manrope-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/manrope-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

/* 00 — Tokens ============================================================= */

/* Colour is declared twice and only twice: once per theme, entirely in this
   block. Nothing below section 00 hard-codes a colour, so a theme is a set of
   token values rather than a parallel stylesheet.

   Every pair below is verified by `node scripts/contrast.js`, which composites
   translucent values over their backdrop and holds each role to the threshold
   WCAG specifies for it — 4.5:1 for text, 3:1 for state-bearing marks. */

:root {
  color-scheme: dark;

  /* Canvas: cool near-black with a blue cast, layered upward */
  --ink-900: #080a0e;
  --ink-850: #0b0e14;
  --ink-800: #0d1016;
  --ink-700: #141822;
  --ink-600: #1b202b;
  --ink-500: #262c39;

  --line:    rgba(255, 255, 255, 0.07);
  --line-2:  rgba(255, 255, 255, 0.12);
  --line-3:  rgba(255, 255, 255, 0.2);

  /* Flags carry their own colours, so their edge is drawn in the surrounding
     ink rather than in a line token — a white-fielded flag (Japan, Israel)
     needs a boundary on a pale page and none of the line tokens is dark
     enough there to supply one. */
  --flag-edge: rgba(0, 0, 0, 0.42);

  --fg-hi:   #ffffff;
  --fg:      #e8ecf2;
  --fg-2:    #a2acbc;
  --fg-3:    #7a8496;

  /* THE ONE ACCENT — Alpha Mint. Alpha position, current state, selection. */
  --alpha:       #5fd3a6;
  --alpha-hover: #74e0b6;
  --alpha-dim:   rgba(95, 211, 166, 0.14);
  --alpha-line:  rgba(95, 211, 166, 0.35);
  --alpha-ring:  rgba(95, 211, 166, 0.16);
  --alpha-wash:  rgba(95, 211, 166, 0.05);
  --on-alpha:    #05231a;

  /* Second series + semantics */
  --ion:     #8ab4ff;
  --warn:    #e9b872;
  --rose:    #f08a7c;

  --st-active:  var(--alpha);
  --st-review:  var(--warn);
  --st-removed: var(--rose);
  --st-pending: #8b96a6;

  /* The outline that draws an UNREACHED Alpha node, tick or trail marker,
     and the em-dash placeholder figure. The absence of the accent is the
     state, so this has to clear the 3:1 non-text threshold. */
  --stroke-off: #6b7484;

  /* Chrome and overlays */
  --bar-bg:      rgba(8, 10, 14, 0.72);
  --sheet-bg:    rgba(8, 10, 14, 0.6);
  --scrim:       rgba(4, 6, 9, 0.5);
  --scrim-2:     rgba(4, 6, 9, 0.6);
  --scrim-3:     rgba(4, 6, 9, 0.72);
  --dot:         rgba(255, 255, 255, 0.045);

  /* Explorer geography — decorative structure, never data */
  --geo-grid:       rgba(255, 255, 255, 0.065);
  --geo-grid-major: rgba(255, 255, 255, 0.1);
  --geo-link:       rgba(255, 255, 255, 0.1);
  --geo-hub:        rgba(255, 255, 255, 0.18);
  --geo-land:       rgba(255, 255, 255, 0.075);
  --geo-mkt:        rgba(95, 211, 166, 0.3);
  --geo-mkt-on:     rgba(95, 211, 166, 0.62);
  /* The hairline between two countries is negative space — the surface
     showing through — not a mark of its own. */
  --geo-edge:       rgba(8, 10, 14, 0.85);

  --shadow:      0 1px 2px rgba(0,0,0,.4), 0 8px 24px -12px rgba(0,0,0,.7);
  --shadow-lg:   0 24px 70px -20px rgba(0,0,0,.85);
  --shadow-soft: 0 1px 2px rgba(0,0,0,.3), 0 14px 40px -20px rgba(0,0,0,.6);

  /* Type */
  --display: "Sora", "Segoe UI", system-ui, sans-serif;
  --ui: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --t-hero: clamp(3rem, 8vw, 7rem);
  --t-xl:   clamp(2.25rem, 5.2vw, 4.25rem);
  --t-lg:   clamp(1.75rem, 3.2vw, 2.75rem);
  --t-md:   1.375rem;
  --t-base: 1rem;
  --t-sm:   0.875rem;
  --t-xs:   0.75rem;

  /* Space */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 36px; --s7: 56px; --s8: 96px; --s9: 144px;

  /* Shape — soft and generous. Large surfaces round hard, controls round
     fully, and small chrome keeps just enough radius to feel of a piece. */
  --r-sm: 10px;
  --r: 16px;
  --r-lg: 24px;
  --r-xl: 32px;
  --r-full: 999px;

  --wrap: 1360px;
  --pad: 20px;
  --bar: 60px;

  --ease: cubic-bezier(.2,.7,.2,1);
  --spring: cubic-bezier(.22,1.2,.36,1);
  --settle: cubic-bezier(.16,1,.3,1);
}

/* LIGHT — the same instrument on paper, not an inverted screenshot. The
   surfaces warm slightly as they rise, the accent darkens to hold 4.5:1 on
   white, and shadows become soft rather than deep. */
[data-theme="light"] {
  color-scheme: light;

  --ink-900: #ffffff;
  --ink-850: #f7f8fa;
  --ink-800: #ffffff;
  --ink-700: #f2f4f7;
  --ink-600: #e6eaf0;
  --ink-500: #ccd4df;

  --line:    rgba(10, 16, 26, 0.10);
  --line-2:  rgba(10, 16, 26, 0.16);
  --line-3:  rgba(10, 16, 26, 0.28);

  --flag-edge: rgba(10, 16, 26, 0.30);

  --fg-hi:   #080d15;
  --fg:      #1b2431;
  --fg-2:    #455266;
  --fg-3:    #5c6675;

  --alpha:       #00785a;
  --alpha-hover: #00614a;
  --alpha-dim:   rgba(0, 120, 90, 0.10);
  --alpha-line:  rgba(0, 120, 90, 0.30);
  --alpha-ring:  rgba(0, 120, 90, 0.14);
  --alpha-wash:  rgba(0, 120, 90, 0.045);
  --on-alpha:    #ffffff;

  --ion:  #2451c4;
  --warn: #8a5300;
  --rose: #b3271d;

  --st-pending: #5b6675;
  --stroke-off: #79818f;

  --bar-bg:   rgba(255, 255, 255, 0.82);
  --sheet-bg: rgba(255, 255, 255, 0.76);
  --scrim:    rgba(18, 26, 38, 0.28);
  --scrim-2:  rgba(18, 26, 38, 0.36);
  --scrim-3:  rgba(18, 26, 38, 0.44);
  --dot:      rgba(10, 16, 26, 0.05);

  --geo-grid:       rgba(10, 16, 26, 0.08);
  --geo-grid-major: rgba(10, 16, 26, 0.14);
  --geo-link:       rgba(10, 16, 26, 0.16);
  --geo-hub:        rgba(10, 16, 26, 0.3);
  --geo-land:       rgba(10, 16, 26, 0.085);
  --geo-mkt:        rgba(0, 120, 90, 0.3);
  --geo-mkt-on:     rgba(0, 120, 90, 0.62);
  --geo-edge:       rgba(255, 255, 255, 0.92);

  --shadow:    0 1px 2px rgba(16,24,40,.05), 0 10px 30px -14px rgba(16,24,40,.16);
  --shadow-lg: 0 30px 80px -28px rgba(16,24,40,.24);
  /* Soft lift for raised tiles — the reference leans on shadow, not borders. */
  --shadow-soft: 0 1px 3px rgba(16,24,40,.04), 0 14px 40px -20px rgba(16,24,40,.18);
}

@media (min-width: 800px) { :root { --pad: 32px; } }
@media (min-width: 1200px) { :root { --pad: 48px; --bar: 64px; } }

/* 01 — Base =============================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--bar) + 64px); }

body {
  margin: 0;
  background: var(--ink-900);
  color: var(--fg);
  font-family: var(--ui);
  font-size: var(--t-base);
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* An ambient field: a faint dot lattice that anchors the product surface */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(circle at 1px 1px, var(--dot) 1px, transparent 0);
  background-size: 34px 34px;
  mask-image: radial-gradient(120% 80% at 50% 0%, #000 10%, transparent 70%);
}
body > * { position: relative; z-index: 1; }

img, svg { display: block; max-width: 100%; }
::selection { background: var(--alpha); color: var(--ink-900); }

:focus-visible {
  outline: 2px solid var(--alpha);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.skip {
  position: fixed; top: 10px; left: -9999px; z-index: 400;
  background: var(--alpha); color: var(--ink-900);
  padding: 10px 18px; border-radius: var(--r-full);
  font-weight: 600; font-size: var(--t-sm);
}
.skip:focus { left: 10px; }

/* 02 — Type =============================================================== */

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 0;
  color: var(--fg-hi);
  /* `pretty` avoids orphans without the aggressive narrowing `balance`
     applies to long headings; `balance` is reserved for short display type. */
  text-wrap: pretty;
}
.t-hero, .t-xl { text-wrap: balance; }

.t-hero { font-size: var(--t-hero); letter-spacing: -0.045em; line-height: 0.94; }
.t-xl { font-size: var(--t-xl); letter-spacing: -0.038em; }
.t-lg { font-size: var(--t-lg); letter-spacing: -0.03em; }
.t-md { font-size: var(--t-md); letter-spacing: -0.02em; line-height: 1.25; }

.lede {
  font-size: clamp(1rem, 1.35vw, 1.25rem);
  line-height: 1.6;
  color: var(--fg-2);
  max-width: 58ch;
  margin: 0;
  font-weight: 400;
}

.eyebrow {
  display: inline-flex; align-items: center; gap: var(--s2);
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--alpha);
  margin: 0;
}
.eyebrow--dim { color: var(--fg-3); }

.mono { font-family: var(--mono); font-variant-ligatures: none; }
.label {
  font-family: var(--mono); font-size: var(--t-xs);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-3);
}
.muted { color: var(--fg-3); }
.dim { color: var(--fg-2); }
.small { font-size: var(--t-sm); color: var(--fg-2); line-height: 1.6; }
.fine { font-size: var(--t-sm); color: var(--fg-3); line-height: 1.65; max-width: 76ch; }
.nowrap { white-space: nowrap; }
.vh { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }
a { color: inherit; text-decoration: none; }

.ico { flex: none; }

/* 03 — Layout ============================================================= */

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad); }

.sec { padding-block: var(--s8); }
.sec--sm { padding-block: var(--s7); }
.sec--lg { padding-block: var(--s9); }
.sec--raise { background: linear-gradient(180deg, var(--ink-850), var(--ink-900)); border-top: 1px solid var(--line); }

.grid { display: grid; gap: var(--s5); }
.g2 { grid-template-columns: 1fr; }
.g3 { grid-template-columns: 1fr; }
.g-split { grid-template-columns: 1fr; gap: var(--s6); }
.g-side { grid-template-columns: 1fr; gap: var(--s6); }
@media (min-width: 720px) { .g2 { grid-template-columns: 1fr 1fr; } .g3 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1040px) {
  .g3 { grid-template-columns: repeat(3, 1fr); }
  .g-split { grid-template-columns: 1.15fr 1fr; gap: var(--s7); }
  .g-side { grid-template-columns: minmax(0,1fr) 340px; gap: var(--s7); }
}
.grid > * { min-width: 0; }

.stack > * + * { margin-top: var(--s4); }
.stack-5 > * + * { margin-top: var(--s5); }
.stack-6 > * + * { margin-top: var(--s6); }

.row { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; }
.row--between { justify-content: space-between; }
.mt2{margin-top:var(--s2)}.mt3{margin-top:var(--s3)}.mt4{margin-top:var(--s4)}
.mt5{margin-top:var(--s5)}.mt6{margin-top:var(--s6)}.mt7{margin-top:var(--s7)}
.mb4{margin-bottom:var(--s4)}.mb5{margin-bottom:var(--s5)}.mb6{margin-bottom:var(--s6)}

/* Homepage console: the statement and the world share the first screen.
   Below 1100px the world drops beneath the statement rather than shrinking
   into an unreadable strip. */
.home { display: grid; gap: var(--s6); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 1100px) {
  .home { grid-template-columns: minmax(340px, 0.82fr) minmax(0, 1.18fr); gap: var(--s7); }
}
.home__say { max-width: 46ch; }

/* Section header: eyebrow + title + action, never a card */
.shead { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s5); margin-bottom: var(--s6); flex-wrap: wrap; }
.shead__t { max-width: 70ch; flex: 1 1 34ch; }
.shead h2 { margin-top: var(--s3); }
/* Centred variant for the marketing-rhythm sections. Widths are set in rem,
   not ch: `ch` here resolves against the body font, not the display face, and
   silently squeezes a large centred heading into a column. */
.shead--center { justify-content: center; text-align: center; margin-bottom: var(--s7); }
.shead--center .shead__t { max-width: 46rem; margin-inline: auto; flex: 0 1 auto; }
.shead--center .shead__t h2 { text-wrap: balance; }
.shead--center .eyebrow { justify-content: center; }
.shead--center .fine { max-width: 40rem; margin-inline: auto; }

/* 04 — App chrome ========================================================= */

.bar {
  position: sticky; top: 0; z-index: 60;
  background: var(--bar-bg);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.bar__in { display: flex; align-items: center; gap: var(--s4); height: var(--bar); }

.brand { display: inline-flex; align-items: center; gap: 10px; font-family: var(--display); font-weight: 600; letter-spacing: -0.02em; color: var(--fg-hi); font-size: 1.0625rem; }
.brand__dot { width: 9px; height: 9px; background: var(--alpha); transform: rotate(45deg); border-radius: 1px; flex: none; box-shadow: 0 0 14px var(--alpha-line); }


/* FIBCOS logo sizing */
.brand--logo {
  gap: 0;
  flex: none;
}

.brand--logo img {
  display: block;
  width: 62px;
  height: 15px;
  object-fit: contain;
  object-position: left center;
}

.foot__brand img {
  width: 75px;
  height: 19px;
}

@media (max-width: 760px) {
  .brand--logo img {
    width: 54px;
    height: 14px;
  }

  .foot__brand img {
    width: 70px;
    height: 18px;
  }
}

/* Context switcher — always shows where you are in the hierarchy */
.ctx {
  display: none; align-items: center; gap: var(--s2);
  height: 36px; padding: 0 6px 0 12px;
  background: var(--ink-700); border: 1px solid var(--line-2);
  border-radius: var(--r-full); color: var(--fg-2);
  font-size: var(--t-sm); font-weight: 500;
  cursor: pointer; transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
@media (min-width: 700px) { .ctx { display: inline-flex; } }
.ctx:hover { border-color: var(--line-3); color: var(--fg); background: var(--ink-600); }
.ctx[aria-expanded="true"] { border-color: var(--alpha); color: var(--fg); }
.ctx__sep { color: var(--fg-3); }
.ctx__cur { color: var(--fg-hi); }
.ctx .ico { color: var(--fg-3); }

.bar__nav { display: none; margin-left: auto; gap: 2px; }
@media (min-width: 960px) { .bar__nav { display: flex; } }
.navlink {
  padding: 7px 12px; border-radius: var(--r-full);
  font-size: var(--t-sm); font-weight: 500; color: var(--fg-2);
  transition: color .18s var(--ease), background-color .18s var(--ease);
}
.navlink:hover { color: var(--fg); background: var(--ink-700); }
.navlink[aria-current="page"] { color: var(--ink-900); background: var(--fg); }

.bar__act { display: flex; align-items: center; gap: var(--s2); margin-left: auto; }
@media (min-width: 960px) { .bar__act { margin-left: var(--s3); } }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  height: 40px; padding: 0 18px;
  border: 1px solid transparent; border-radius: var(--r-full);
  font-family: var(--ui); font-size: var(--t-sm); font-weight: 600; letter-spacing: -0.01em;
  cursor: pointer; white-space: nowrap;
  transition: transform .18s var(--spring), background-color .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
}
.btn:active { transform: scale(.97); }
.btn--primary { background: var(--alpha); color: var(--on-alpha); box-shadow: 0 6px 22px -8px var(--alpha-line); }
.btn--primary:hover { background: var(--alpha-hover); box-shadow: 0 10px 30px -8px var(--alpha-line); }
.btn--ghost { background: var(--ink-700); border-color: var(--line-2); color: var(--fg); }
.btn--ghost:hover { background: var(--ink-600); border-color: var(--line-3); }
.btn--bare { background: transparent; color: var(--fg-2); }
.btn--bare:hover { color: var(--fg); background: var(--ink-700); }
.btn--sm { height: 32px; padding: 0 12px; font-size: var(--t-xs); }
.btn--icon { width: 40px; padding: 0; }
.btn--icon.btn--sm { width: 32px; }
.btns { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* Search trigger reads as a real field, not an icon */
.searchbtn {
  display: inline-flex; align-items: center; gap: var(--s2);
  height: 36px; padding: 0 10px 0 12px;
  background: var(--ink-700); border: 1px solid var(--line-2); border-radius: var(--r-full);
  color: var(--fg-3); font-size: var(--t-sm); cursor: pointer;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.searchbtn:hover { border-color: var(--line-3); color: var(--fg-2); }
.searchbtn__t { display: none; }
@media (min-width: 560px) { .searchbtn__t { display: inline; } .searchbtn { padding-right: 6px; } }
.kbd {
  font-family: var(--mono); font-size: 10px; color: var(--fg-3);
  border: 1px solid var(--line-2); border-radius: 5px; padding: 2px 5px; line-height: 1;
}

/* Theme toggle. Both glyphs ship in the markup; CSS shows the one that
   matches the current theme, so the control is correct on first paint and
   needs no JavaScript to render the right state. */
.themebtn {
  display: grid; place-items: center; width: 36px; height: 36px; flex: none;
  background: var(--ink-700); border: 1px solid var(--line-2); border-radius: var(--r-full);
  color: var(--fg-3); cursor: pointer;
  transition: border-color .2s var(--ease), color .2s var(--ease), background-color .2s var(--ease);
}
.themebtn:hover { border-color: var(--line-3); color: var(--fg); }
.themebtn__i { display: none; grid-area: 1 / 1; }
.themebtn__i .ico { transition: transform .45s var(--spring); }
.themebtn:hover .themebtn__i .ico { transform: rotate(28deg); }
/* Dark theme shows the sun (what you would switch TO); light shows the moon. */
:root .themebtn__i--dark { display: grid; }
[data-theme="light"] .themebtn__i--dark { display: none; }
[data-theme="light"] .themebtn__i--light { display: grid; }
.sheet__link--act .themebtn__i { display: none; }
:root .sheet__link--act .themebtn__i--dark { display: inline-flex; }
[data-theme="light"] .sheet__link--act .themebtn__i--dark { display: none; }
[data-theme="light"] .sheet__link--act .themebtn__i--light { display: inline-flex; }

/* Mobile sheet nav */
.sheet {
  position: fixed; inset: 0; z-index: 120;
  background: var(--sheet-bg); backdrop-filter: blur(6px);
  display: none;
}
.sheet[data-open="true"] { display: block; }
.sheet__panel {
  position: absolute; inset: auto 0 0 0;
  background: var(--ink-800); border-top: 1px solid var(--line-2);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  padding: var(--s3) var(--pad) var(--s6);
  max-height: 88vh; overflow-y: auto;
  animation: sheet-up .3s var(--spring);
}
@keyframes sheet-up { from { transform: translateY(14%); opacity: 0; } to { transform: none; opacity: 1; } }
.sheet__grip { width: 38px; height: 4px; background: var(--line-3); border-radius: 2px; margin: 6px auto var(--s5); }
.sheet__link {
  display: flex; align-items: center; gap: var(--s3);
  padding: 13px 0; border-bottom: 1px solid var(--line);
  font-family: var(--display); font-size: 1.125rem; font-weight: 600; color: var(--fg-hi);
}
.sheet__link .ico { color: var(--alpha); }
.sheet__link span:last-child { margin-left: auto; color: var(--fg-3); }
/* Product actions sit above the destinations: the switcher and the palette
   are the two things the bar hides on small screens. */
.sheet__link--act { width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line); cursor: pointer; }
.sheet__rule { height: var(--s4); }
body[data-lock="true"] { overflow: hidden; }

/* 05 — Command palette ==================================================== */

.pal { position: fixed; inset: 0; z-index: 200; display: none; padding: 8vh var(--s4) var(--s4); }
.pal[data-open="true"] { display: block; }
.pal__scrim { position: absolute; inset: 0; background: var(--scrim-3); backdrop-filter: blur(8px); animation: fade .2s var(--ease); }
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
.pal__box {
  position: relative; max-width: 660px; margin-inline: auto;
  background: var(--ink-800); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  overflow: hidden; display: flex; flex-direction: column; max-height: 76vh;
  animation: pal-in .26s var(--spring);
}
@keyframes pal-in { from { transform: translateY(-10px) scale(.985); opacity: 0 } to { transform: none; opacity: 1 } }
.pal__field { display: flex; align-items: center; gap: var(--s3); padding: var(--s4) var(--s5); border-bottom: 1px solid var(--line); }
.pal__field .ico { color: var(--fg-3); }
.pal__field input {
  flex: 1; background: transparent; border: 0; color: var(--fg);
  font-family: var(--ui); font-size: 1.0625rem; padding: 2px 0;
}
.pal__field input::placeholder { color: var(--fg-3); }
.pal__field input:focus { outline: none; }
.pal__list { overflow-y: auto; padding: var(--s2) var(--s2) var(--s3); }
.pal__group { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); padding: var(--s4) var(--s3) var(--s2); }
.pal__item {
  display: grid; grid-template-columns: 30px minmax(0,1fr) auto; align-items: center; gap: var(--s3);
  padding: 9px var(--s3); border-radius: var(--r-sm); cursor: pointer;
}
.pal__item .ico { color: var(--fg-3); }
.pal__item[aria-selected="true"] { background: var(--ink-700); }
.pal__item[aria-selected="true"] .ico { color: var(--alpha); }
.pal__t { font-weight: 600; color: var(--fg); font-size: var(--t-base); }
.pal__c { display: block; font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); margin-top: 2px; letter-spacing: .02em; }
.pal__k { font-family: var(--mono); font-size: 10px; color: var(--fg-3); }
.pal__foot { display: flex; gap: var(--s5); padding: var(--s3) var(--s5); border-top: 1px solid var(--line); font-size: var(--t-xs); color: var(--fg-3); }
.pal__foot span { display: inline-flex; align-items: center; gap: 6px; }
.pal__empty { padding: var(--s7) var(--s5); text-align: center; color: var(--fg-3); font-size: var(--t-sm); }

/* 06 — Switcher popover & Peek panel ===================================== */

.switch {
  position: fixed; inset: 0; z-index: 150; display: none;
}
.switch[data-open="true"] { display: block; }
.switch__scrim { position: absolute; inset: 0; background: var(--scrim); }
.switch__box {
  position: absolute; top: calc(var(--bar) + 8px); left: 50%; transform: translateX(-50%);
  width: min(760px, calc(100vw - 2 * var(--s4)));
  background: var(--ink-800); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  display: grid; grid-template-columns: 1fr; overflow: hidden;
  max-height: min(70vh, 560px);
  animation: pal-in .24s var(--spring);
}
@media (min-width: 700px) { .switch__box { grid-template-columns: 220px minmax(0,1fr); } }
/* Below 700px the region list becomes a horizontal rail: ten regions in a
   scrollable strip beats a cropped vertical column on a phone. */
.switch__regions {
  display: flex; gap: var(--s2); padding: var(--s3);
  overflow-x: auto; overflow-y: hidden;
  border-bottom: 1px solid var(--line);
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.switch__regions::-webkit-scrollbar { display: none; }
@media (min-width: 700px) {
  .switch__regions {
    display: block; overflow-x: hidden; overflow-y: auto;
    border-bottom: 0; border-right: 1px solid var(--line);
  }
}
.switch__r {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  flex: none; white-space: nowrap;
  text-align: left; padding: 8px 12px; border-radius: var(--r-full);
  background: var(--ink-700); border: 1px solid var(--line); cursor: pointer;
  color: var(--fg-2); font: inherit; font-size: var(--t-sm);
}
@media (min-width: 700px) {
  .switch__r { width: 100%; border-radius: var(--r-sm); background: transparent; border-color: transparent; }
}
.switch__r:hover { background: var(--ink-700); color: var(--fg); }
.switch__r[aria-selected="true"] { background: var(--alpha-dim); color: var(--alpha); border-color: var(--alpha-line); }
.switch__r span:last-child { font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); }
.switch__markets { padding: var(--s3); overflow-y: auto; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 2px; align-content: start; }
.switch__m {
  display: flex; align-items: center; gap: var(--s2);
  padding: 8px 10px; border-radius: var(--r-sm); color: var(--fg-2); font-size: var(--t-sm);
}
.switch__m:hover { background: var(--ink-700); color: var(--fg); }
.switch__m i { width: 6px; height: 6px; border-radius: 50%; background: var(--st-pending); flex: none; }
.switch__m[data-state="active-coverage"] i { background: var(--alpha); }
.switch__m code { font-family: var(--mono); font-size: 10px; color: var(--fg-3); margin-left: auto; }

/* Peek — inspect without leaving the page */
.peek { position: fixed; inset: 0; z-index: 160; display: none; }
.peek[data-open="true"] { display: block; }
.peek__scrim { position: absolute; inset: 0; background: var(--scrim-2); backdrop-filter: blur(3px); animation: fade .2s var(--ease); }
.peek__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(440px, 100vw);
  background: var(--ink-800); border-left: 1px solid var(--line-2);
  box-shadow: var(--shadow-lg);
  display: flex; flex-direction: column;
  animation: peek-in .3s var(--spring);
}
@keyframes peek-in { from { transform: translateX(24px); opacity: .4 } to { transform: none; opacity: 1 } }
@media (max-width: 560px) {
  .peek__panel { top: auto; width: 100%; border-left: 0; border-top: 1px solid var(--line-2); border-radius: var(--r-lg) var(--r-lg) 0 0; max-height: 86vh; }
  @keyframes peek-in { from { transform: translateY(24px); opacity: .4 } to { transform: none; opacity: 1 } }
}
.peek__head { display: flex; align-items: flex-start; gap: var(--s3); padding: var(--s5); border-bottom: 1px solid var(--line); }
.peek__body { padding: var(--s5); overflow-y: auto; }
.peek__foot { margin-top: auto; padding: var(--s4) var(--s5); border-top: 1px solid var(--line); display: flex; gap: var(--s3); }

/* Loading skeleton: shows the shape of the record that is arriving rather
   than the word "Loading", so the panel does not appear to stall. */
.skel { display: grid; gap: 14px; }
.skel span {
  display: block; height: 11px; border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--ink-700) 0%, var(--ink-600) 40%, var(--ink-700) 80%);
  background-size: 300% 100%; animation: skel 1.25s var(--ease) infinite;
}
.skel span:nth-child(2n) { width: 72%; }
.skel span:nth-child(3n) { width: 88%; }
@keyframes skel { from { background-position: 120% 0 } to { background-position: -60% 0 } }

/* 07 — Controls: chips, pills, segmented, status ========================== */

.chip {
  display: inline-flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 12px;
  background: var(--ink-700); border: 1px solid var(--line);
  border-radius: var(--r-full); color: var(--fg-2);
  font-size: var(--t-xs); font-weight: 600; letter-spacing: .02em;
  cursor: pointer; white-space: nowrap;
  transition: background-color .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.chip:hover { color: var(--fg); border-color: var(--line-3); }
.chip[aria-pressed="true"], .chip.is-on { background: var(--alpha); border-color: var(--alpha); color: var(--on-alpha); }
.chips { display: flex; flex-wrap: wrap; gap: var(--s2); }

/* Market flag — one row of a single vertical sprite.

   `--f` is the row index. The vertical position is a percentage of the
   travel between the first and last cell, which makes the rule independent
   of the size it is displayed at: one background-position serves the 14px
   flag in a table row and the 30px one beside a page heading, with no second
   sprite and no per-size arithmetic.

   45 cells → the position denominator is 44, one less than the count. */
.flag {
  display: inline-block; flex: none;
  width: 20px; height: 15px;
  border-radius: 2px;
  background-image: url(../img/flags.png);
  background-repeat: no-repeat;
  background-size: 100% 4500%;
  background-position: 0 calc(var(--f, 0) * 100% / 44);
  box-shadow: inset 0 0 0 1px var(--flag-edge);
  vertical-align: -2px;
  /* Every use is "flag, then name", so the gap belongs to the flag. Layouts
     that set their own spacing clear it rather than fight it. */
  margin-right: 9px;
}
.flag--sm { width: 15px; height: 11.25px; border-radius: 1.5px; vertical-align: -1px; margin-right: 8px; }
.flag--lg { width: 38px; height: 28.5px; border-radius: 3px; vertical-align: -1px; }
.hflag > .flag, .flag--bare { margin-right: 0; }
/* Beside a display heading the flag is set on the cap height rather than the
   baseline, so it reads as part of the title block and not as punctuation. */
/* Aligned to the FIRST line, not to the block: a long market name wraps to
   two lines on a narrow screen, and a flag centred across both would float
   in the middle of the title instead of introducing it. The offset is in em,
   so it tracks the heading size at every breakpoint. */
.hflag { display: flex; align-items: flex-start; gap: 16px; }
.hflag > .flag { margin-top: .3em; }
@media (max-width: 560px) { .hflag { gap: 11px; } .flag--lg { width: 24px; height: 18px; } }

/* Status: a dot + label, sized for scanning. Never a heavy pill. */
.st {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: var(--t-xs);
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-2);
  white-space: nowrap;
}
.st::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.st--active { color: var(--st-active); }
.st--active::before { box-shadow: 0 0 0 3px var(--alpha-ring); }
.st--review { color: var(--st-review); }
.st--removed { color: var(--st-removed); }
.st--pending { color: var(--st-pending); }
.st--pending::before { background: transparent; border: 1px solid currentColor; }
/* Screening is deliberately the quietest state on the site — an outlined,
   uncoloured marker. It precedes every claim, so it must never look like one. */
.st--screen { color: var(--fg-3); }
.st--screen::before { background: transparent; border: 1px solid currentColor; opacity: .8; }
.st--paid { color: var(--warn); }
.st--paid::before { border-radius: 1px; transform: rotate(45deg); }
/* Free with registration is its own state, not a quieter kind of paid: it
   uses the informational hue rather than the accent, so a reader scanning a
   list can separate the two at a glance without reading either word. */
.st--free { color: var(--ion); }
.st--free::before { background: var(--ion); border-color: var(--ion); }
.st--public { color: var(--fg-3); }
.st--public::before { border-radius: 1px; width: 10px; height: 2px; }
.st--demo {
  color: var(--ink-900); background: var(--fg-2); border-radius: var(--r-full);
  padding: 3px 9px; letter-spacing: .12em; font-weight: 700;
}
.st--demo::before { display: none; }
.sts { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); align-items: center; }

/* Segmented control — the country page view switcher */
.seg {
  display: inline-flex; padding: 4px; gap: 2px;
  background: var(--ink-700); border: 1px solid var(--line);
  border-radius: var(--r-full); overflow-x: auto; max-width: 100%;
  scrollbar-width: none;
}
.seg::-webkit-scrollbar { display: none; }
.seg__b {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border: 0; background: transparent; cursor: pointer;
  border-radius: var(--r-full); color: var(--fg-2);
  font: inherit; font-size: var(--t-sm); font-weight: 600; white-space: nowrap;
  transition: color .18s var(--ease), background-color .18s var(--ease);
}
.seg__b .ico { opacity: .7; }
.seg__b:hover { color: var(--fg); }
.seg__b[aria-selected="true"] { background: var(--fg); color: var(--ink-900); }
.seg__b[aria-selected="true"] .ico { opacity: 1; }
.segbar { position: sticky; top: var(--bar); z-index: 40; padding-block: var(--s3); background: linear-gradient(180deg, var(--ink-900) 70%, transparent); }

/* Feature tiles — soft raised surfaces with an icon chip. */
.tiles { display: grid; gap: var(--s5); grid-template-columns: 1fr; }
@media (min-width: 700px) { .tiles--2, .tiles--4 { grid-template-columns: repeat(2, 1fr); } .tiles--3 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1040px) {
  .tiles--3 { grid-template-columns: repeat(3, 1fr); }
  .tiles--4 { grid-template-columns: repeat(4, 1fr); }
}
.tile {
  display: flex; flex-direction: column; padding: var(--s6);
  background: var(--ink-800); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-soft);
  transition: transform .3s var(--settle), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.tile__i {
  display: grid; place-items: center; width: 46px; height: 46px;
  border-radius: var(--r); background: var(--alpha-dim); color: var(--alpha);
  margin-bottom: var(--s5);
}
.tile__h { font-size: var(--t-md); margin: 0 0 var(--s3); }
.tile__b { font-size: var(--t-sm); color: var(--fg-2); margin: 0; line-height: 1.65; }
.tile__m { display: block; margin-top: var(--s4); }
/* Pinned to the bottom so a row of tiles aligns on its calls to action
   however unequal the copy above them is. */
.tile__go {
  display: inline-flex; align-items: center; gap: 7px; margin-top: auto; padding-top: var(--s5);
  align-self: flex-start;
  font-size: var(--t-sm); font-weight: 600; color: var(--alpha);
}
.tile__go .ico { transition: transform .25s var(--spring); }
.tile--link:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--line-2); }
.tile--link:hover .tile__go .ico { transform: translateX(4px); }

/* Marquee — the markets FIBCOS covers, running continuously. */
.marquee { overflow: hidden; position: relative; padding-block: var(--s2);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee__t { display: flex; width: max-content; animation: marquee 80s linear infinite; }
.marquee:hover .marquee__t, .marquee:focus-within .marquee__t { animation-play-state: paused; }
.marquee__run { display: flex; align-items: center; gap: var(--s3); list-style: none; margin: 0; padding: 0 var(--s2); }
.marquee__i {
  display: inline-flex; align-items: center; gap: var(--s2); white-space: nowrap;
  padding: 9px 16px; border-radius: var(--r-full);
  background: var(--ink-800); border: 1px solid var(--line);
  font-size: var(--t-sm); color: var(--fg-2);
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.marquee__i:hover { border-color: var(--alpha-line); color: var(--fg); }
.marquee__i i { width: 6px; height: 6px; border-radius: 50%; background: var(--st-pending); flex: none; }
.marquee__i code { font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); }
@keyframes marquee { to { transform: translateX(-50%); } }

/* Comparison — commitments, not competitor knocking. */
.cmp { display: grid; gap: var(--s5); grid-template-columns: 1fr; }
@media (min-width: 820px) { .cmp { grid-template-columns: 1fr 1fr; } }
.cmp__c { padding: var(--s6); border-radius: var(--r-lg); border: 1px solid var(--line); background: var(--ink-800); }
.cmp__c--yes { box-shadow: var(--shadow-soft); border-color: var(--alpha-line); }
.cmp__h { display: flex; align-items: center; gap: var(--s2); margin: 0 0 var(--s5);
  font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; }
.cmp__c--yes .cmp__h { color: var(--alpha); }
.cmp__c--no .cmp__h { color: var(--fg-3); }
.cmp__l { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); }
.cmp__l li { display: grid; grid-template-columns: 18px 1fr; gap: var(--s3); align-items: start;
  font-size: var(--t-sm); color: var(--fg-2); line-height: 1.6; }
.cmp__l .ico { margin-top: 3px; }
.cmp__c--yes .cmp__l .ico { color: var(--alpha); }
.cmp__c--no .cmp__l .ico { color: var(--fg-3); }

/* Closing band */
.band {
  display: grid; gap: var(--s6); align-items: center; grid-template-columns: 1fr;
  padding: var(--s8) var(--s6); border-radius: var(--r-xl);
  background: linear-gradient(150deg, var(--ink-700), var(--ink-800) 65%);
  border: 1px solid var(--line); box-shadow: var(--shadow-soft);
}
@media (min-width: 900px) { .band { grid-template-columns: 1.4fr auto; padding-inline: var(--s8); } }
.band__t { max-width: 54ch; }
.band__a { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* Surfaces — used sparingly, never as a repeating grid of equals */
.surface {
  background: var(--ink-800);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s5);
}
.surface--flush { padding: 0; overflow: hidden; }
.surface--raise { background: linear-gradient(180deg, var(--ink-700), var(--ink-800)); }
.surface--glow { border-color: var(--alpha-line); box-shadow: 0 0 60px -30px var(--alpha); }

/* 08 — Explorer: the world as interface =================================== */

.explorer { position: relative; }
.explorer__stage {
  position: relative;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 120% at 50% 0%, var(--alpha-wash), transparent 60%),
    var(--ink-850);
  overflow: hidden;
}
.explorer__svg { width: 100%; height: auto; display: block; touch-action: none; }
/* Only claim to be draggable once the script has taken over. */
.explorer[data-live] .explorer__svg { cursor: grab; }
.explorer[data-live][data-dragging="true"] .explorer__svg { cursor: grabbing; }
.explorer[data-live][data-dragging="true"] .mkt { pointer-events: none; }
[data-viewport] { transition: transform .42s var(--settle); }
.explorer[data-dragging="true"] [data-viewport] { transition: none; }
/* ------------------------------------------------------------- the world

   Country outlines sit under everything else. Their fill states coverage
   status and nothing else — a covered market is drawn in the accent, the
   rest of the world is neutral ground — which is the same rule the nodes
   follow. It is a reinforcement of the node colour and the legend, never
   the only place a state is stated, and it never encodes market data.

   The layer takes no pointer events of its own; the shapes mirror whatever
   the market nodes are doing, so hit testing has exactly one owner. */
.geo-land { pointer-events: none; }
.geo-land__rest { fill: var(--geo-land); stroke: var(--geo-edge); stroke-width: .6; }
.geo-mkt {
  fill: var(--geo-mkt); stroke: var(--geo-edge); stroke-width: .6;
  transition: fill .25s var(--ease);
}
.geo-mkt[data-state="active-coverage"] { fill: var(--geo-mkt-on); }
.geo-mkt.is-lit, .geo-mkt.is-hot, .geo-mkt.is-picked { fill: var(--geo-mkt-on); }
.geo-mkt.is-muted { fill: var(--geo-land); }
.explorer.is-filtered .geo-land__rest { opacity: .55; }

.geo-grid { stroke: var(--geo-grid); stroke-width: 1; }
.geo-grid--major { stroke: var(--geo-grid-major); }
.geo-link { stroke: var(--geo-link); stroke-width: 1; }
.geo-hub { fill: var(--geo-hub); }

/* --------------------------------------------------------- ambient motion

   The map keeps moving after it has finished arriving: a signal travels
   outward from each region hub to its markets, and every market emits a
   slow ping. Both are decoration and are identical everywhere — the same
   period, the same amplitude, on all 45 markets. Nothing here is derived
   from anything, so the moving map reports no more than the still one did:
   that the coverage exists.

   `data-motion` is written by the script only while the map is on screen
   and removed when it leaves, so nothing animates off-screen, nothing
   animates without JavaScript, and nothing animates under reduced motion.
   The still map remains the complete picture. */
.geo-pulse {
  stroke: var(--alpha); stroke-width: 1.3; stroke-linecap: round;
  stroke-dasharray: .07 .93; stroke-dashoffset: 1; opacity: 0;
}
.explorer[data-motion] .geo-pulse {
  opacity: .5;
  animation: geo-flow 5.6s linear infinite;
  animation-delay: calc(var(--i) * -113ms);
}
/* Negative delays distribute the phases immediately, so the map is already
   alive on the first frame instead of starting with a visible wave. */
.mkt__ping {
  stroke: var(--alpha); stroke-width: 1.2; fill: none; opacity: 0;
  transform-box: fill-box; transform-origin: center;
}
.explorer[data-motion] .mkt__ping {
  animation: mkt-ping 4.8s var(--ease) infinite;
  animation-delay: calc(var(--i) * -104ms);
}
@keyframes geo-flow { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes mkt-ping {
  0%   { transform: scale(.28); opacity: 0; }
  9%   { opacity: .48; }
  46%  { transform: scale(1); opacity: 0; }
  100% { transform: scale(1); opacity: 0; }
}

/* Every mark keeps its geometry in SVG attributes and is counter-scaled by
   an inner group, so a node stays the same size on screen at any zoom level.

   Deliberately not CSS `r`: a radius set only in CSS renders correctly but
   does not produce a reliable hit box, which silently breaks hover, focus
   and click on the map. Attribute geometry keeps the target real. */
.explorer { --k: 1; }
.mkt { cursor: pointer; }
.mkt__s { transition: transform .42s var(--settle); }
.explorer[data-dragging="true"] .mkt__s { transition: none; }
.mkt__halo { fill: var(--alpha); opacity: 0; transition: opacity .25s var(--ease); }
.mkt__code { pointer-events: none; }
.mkt__dot {
  fill: var(--ink-900); stroke: var(--fg-3); stroke-width: 1.4;
  transition: stroke .2s var(--ease), fill .2s var(--ease);
}
.mkt__code {
  fill: var(--fg-3); font-family: var(--mono); font-size: 8.5px; font-weight: 500;
  letter-spacing: .08em; text-anchor: middle; pointer-events: none;
  opacity: .62; transition: opacity .2s var(--ease), fill .2s var(--ease);
  paint-order: stroke; stroke: var(--ink-850); stroke-width: 3px; stroke-linejoin: round;
}
/* The market opened in the peek panel keeps a ring, so the reader never
   loses which node they are looking at. */
.mkt.is-picked .mkt__dot { fill: var(--alpha); stroke: var(--alpha); }
.mkt.is-picked .mkt__halo { opacity: .22; }
.mkt.is-picked .mkt__code { opacity: 1; fill: var(--fg-hi); }
.mkt:hover .mkt__dot, .mkt:focus-visible .mkt__dot { stroke: var(--alpha); fill: var(--alpha); }
.mkt:hover .mkt__halo, .mkt:focus-visible .mkt__halo { opacity: .18; }
.mkt:hover .mkt__code, .mkt:focus-visible .mkt__code { opacity: 1; fill: var(--fg-hi); }
.mkt[data-state="active-coverage"] .mkt__dot { fill: var(--alpha); stroke: var(--alpha); }
.mkt.is-muted { opacity: .18; }
.mkt.is-lit .mkt__dot { stroke: var(--alpha); }
.mkt.is-lit .mkt__code { opacity: 1; fill: var(--fg); }
.mkt[data-state="active-coverage"] .mkt__code { fill: var(--alpha); opacity: .85; }
.explorer.is-filtered .geo-link { opacity: .3; }
.mkt.is-muted .mkt__ping { animation: none; opacity: 0; }

.tip {
  position: absolute; z-index: 5; pointer-events: none;
  background: var(--ink-700); border: 1px solid var(--line-2);
  border-radius: var(--r); padding: 10px 13px; box-shadow: var(--shadow);
  transform: translate(-50%, -128%); opacity: 0; transition: opacity .14s var(--ease);
  min-width: 148px;
}
.tip[data-show="true"] { opacity: 1; }
/* Both lines are block-level on purpose. As inline spans the market name and
   its region ran together into one string — "EgyptAfrica · Coverage
   Developing" — and the separating margin was inert. */
.tip__h { display: flex; align-items: center; gap: 8px; }
.tip__n { display: block; font-weight: 700; font-size: var(--t-sm); line-height: 1.25; color: var(--fg-hi); }
.tip__m {
  display: block; margin-top: 5px; font-family: var(--mono); font-size: 10px;
  line-height: 1.35; color: var(--fg-3); letter-spacing: .04em; text-transform: uppercase;
}

.explorer__bar { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; justify-content: space-between; margin-bottom: var(--s5); }
.explorer__legend { display: flex; flex-wrap: wrap; gap: var(--s5); font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); letter-spacing: .1em; text-transform: uppercase; }
.explorer__legend span { display: inline-flex; align-items: center; gap: 7px; }
.explorer__legend i { width: 8px; height: 8px; border-radius: 50%; border: 1.4px solid var(--fg-3); }
.explorer__legend i.on { background: var(--alpha); border-color: var(--alpha); }

/* Zoom controls and the drag affordance. Both are enhancement-only: the
   markup ships hidden and the script reveals them once it is driving. */
.zoomer {
  position: absolute; right: var(--s4); bottom: var(--s4); z-index: 4;
  display: grid; gap: 1px; background: var(--line);
  border: 1px solid var(--line-2); border-radius: var(--r); overflow: hidden;
  box-shadow: var(--shadow);
}
.zoomer__b {
  display: grid; place-items: center; width: 36px; height: 36px;
  background: var(--ink-800); border: 0; color: var(--fg-3); cursor: pointer;
  transition: background-color .16s var(--ease), color .16s var(--ease);
}
.zoomer__b:hover { background: var(--ink-700); color: var(--fg); }
.zoomer__b:disabled { color: var(--ink-500); cursor: default; background: var(--ink-800); }
.explorer__hint {
  position: absolute; left: var(--s4); bottom: var(--s4); z-index: 4; margin: 0;
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .1em;
  text-transform: uppercase; color: var(--fg-3);
  opacity: 0; transition: opacity .3s var(--ease); pointer-events: none;
}
.explorer__stage:hover .explorer__hint { opacity: 1; }
@media (hover: none) { .explorer__hint { display: none; } }

/* A no-JS and small-screen equivalent: the market roster */
.roster { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 2px; }
.roster__i {
  display: flex; align-items: center; gap: var(--s2);
  padding: 10px 12px; border-radius: var(--r-sm);
  color: var(--fg-2); font-size: var(--t-sm);
  transition: background-color .16s var(--ease), color .16s var(--ease);
}
.roster__i:hover { background: var(--ink-700); color: var(--fg); }
.roster__i i { width: 6px; height: 6px; border-radius: 50%; background: var(--st-pending); flex: none; }
.roster__i[data-state="active-coverage"] i { background: var(--alpha); }
.roster__i code { font-family: var(--mono); font-size: 10px; color: var(--fg-3); margin-left: auto; }

/* 09 — Data surfaces ====================================================== */

/* Stat strip: figures on a single rule, not four boxes */
.stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
@media (min-width: 760px) { .stats--3 { grid-template-columns: repeat(3,1fr) } .stats--4 { grid-template-columns: repeat(4,1fr) } .stats--5 { grid-template-columns: repeat(5,1fr) } .stats--6 { grid-template-columns: repeat(6,1fr) } }
.stat { background: var(--ink-800); padding: var(--s5) var(--s4); display: flex; flex-direction: column; gap: 6px; }
.stat__k { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); }
.stat__v { font-family: var(--display); font-size: clamp(1.5rem, 2.6vw, 2rem); font-weight: 600; letter-spacing: -.03em; color: var(--fg-hi); line-height: 1; }
.stat__v--void { color: var(--stroke-off); }
.stat__v--sm { font-size: 1.0625rem; letter-spacing: -.01em; }
.stat__n { font-size: var(--t-xs); color: var(--fg-3); }

/* Meter — proportion without a chart library */
.meter { height: 6px; border-radius: var(--r-full); background: var(--ink-600); overflow: hidden; }
.meter__f { height: 100%; border-radius: var(--r-full); background: var(--alpha); }
.meter__f--void { background: repeating-linear-gradient(90deg, var(--stroke-off) 0 3px, transparent 3px 8px); width: 100% !important; }

/* Data list — replaces key/value panels */
.dl { display: grid; }
.dl__r { display: grid; grid-template-columns: 1fr; gap: 2px; padding: 11px 0; border-bottom: 1px solid var(--line); }
@media (min-width: 480px) { .dl__r { grid-template-columns: minmax(120px, 42%) minmax(0,1fr); gap: var(--s4); align-items: baseline; } }
.dl__r:last-child { border-bottom: 0; }
.dl__k { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3); }
.dl__v { font-size: var(--t-sm); color: var(--fg); }
/* A qualifier that travels with its figure. The notional base must never be
   read as capital under management, so the words that say so are part of the
   value, not a footnote somewhere else on the page. */
.dl__x { display: block; margin-top: 2px; font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--fg-3); }
.dl__v a { color: var(--alpha); }
.dl__v a:hover { text-decoration: underline; }

/* Rows — the primary list pattern. Expandable where useful. */
.rows { border-top: 1px solid var(--line); }
.rowitem { border-bottom: 1px solid var(--line); }
.rowitem__main {
  display: grid; grid-template-columns: 34px minmax(0,1fr) auto; align-items: center; gap: var(--s4);
  padding: var(--s4) var(--s3); width: 100%; text-align: left;
  background: transparent; border: 0; cursor: pointer; color: inherit; font: inherit;
  border-radius: var(--r); transition: background-color .18s var(--ease);
}
a.rowitem__main { cursor: pointer; }
.rowitem__main:hover { background: var(--ink-800); }
.rowitem__n { font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); }
.rowitem__t { font-family: var(--display); font-size: 1.0625rem; font-weight: 600; letter-spacing: -.02em; color: var(--fg-hi); }
.rowitem__s { display: block; font-size: var(--t-sm); color: var(--fg-3); margin-top: 3px; }
.rowitem__r { display: flex; align-items: center; gap: var(--s5); }
.rowitem__r .ico { color: var(--fg-3); transition: transform .22s var(--spring), color .18s var(--ease); }
.rowitem__main:hover .ico { color: var(--alpha); transform: translateX(3px); }
[aria-expanded="true"] .ico--chev { transform: rotate(180deg); color: var(--alpha); }
.rowitem__more { padding: 0 var(--s3) var(--s5) calc(34px + var(--s4)); }

/* Split row: navigate with the row, disclose with the control beside it. */
.rowitem--split { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center; }
.rowitem--split .rowitem__more { grid-column: 1 / -1; }
.rowitem__x {
  display: grid; place-items: center; width: 40px; height: 40px; margin-right: var(--s2);
  background: transparent; border: 1px solid transparent; border-radius: var(--r-sm);
  color: var(--fg-3); cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease), border-color .18s var(--ease);
}
.rowitem__x:hover { background: var(--ink-700); border-color: var(--line-2); color: var(--fg); }
.rowitem__x .ico { transition: transform .22s var(--spring), color .18s var(--ease); }

@media (max-width: 700px) {
  .rowitem__main { grid-template-columns: 28px minmax(0,1fr); }
  /* The right-hand cluster carries a status badge, a count and an arrow.
     Below the phone breakpoint it drops under the title, where it has the
     full column — but only wrapping stops it overflowing once a badge is
     long: "Free · Registration" is nearly three times the width of "Paid",
     and a single unwrapped row of those three items runs past a 320px
     viewport. */
  .rowitem__r { grid-column: 2; justify-self: start; gap: var(--s4); flex-wrap: wrap; row-gap: 6px; }
  .rowitem__more { padding-left: var(--s3); }
}

/* Table — for genuine tabular comparison only */
.tw { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--ink-800); }
table.tbl { width: 100%; border-collapse: collapse; min-width: 680px; font-size: var(--t-sm); }
table.tbl caption { text-align: left; padding: var(--s4) var(--s5) 0; font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); }
table.tbl thead th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; padding: var(--s4) var(--s4);
  background: var(--ink-700);
  font-family: var(--mono); font-size: var(--t-xs); font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3);
  white-space: nowrap; border-bottom: 1px solid var(--line);
}
table.tbl th[data-sort] { cursor: pointer; }
table.tbl th[data-sort]:hover { color: var(--fg); }
table.tbl th[aria-sort="ascending"], table.tbl th[aria-sort="descending"] { color: var(--alpha); }
table.tbl tbody td { padding: 13px var(--s4); border-bottom: 1px solid var(--line); vertical-align: middle; }
table.tbl tbody tr:last-child td { border-bottom: 0; }
table.tbl tbody tr { transition: background-color .15s var(--ease); }
table.tbl tbody tr:hover { background: var(--ink-700); }
table.tbl .num { text-align: right; font-family: var(--mono); font-size: var(--t-xs); }
table.tbl th.num { text-align: right; }
table.tbl .lead { font-weight: 700; color: var(--fg-hi); }
table.tbl .lead a:hover { color: var(--alpha); }
table.tbl .sub { display: block; font-family: var(--mono); font-size: 10px; color: var(--fg-3); margin-top: 2px; letter-spacing: .06em; }

/* 10 — Charts ============================================================= */

.plot { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--ink-800); overflow: hidden; }
.plot__h { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); justify-content: space-between; padding: var(--s4) var(--s5); border-bottom: 1px solid var(--line); }
.plot__t { font-size: var(--t-sm); font-weight: 700; color: var(--fg); }
.plot__a { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3); }
.plot__b { position: relative; padding: var(--s5); }
.plot svg { width: 100%; height: auto; overflow: visible; }
.plot__void { position: absolute; inset: var(--s5); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; pointer-events: none; }
.plot__void b { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .16em; text-transform: uppercase; color: var(--fg-2); font-weight: 500; }
.plot__void span { font-size: var(--t-xs); color: var(--fg-3); max-width: 42ch; }
.plot__k { display: flex; flex-wrap: wrap; gap: var(--s5); padding: 0 var(--s5) var(--s5); font-size: var(--t-xs); color: var(--fg-3); }
.plot__k span { display: inline-flex; align-items: center; gap: 7px; }
.plot__k i { width: 12px; height: 3px; border-radius: 2px; }

.ax { stroke: var(--line-2); stroke-width: 1; }
.axg { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 6; }
.axt { fill: var(--fg-3); font-family: var(--mono); font-size: 9px; letter-spacing: .06em; }

/* Plotted series. The benchmark is drawn thinner and dashed so the two are
   still distinguishable printed, photocopied, or by a reader who cannot
   separate the two hues — colour is never the only difference. */
.ln { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.ln--pf { stroke: var(--alpha); }
.ln--bm { stroke: var(--ion); stroke-width: 1.5; stroke-dasharray: 5 4; }
.ln--dd { stroke: var(--rose); stroke-width: 1.6; }
.ln__end { fill: var(--alpha); stroke: var(--ink-900); stroke-width: 2; }

/* Radial position gauge */
.dial__track { stroke: var(--ink-600); }
.dial__val { stroke: var(--alpha); stroke-linecap: round; transition: stroke-dashoffset 1s var(--ease); }
.dial__n { fill: var(--fg-hi); font-family: var(--display); font-weight: 600; text-anchor: middle; }
.dial__l { fill: var(--fg-3); font-family: var(--mono); font-size: 8px; letter-spacing: .12em; text-anchor: middle; }

/* 11 — The Alpha Line ===================================================== */

.aline { --n: 11px; }
.aline__t { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; position: relative; }
.aline__t::before { content: ""; position: absolute; left: 0; right: 0; top: calc(var(--n) / 2); height: 2px; border-radius: 2px; background: var(--ink-600); }
.aline__fill {
  position: absolute; left: 0; top: calc(var(--n) / 2); height: 2px; border-radius: 2px;
  background: var(--alpha); box-shadow: 0 0 16px var(--alpha-line);
  transform-origin: left center;
}
/* The line draws itself when it comes into view. The width is the real
   value from the data; only the reveal is animated, so an interrupted
   animation still leaves the correct position on screen. */
.aline[data-draw] .aline__fill { transform: scaleX(0); }
.aline[data-draw].on .aline__fill { transform: none; transition: transform 1.15s var(--settle); }
.aline[data-draw] .aline__n::before { opacity: .35; }
.aline[data-draw].on .aline__n::before {
  opacity: 1;
  transition: opacity .5s var(--ease), background-color .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
  transition-delay: calc(var(--n-i, 0) * 90ms);
}
.aline__n { position: relative; padding-top: calc(var(--n) + 16px); }
.aline__n::before {
  content: ""; position: absolute; top: 0; left: 0;
  width: var(--n); height: var(--n); border-radius: 3px;
  background: var(--ink-800); border: 2px solid var(--stroke-off);
  transform: rotate(45deg); transition: background-color .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.aline__n[data-on="1"]::before { background: var(--alpha); border-color: var(--alpha); box-shadow: 0 0 18px var(--alpha-line); }
.aline__n[data-now="1"]::before { border-color: var(--alpha); box-shadow: 0 0 0 4px var(--alpha-dim); }
.aline__s { display: block; font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3); padding-right: var(--s3); }
.aline__n[data-on="1"] .aline__s, .aline__n[data-now="1"] .aline__s { color: var(--fg); }
.aline__x { display: block; font-size: 10px; color: var(--fg-3); margin-top: 4px; }
@media (max-width: 820px) {
  .aline__t { grid-auto-flow: row; grid-auto-columns: auto; }
  .aline__t::before { left: calc(var(--n) / 2 - 1px); right: auto; top: 0; bottom: 0; width: 2px; height: auto; }
  .aline__fill { left: calc(var(--n) / 2 - 1px); top: 0; width: 2px !important; height: var(--fillh, 0%); transition: height 1.1s var(--ease); }
  .aline__n { padding: 0 0 var(--s5) calc(var(--n) + 18px); }
  .aline__n::before { top: 2px; }
}

/* Tick variant — inline position in rows and tables */
.ticks { display: inline-flex; gap: 4px; align-items: center; }
.ticks i { width: 6px; height: 6px; border-radius: 2px; transform: rotate(45deg); border: 1.5px solid var(--stroke-off); }
.ticks i[data-on="1"] { background: var(--alpha); border-color: var(--alpha); }

/* Trail — the vertical audit record */
.trail { position: relative; padding-left: 26px; }
.trail::before { content: ""; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 2px; background: var(--ink-600); border-radius: 2px; }
.trail__i { position: relative; padding-bottom: var(--s6); }
.trail__i:last-child { padding-bottom: 0; }
.trail__i::before {
  content: ""; position: absolute; left: -26px; top: 4px;
  width: 12px; height: 12px; border-radius: 3px; transform: rotate(45deg);
  background: var(--ink-800); border: 2px solid var(--stroke-off);
}
.trail__i[data-on="1"]::before { background: var(--alpha); border-color: var(--alpha); box-shadow: 0 0 16px var(--alpha-line); }
.trail__s { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--fg); }
.trail__i:not([data-on="1"]) .trail__s { color: var(--fg-3); }
.trail__d { font-family: var(--mono); font-size: var(--t-xs); color: var(--alpha); margin-top: 4px; }
.trail__i:not([data-on="1"]) .trail__d { color: var(--fg-3); }
.trail__b { font-size: var(--t-sm); color: var(--fg-2); margin-top: 7px; max-width: 62ch; line-height: 1.55; }

/* 12 — Reading & documents =============================================== */

.doc { max-width: 68ch; font-size: 1.0625rem; line-height: 1.75; color: var(--fg-2); }
.doc > :first-child { margin-top: 0; }
.doc h2 { font-size: var(--t-md); color: var(--fg-hi); margin: var(--s7) 0 var(--s4); letter-spacing: -.02em; }
.doc h3, .doc h2.sub { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--alpha); font-weight: 500; margin: var(--s6) 0 var(--s3); }
.doc p { margin: 0 0 1.05em; }
.doc strong { color: var(--fg); font-weight: 700; }
.doc ul, .doc ol { padding-left: 1.15em; margin: 0 0 1.2em; }
.doc li { margin-bottom: .55em; }
.doc li::marker { color: var(--fg-3); }
.doc a { color: var(--alpha); }
.doc a:hover { text-decoration: underline; }
.doc blockquote {
  margin: var(--s6) 0; padding: var(--s4) var(--s5);
  border-left: 2px solid var(--alpha); border-radius: 0 var(--r) var(--r) 0;
  background: var(--alpha-dim); color: var(--fg);
  font-family: var(--mono); font-size: var(--t-sm); letter-spacing: .01em;
}

.callout { display: flex; gap: var(--s4); padding: var(--s4) var(--s5); border: 1px solid var(--line); border-left: 2px solid var(--alpha); border-radius: 0 var(--r) var(--r) 0; background: var(--ink-800); }
.callout .ico { color: var(--alpha); margin-top: 2px; }
.callout__t { font-size: var(--t-sm); font-weight: 700; color: var(--fg); margin-bottom: 4px; }
.callout__b { font-size: var(--t-sm); color: var(--fg-2); margin: 0; line-height: 1.6; }
.callout--warn { border-left-color: var(--warn); }
.callout--warn .ico { color: var(--warn); }

/* Access gate */
.gate { border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--ink-800); }
.gate__blur { padding: var(--s5) var(--s5) 0; position: relative; height: 132px; overflow: hidden; }
.gate__blur i { display: block; height: 9px; border-radius: var(--r-full); background: var(--ink-600); margin-bottom: 13px; }
.gate__blur i:nth-child(3n) { width: 76% } .gate__blur i:nth-child(4n) { width: 90% }
.gate__blur::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent, var(--ink-800) 86%); }
.gate__b { padding: var(--s5); text-align: center; display: flex; flex-direction: column; align-items: center; gap: var(--s3); }

/* Contents rail */
/* The contents rail sticks — but the whole rail, not the list inside it.

   A sticky element is out of flow while stuck, so it draws over the siblings
   below it in the same column. On a long publication that is invisible,
   because those siblings have scrolled away by the time the list sticks; on
   a short one they have not, and the contents list lands on top of the
   specification beneath it. It surfaced the day the first short publication
   was added, having been latent since the page was built.

   Sticking the column instead of the list removes the failure mode rather
   than tuning around it: a sticky box cannot overlap something it contains.
   `align-self: start` stops the grid stretching the column to full height,
   which would leave the sticky box no room to travel at all. */
.toc { position: static; }
.g-side > .stack-5:has(> .toc) {
  position: sticky;
  top: calc(var(--bar) + 24px);
  align-self: start;
}
.toc__l { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--s3); }
.toc ol { list-style: none; margin: 0; padding: 0; counter-reset: t; }
.toc li { counter-increment: t; }
.toc a { display: flex; gap: var(--s3); padding: 8px 12px; border-radius: var(--r-sm); font-size: var(--t-sm); color: var(--fg-2); }
.toc a::before { content: counter(t, decimal-leading-zero); font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); }
.toc a:hover { background: var(--ink-800); color: var(--fg); }

/* 13 — Empty states ====================================================== */

.void {
  border: 1px dashed var(--line-2); border-radius: var(--r-lg);
  padding: var(--s6); background: var(--ink-850);
  display: flex; flex-direction: column; gap: var(--s3);
}
.void__i { width: 38px; height: 38px; border-radius: var(--r); display: grid; place-items: center; background: var(--ink-700); color: var(--fg-3); border: 1px solid var(--line); }
.void__t { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .16em; text-transform: uppercase; color: var(--fg); }
.void__b { font-size: var(--t-sm); color: var(--fg-3); margin: 0; max-width: 56ch; line-height: 1.6; }
.void--center { align-items: center; text-align: center; }

/* 14 — Forms & filters =================================================== */

.field { display: grid; gap: 7px; }
.field > label { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em; text-transform: uppercase; color: var(--fg-3); }
input[type=text], input[type=email], input[type=search], select, textarea {
  width: 100%; font-family: var(--ui); font-size: var(--t-sm); color: var(--fg);
  background: var(--ink-800); border: 1px solid var(--line-2); border-radius: var(--r);
  padding: 11px 14px; transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
input::placeholder, textarea::placeholder { color: var(--fg-3); }
input:hover, select:hover, textarea:hover { border-color: var(--line-3); }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--alpha); background: var(--ink-700); }
textarea { min-height: 130px; resize: vertical; }
select {
  appearance: none; padding-right: 36px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%237a8496' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
}

.filters { display: grid; gap: var(--s4); }
.filters__g { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 760px) { .filters__g { grid-template-columns: 1.4fr 1fr 1fr 1fr; } }
.filters__f { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--fg-3); }
.linkbtn { background: none; border: 0; padding: 0; cursor: pointer; font: inherit; color: var(--alpha); }
.linkbtn:hover { text-decoration: underline; }

/* Research entry */
.entry { display: grid; grid-template-columns: 1fr; gap: var(--s3); padding: var(--s5) var(--s3); border-bottom: 1px solid var(--line); border-radius: var(--r); transition: background-color .18s var(--ease); }
.entry:hover { background: var(--ink-800); }
@media (min-width: 900px) { .entry { grid-template-columns: 176px minmax(0,1fr) 156px; gap: var(--s5); align-items: start; } }
.entry__m { font-family: var(--mono); font-size: var(--t-xs); color: var(--fg-3); letter-spacing: .06em; line-height: 1.8; }
.entry__m b { display: block; color: var(--alpha); font-weight: 500; letter-spacing: .1em; text-transform: uppercase; }
.entry__t { font-size: var(--t-md); margin: 0 0 var(--s2); }
.entry__t a:hover { color: var(--alpha); }
.entry__s { font-size: var(--t-sm); color: var(--fg-2); margin: 0; line-height: 1.6; max-width: 70ch; }
.entry__r { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: flex-start; }
@media (min-width: 900px) { .entry__r { justify-content: flex-end; } }

/* Featured */
.feature { border-radius: var(--r-lg); border: 1px solid var(--line); background: linear-gradient(160deg, var(--ink-700), var(--ink-800) 60%); padding: var(--s6); }
.feature__t { font-size: clamp(1.5rem,3vw,2.25rem); margin: var(--s4) 0; }
.feature__t a:hover { color: var(--alpha); }

/* 15 — Footer, utilities, motion ========================================= */

.foot { border-top: 1px solid var(--line); background: var(--ink-850); margin-top: var(--s9); padding-block: var(--s8) var(--s6); }
.foot__top { display: grid; gap: var(--s7); grid-template-columns: 1fr; }
@media (min-width: 900px) { .foot__top { grid-template-columns: 1.2fr 2fr; } }
.foot__cols { display: grid; grid-template-columns: 1fr; gap: var(--s6) var(--s5); }
@media (min-width: 520px) { .foot__cols { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (min-width: 1040px) { .foot__cols { grid-template-columns: repeat(4, minmax(0,1fr)); } }
.foot__l { font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-3); margin-bottom: var(--s3); }
.foot__nav { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.foot__nav a { font-size: var(--t-sm); color: var(--fg-2); }
.foot__nav a:hover { color: var(--alpha); }

.foot__legal {
  margin-top: var(--s2);
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s4);
}

.foot__legal-links,
.foot__social {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--s4);
  row-gap: var(--s3);
  min-width: 0;
}

.foot__legal-links {
  font-family: var(--mono);
  font-size: var(--t-xs);
  letter-spacing: .08em;
  line-height: 1.7;
  text-transform: uppercase;
  justify-content: center;
}

.foot__legal-links a {
  color: var(--fg-3);
}

.foot__legal-links a:hover {
  color: var(--alpha);
}

.foot__social {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3) var(--s4);
  padding-top: var(--s2);
  padding-bottom: var(--s2);
  margin-top: var(--s5);
  border-top: 1px solid var(--line);
}

.foot__social a {
  color: var(--fg-2);
  font-size: var(--t-sm);
  text-decoration: none;
  transition: color .2s ease;
}

.foot__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 4px;
}

.foot__social svg {
  display: block;
  width: 20px;
  height: 20px;
  fill: currentColor;
  flex: 0 0 auto;
}

.foot__social a:hover {
  color: var(--alpha);
}

.foot__social a:focus-visible,
.foot__legal-links a:focus-visible {
  outline: 2px solid var(--alpha);
  outline-offset: 4px;
  border-radius: 2px;
}

@media (min-width: 700px) {
  .foot__legal-links,
  .foot__social {
    column-gap: var(--s5);
  }
}

.foot__d {
  font-size: var(--t-xs);
  line-height: 1.7;
  color: var(--fg-3);
  max-width: 100ch;
  margin: 0 auto;
  text-align: center;
}
/* The closing line of the site: centred, on its own, last. */
.foot__seal {
  margin: 0; padding-top: var(--s5); border-top: 1px solid var(--line);
  text-align: center;
  font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em;
  text-transform: uppercase; color: var(--fg-3);
}

/* Scroll reveal. Children of a [data-stagger] group inherit an index and
   follow each other in, so a group arrives as a group rather than as eight
   simultaneous fades. */
.rise { opacity: 0; transform: translateY(16px); }
.rise.on {
  opacity: 1; transform: none;
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  transition-delay: calc(var(--i, 0) * 60ms);
}

/* ---------------------------------------------------------------- INTRO

   The homepage assembles itself once: the graticule settles, the region
   constellations trace, the markets arrive in sequence, and the statement
   resolves line by line. It runs on first paint only, is interruptible by
   any interaction, and is switched off entirely under reduced motion.

   `data-intro` is written by the server and removed by the script the moment
   the sequence ends, so nothing here can leave the page in a stuck state:
   if the script never runs, the `no-js`-style fallback at the bottom of this
   block reveals everything immediately. */

[data-intro-scope] .lines__m { display: block; overflow: hidden; }
.lines__l { display: block; }

html[data-intro] [data-intro-scope] .lines__l {
  transform: translateY(105%);
  animation: line-in .9s var(--settle) forwards;
  animation-delay: calc(180ms + var(--i) * 90ms);
}
html[data-intro] [data-intro-scope] [data-intro-el] {
  opacity: 0;
  animation: el-in .8s var(--ease) forwards;
  animation-delay: calc(320ms + var(--i) * 110ms);
}
html[data-intro] .explorer--intro .explorer__stage { animation: stage-in .9s var(--ease) both; }
/* The world arrives first, then the coordinate grid over it. */
html[data-intro] .explorer--intro .geo-land__rest { animation: fade-in 1s var(--ease) both; }
html[data-intro] .explorer--intro .geo-mkt { animation: fade-in .7s var(--ease) .35s both; }
html[data-intro] .explorer--intro .geo-grid { animation: fade-in .8s var(--ease) .1s both; }
html[data-intro] .explorer--intro .geo-hub { animation: fade-in .6s var(--ease) .5s both; }
/* The links trace outward from each region hub. */
html[data-intro] .explorer--intro .geo-link {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: trace .9s var(--ease) .35s forwards;
}
/* Opacity on the node, radius on the mark. A CSS `transform` here would
   override the SVG positioning attribute and stack every market on the
   origin, so the pop is expressed as radius instead. */
html[data-intro] .explorer--intro .mkt {
  opacity: 0;
  animation: fade-in .5s var(--ease) forwards;
  animation-delay: calc(420ms + var(--i) * 16ms);
}
html[data-intro] .explorer--intro .mkt__s {
  animation: dot-in .62s var(--spring) both;
  animation-delay: calc(420ms + var(--i) * 16ms);
}
html[data-intro] .explorer--intro .mkt__code { animation: fade-in .5s var(--ease) both; animation-delay: calc(700ms + var(--i) * 16ms); }
html[data-intro] .explorer--intro .explorer__bar { animation: el-in .7s var(--ease) .75s both; }

@keyframes line-in  { to { transform: none; } }
@keyframes el-in    { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes trace    { to { stroke-dashoffset: 0; } }
@keyframes stage-in { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
@keyframes dot-in   { from { transform: scale(.1); } to { transform: none; } }

/* Skipping, and the reduced-motion path, land in the same place: everything
   final, nothing mid-flight. */
html[data-intro-done] [data-intro-scope] .lines__l,
html[data-intro-done] [data-intro-scope] [data-intro-el],
html[data-intro-done] .explorer--intro .mkt,
html[data-intro-done] .explorer--intro .mkt__code { animation: none !important; opacity: 1; }
html[data-intro-done] .explorer--intro .mkt__s { animation: none !important; }
html[data-intro-done] .explorer--intro .geo-link { animation: none !important; stroke-dashoffset: 0; }
/* The ambient loop waits for the arrival sequence to finish, so the two
   never run over one another. */
html[data-intro] .explorer--intro .geo-pulse,
html[data-intro] .explorer--intro .mkt__ping { animation: none !important; opacity: 0 !important; }

/* ------------------------------------------------- cross-page transitions

   Same-origin navigations cross-fade instead of flashing white, and the app
   chrome is named so it stays put rather than fading with the content — the
   shell should feel continuous because it *is* continuous. Unsupported
   browsers simply navigate normally. */
@view-transition { navigation: auto; }
.bar { view-transition-name: fibcos-bar; }
.foot { view-transition-name: fibcos-foot; }

::view-transition-old(root) { animation: vt-out .22s var(--ease) both; }
::view-transition-new(root) { animation: vt-in .34s var(--ease) both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(10px); } }

/* Theme switching cross-fades the whole surface with no movement. */
html[data-theme-switching] ::view-transition-old(root),
html[data-theme-switching] ::view-transition-new(root) { animation-duration: .3s; }
html[data-theme-switching] ::view-transition-old(root) { animation-name: fade-out; }
html[data-theme-switching] ::view-transition-new(root) { animation-name: fade-in; }
@keyframes fade-out { to { opacity: 0; } }

/* Scrollbars belong to the instrument too. */
* { scrollbar-color: var(--ink-500) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--ink-500); border-radius: var(--r-full); border: 3px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--line-3); background-clip: content-box; }

/* A hairline that only appears if a navigation is slow enough to notice. */
.navbar-progress {
  position: fixed; inset: 0 auto auto 0; height: 2px; width: 100%; z-index: 300;
  transform: scaleX(0); transform-origin: left;
  background: var(--alpha); box-shadow: 0 0 12px var(--alpha-line);
  opacity: 0; pointer-events: none;
}
.navbar-progress.on { opacity: 1; animation: nav-progress 8s var(--ease) forwards; }
@keyframes nav-progress {
  0% { transform: scaleX(0); } 40% { transform: scaleX(.7); } 100% { transform: scaleX(.96); }
}

[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-delay: 0ms !important;
    transition-duration: .001ms !important; transition-delay: 0ms !important;
  }
  .rise { opacity: 1; transform: none; }
  [data-intro-scope] .lines__l,
  [data-intro-scope] [data-intro-el],
  .explorer--intro .mkt, .explorer--intro .mkt__s { opacity: 1 !important; animation: none !important; }
  .explorer--intro .geo-link { stroke-dashoffset: 0 !important; }
  .geo-pulse, .mkt__ping { animation: none !important; opacity: 0 !important; }
  [data-viewport] { transition: none !important; }
  .marquee__t { animation: none !important; }
  .aline[data-draw] .aline__fill { transform: none !important; }
  .aline[data-draw] .aline__n::before { opacity: 1 !important; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none !important; }
}

@media print {
  body::before, .bar, .pal, .switch, .peek, .sheet, .foot, .segbar { display: none !important; }
  body { background: #fff; color: #000; }
  * { color: #000 !important; background: transparent !important; }
  [role="tabpanel"] { display: block !important; }
}

/* FIBCOS research thesis content */
.thesis-summary {
  display: grid;
  gap: var(--s5);
}

.thesis-pillar {
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}

.thesis-pillar:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

.thesis-pillar h3 {
  font-size: var(--t-md);
  line-height: 1.25;
  margin-bottom: var(--s3);
}


.thesis-pillar p {
  max-width: 76ch;
  line-height: 1.7;
  margin-top: var(--s3);
  margin-bottom: var(--s3);
}

.thesis-pillar p:last-child {
  margin-bottom: 0;
}


.thesis-pillar p + p {
  margin-top: var(--s3);
}

.thesis-item {
  line-height: 1.7;
}
/* Separate closing statement in the public thesis */
.thesis-conclusion {
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
}

.thesis-conclusion p {
  max-width: 76ch;
  line-height: 1.7;
  margin: 0;
}
/* Spacing before the public thesis conclusion */
.thesis-summary + .fine {
  margin-top: var(--s5);
}
/* FIBCOS navigation logo — compact override */
a.brand.brand--logo {
  gap: 0 !important;
  width: auto !important;
  height: auto !important;
  flex: 0 0 auto;
}

a.brand.brand--logo img {
  display: block;
  width: 180px !important;
  height: 72px !important;
  max-width: 180px !important;
  object-fit: contain;
  object-position: left center;
}

@media (max-width: 760px) {
  a.brand.brand--logo img {
    width: 130px !important;
    height: 52px !important;
    max-width: 130px !important;
  }
}
/* Tighten spacing between footer logo and tagline only */
.foot__brand {
  margin-bottom: 0 !important;
  padding-bottom: 0 !important;
  line-height: 1 !important;
}