/**
 * auralfm.xyz — the front door, brutalist.
 *
 * Built around the globe (BRAND.md §0): the page frames a real render of it and
 * reads it aloud — local times, vibes, places — rather than swapping it for a
 * feed. Everything sits in a cell of a hairline grid (the lines are the page's
 * background showing through 1px gaps). Science Gothic sets the big lines and
 * stretches from condensed to extended as they arrive; Space Mono labels and
 * data; Space Grotesk for reading. Onyx and bone, aqua for the one thing to
 * press, green only for "live".
 *
 * Fonts are served from here, not from Google: the app's whole claim is that
 * nothing sits in the middle, and a font request would put somebody there.
 */
@font-face {
  font-family: "Science Gothic"; src: url("assets/fonts/ScienceGothic-latin.woff2") format("woff2");
  font-weight: 100 900; font-stretch: 50% 200%; font-display: swap;
  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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Science Gothic"; src: url("assets/fonts/ScienceGothic-latin-ext.woff2") format("woff2");
  font-weight: 100 900; font-stretch: 50% 200%; font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Science Gothic"; src: url("assets/fonts/ScienceGothic-cyrillic.woff2") format("woff2");
  font-weight: 100 900; font-stretch: 50% 200%; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Science Gothic"; src: url("assets/fonts/ScienceGothic-cyrillic-ext.woff2") format("woff2");
  font-weight: 100 900; font-stretch: 50% 200%; font-display: swap;
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: "Space Grotesk"; src: url("assets/fonts/SpaceGrotesk-wght.woff2") format("woff2-variations");
  font-weight: 300 700; font-display: swap;
}
@font-face { font-family: "Space Mono"; src: url("assets/fonts/SpaceMono-400.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Space Mono"; src: url("assets/fonts/SpaceMono-700.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  color-scheme: dark;
  --onyx: #0C0B0B;
  --bone: #F7F4EE;
  --bone2: rgba(247, 244, 238, .72);     /* 9.2:1 on onyx */
  --line: rgba(247, 244, 238, .26);
  --aqua: #02E8CD;                       /* 12.6:1 on onyx */
  --green: #10F205;
  /* Mast red: the red of a radio mast's aviation bands, and of the posters it
     is borrowed from. Used for the argument — bands, stamps, halftones — never
     for text on onyx, where it measures 4.3:1. */
  --mast: #E5382C;
  --display: "Science Gothic", "Space Grotesk", system-ui, sans-serif;
  --mono: "Space Mono", ui-monospace, Menlo, monospace;
  --body: "Space Grotesk", system-ui, sans-serif;
  --ease: cubic-bezier(.32, .72, 0, 1);
  --pad: 24px;
  /* Fixed inks, the same in both themes: text on aqua, mast red and paper is
     always onyx; text on the globe and on photographs is always bone. */
  --ink: #0C0B0B;
  --bone-fixed: #F7F4EE;
  /* Aqua as a colour for text and rings: aqua on onyx, a deep teal on bone. */
  --aq: var(--aqua);
}

/* ── light ─────────────────────────────────────────────────────────────────
   Follows the system until someone presses the half moon in the bar (aural.js,
   remembered as auralfm.theme). The two grounds swap: --onyx is always the
   page, --bone always the words on it. Contrasts on bone: text 17:1, muted
   8.9:1, teal 5.1:1, lines 1.6:1 (decorative). */
:root[data-theme="light"] {
  color-scheme: light;
  --onyx: #FFFFFF; --bone: #0C0B0B; --bone2: rgba(12, 11, 11, .74); --line: rgba(12, 11, 11, .2);
  --aq: #00705F; --paper: #EDE6D8;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --onyx: #FFFFFF; --bone: #0C0B0B; --bone2: rgba(12, 11, 11, .74); --line: rgba(12, 11, 11, .2);
    --aq: #00705F; --paper: #EDE6D8;
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: 72px; }
body {
  margin: 0; background: var(--onyx); color: var(--bone);
  font: 400 16px/24px var(--body); -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-underline-offset: 3px; }
:focus-visible { outline: 2px solid var(--aq); outline-offset: 2px; }
/* The links invert on a tap already; iOS's grey flash on top of that read as a
   glitch. */
html { -webkit-tap-highlight-color: transparent; }
/* viewport-fit=cover lets the page run under an iPhone's notch when it is
   turned sideways, and nothing held the words back from it. */
body { padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
h1, h2, h3, p, dl, dd, figure, ol, ul { margin: 0; }
ul, ol { padding: 0; list-style: none; }
p, li, dd, figcaption { text-wrap: pretty; }
h1, h2, h3, .display, .lede, .hi { text-wrap: balance; }
.sronly { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.skip {
  position: absolute; left: 16px; top: -64px; z-index: 100;
  padding: 8px 12px; background: var(--bone); color: var(--onyx); font: 700 14px/20px var(--mono);
}
.skip:focus { top: 16px; }

/* ── the grid ─────────────────────────────────────────────────────────────── */
/* Lines are the page showing through: a 1px gap over a line-coloured ground. */
.grid, .island, .numbers, .vibe-list, .steps {
  display: grid; gap: 1px; background: var(--line);
}
.grid { border-bottom: 1px solid var(--line); }
.cell { background: var(--onyx); padding: var(--pad); min-width: 0; }
/* Headlines size to their own cell (cqi), so one long word never outruns it. */
.cell:has(> .display) { container-type: inline-size; }

.label {
  font: 400 12px/16px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--aq);
}

/* ── display type ─────────────────────────────────────────────────────────── */
.display {
  font-family: var(--display); font-weight: 900; text-transform: uppercase;
  line-height: .9; letter-spacing: -.005em; text-wrap: balance;
  font-size: clamp(32px, 6.4vw, 96px);
  font-size: clamp(32px, 11cqi, 110px);
  font-variation-settings: "wdth" 100;
}
/* Arrives condensed and stretches out to its width. */
/* Arrives a little condensed and settles — kept small: the first cut stretched
   from half width over 1.4s on every heading, and read as too much motion. */
.js .stretch { font-variation-settings: "wdth" 76; transition: font-variation-settings .9s var(--ease); }
.js .stretch.in { font-variation-settings: "wdth" 100; }
/* Fitted lines are sized by home.js to fill their cell edge to edge. */
.fit { white-space: nowrap; line-height: .82; }

/* ── ultrawide ────────────────────────────────────────────────────────────── */
/* Past 1920px the page stops growing and sits centred between two rules: on a
   3440px monitor the hero globe was 2000px tall and the words beside it tiny. */
@media (min-width: 1921px) {
  main, .foot { max-width: 1920px; margin-inline: auto; box-shadow: 1px 0 0 var(--line), -1px 0 0 var(--line); }
}

/* ── the bar ──────────────────────────────────────────────────────────────── */
.island {
  position: sticky; top: 0; z-index: 20;
  /* The brand, the live read-out, then as many small cells as the width has:
     sections, the theme, Listen, the menu. */
  grid-template-columns: auto minmax(0, 1fr); grid-auto-flow: column; grid-auto-columns: auto;
  border-bottom: 1px solid var(--line);
}
.island .cell { padding: 0 18px; min-height: 56px; display: flex; align-items: center; }
.brand { gap: 10px; text-decoration: none; }
.brand-mark { width: 26px; height: 26px; border-radius: 50%; color: var(--bone-fixed); }
.brand-word { font: 700 15px/1 var(--mono); letter-spacing: .04em; }
/* The flap re-sets this text every 42ms while it turns; contained, a turn
   re-lays out the bar and nothing else on the page. */
.livebar { contain: content; }
.livebar { gap: 10px; font: 700 14px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; overflow: hidden; }
/* The bar is a link: "04:12 in Lagos · a station there". It slides, never scrambles. */
.livelink { text-decoration: none; color: var(--bone); min-width: 0; }
.livelink:hover { background: var(--bone); color: var(--onyx); }
.lb { display: flex; align-items: baseline; gap: 10px; min-width: 0; transition: opacity .26s var(--ease), transform .26s var(--ease); }
.lb.out { opacity: 0; transform: translateY(-6px); }
/* The time always shows; a long city ("Johannesburg") trails off on a phone. */
.lb-now { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-now b { white-space: nowrap; }
.lb-now b { font-variant-numeric: tabular-nums; }
.lb-st { min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--aq); font-weight: 400; }
.lb-st::before { content: "· "; color: var(--bone2); }
.livelink:hover .lb-st { color: var(--onyx); }
.live { width: 8px; height: 8px; border-radius: 50%; background: var(--green); flex: none; box-shadow: 0 0 0 0 rgba(16, 242, 5, .5); animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(16, 242, 5, .45); } 70%, 100% { box-shadow: 0 0 0 10px rgba(16, 242, 5, 0); } }
.links { display: flex; gap: 1px; background: var(--line); }
.links .cell { font: 400 13px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; }
.links .cell:hover { background: var(--bone); color: var(--onyx); }
.go {
  gap: 8px; background: var(--aqua) !important; color: var(--ink); text-decoration: none;
  font: 700 14px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  transition: background-color .5s var(--ease);
}
.go:hover { background: #5CF2E0 !important; }
/* The theme: a half moon, dark half and light half, that turns over. */
.island .themebtn { width: 56px; justify-content: center; padding: 0; border: 0; background: var(--onyx); color: var(--bone); cursor: pointer; }
.themebtn svg { width: 20px; height: 20px; transition: transform .7s var(--ease); }
:root[data-theme="light"] .themebtn svg { transform: rotate(180deg); }
.themebtn:hover { background: var(--bone); color: var(--onyx); }
/* `.island .cell` sets display: flex, which outranked a bare `.burger` rule and
   put the phone menu button on wide screens as a stray box under the logo. */
.island .burger { display: none; }

/* The menu, on phones: a full screen of big lines. */
.menu {
  position: fixed; inset: 56px 0 0; z-index: 19; background: var(--onyx);
  padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right);
  opacity: 0; transition: opacity .5s var(--ease);
}
.menu.open { opacity: 1; }
.menu nav { display: grid; gap: 1px; background: var(--line); border-bottom: 1px solid var(--line); }
.menu a {
  background: var(--onyx); padding: 18px var(--pad); text-decoration: none;
  font: 900 34px/1 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70;
}
.menu .menu-go { background: var(--aqua); color: var(--ink); }

/* ── the split-flap ───────────────────────────────────────────────────────── */
.flap { display: inline-block; font-variant-numeric: tabular-nums; }

/* ── buttons ──────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 12px 20px; background: var(--aqua); color: var(--ink);
  font: 700 15px/20px var(--mono); letter-spacing: .06em; text-transform: uppercase; text-decoration: none;
  transition: background-color .5s var(--ease), transform .5s var(--ease);
}
.btn:hover { background: #5CF2E0; }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline-color: var(--bone); }
.textlink { font: 700 14px/20px var(--mono); color: var(--aq); }

/* ── hero ─────────────────────────────────────────────────────────────────── */
.hero { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.hero h1 { grid-column: 1 / -1; padding: 28px var(--pad) 18px; overflow: hidden; }
.globe { position: relative; padding: 0; grid-row: span 2; background: #000 url("assets/globe/stars-a.png") 0 0 / 600px 600px; overflow: hidden; isolation: isolate; }
/* Stars behind the planet: two layers, the brighter one breathing slowly. */
.globe::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: url("assets/globe/stars-b.png") 200px 120px / 600px 600px;
  animation: twinkle 7s ease-in-out infinite alternate;
}
@keyframes twinkle { from { opacity: .35; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .globe::before { animation: none; } }
.globe img { width: 100%; aspect-ratio: 1; object-fit: cover; }
/* The live globe: under the picture until it is ready, then the picture fades. */
.globe-live { position: absolute; inset: 0; }
.globe-live canvas { display: block; cursor: grab; touch-action: none; }
.globe-live canvas:active { cursor: grabbing; }
.globe img { position: relative; transition: opacity .8s var(--ease); }
.globe.is-live img { opacity: 0; pointer-events: none; }
.globe img { cursor: pointer; }
.readout { pointer-events: none; }
.globe-go {
  position: absolute; left: 50%; bottom: 52px; translate: -50% 0; z-index: 2;
  min-height: 44px; padding: 10px 18px; border: 1px solid rgba(247, 244, 238, .5);
  background: rgba(12, 11, 11, .72); color: var(--bone-fixed); cursor: pointer;
  font: 700 13px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.globe-go:hover { background: var(--bone-fixed); color: var(--ink); }
.globe.is-live .globe-go { display: none; }
.globe.loading .globe-go { pointer-events: none; display: inline-flex; align-items: center; gap: 10px; }
/* The wave: five bars rising and falling, the same sign the app uses for
   "working on it" (explore.html .wave), in this page's ink and square. */
.wave { --wave: 12px; display: inline-flex; align-items: center; gap: 2px; height: var(--wave); flex: none; }
.wave i { display: block; width: 2px; height: 100%; background: currentColor; transform: scaleY(.3); animation: wave 1.1s var(--ease) infinite; }
.wave i:nth-child(2) { animation-delay: .11s; }
.wave i:nth-child(3) { animation-delay: .22s; }
.wave i:nth-child(4) { animation-delay: .33s; }
.wave i:nth-child(5) { animation-delay: .44s; }
@keyframes wave { 0%, 100% { transform: scaleY(.3); } 50% { transform: scaleY(1); } }
/* Still, for anyone who asked: a standing wave, every bar set. Here beside the
   wave as well as in the page's reduced-motion block below, so it cannot be
   separated from it. */
@media (prefers-reduced-motion: reduce) {
  .wave i { animation: none; }
  .wave i:nth-child(1), .wave i:nth-child(5) { transform: scaleY(.45); }
  .wave i:nth-child(2), .wave i:nth-child(4) { transform: scaleY(.75); }
  .wave i:nth-child(3) { transform: none; }
}
.globe-pick {
  position: absolute; left: 14px; right: 14px; bottom: 44px; z-index: 2;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; padding: 12px 14px;
  background: rgba(12, 11, 11, .86); border: 1px solid rgba(247, 244, 238, .26); color: var(--bone-fixed);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
/* Its own display: flex outranks the hidden attribute, which left an empty
   bordered box on the globe before anything was picked. */
.globe-pick[hidden] { display: none; }
.pick-name { font: 900 22px/1 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; }
.pick-meta { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: rgba(247, 244, 238, .72); }
.pick-go { margin-left: auto; font: 700 13px/20px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--aqua); min-height: 44px; display: inline-flex; align-items: center; }
.readout span {
  position: absolute; padding: 12px 14px; font: 400 12px/14px var(--mono);
  letter-spacing: .08em; text-transform: uppercase; color: rgba(247, 244, 238, .72);
}
.readout .tl { top: 0; left: 0; } .readout .tr { top: 0; right: 0; }
.readout .bl { bottom: 0; left: 0; } .readout .br { bottom: 0; right: 0; color: var(--green); }
.intro { display: flex; flex-direction: column; gap: 20px; justify-content: center; }
.lede { font-size: 22px; line-height: 32px; }
.proof { font: 400 13px/20px var(--mono); color: var(--bone2); }
.intro .btn { align-self: flex-start; }
.numbers { grid-template-columns: repeat(4, minmax(0, 1fr)); margin: 0; align-self: end; }
/* Four across and only as tall as the figures: they were two by two and each
   cell stood a quarter of the globe high with one number in it. */
.numbers .cell { display: flex; flex-direction: column-reverse; justify-content: flex-end; gap: 6px; padding: 18px var(--pad) 20px; }
.numbers dt { font: 400 12px/16px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--bone2); }
.numbers dd { font: 900 44px/1 var(--display); font-variation-settings: "wdth" 70; font-variant-numeric: tabular-nums; }
/* Sized to its own cell as well: between tablet and laptop widths the column
   narrows and "12,579" at 44px ran past the page edge. */
.numbers .cell { container-type: inline-size; }
.numbers dd { font-size: min(36px, 24cqi); }
.hero { grid-template-rows: auto minmax(0, 1fr) auto; }
.hero .intro { align-self: stretch; }
@media (max-width: 760px) { .numbers { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ── the departures board ─────────────────────────────────────────────────── */
.board { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.board-head { display: flex; flex-direction: column; gap: 20px; justify-content: space-between; }
/* The board's own summary: how much of it is in the dark. */
.board-sum { display: flex; flex-direction: column; gap: 10px; }
.sum-big { font: 900 clamp(64px, 9cqi, 132px)/.85 var(--display); font-variation-settings: "wdth" 70; font-variant-numeric: tabular-nums; }
.sum-big span { color: var(--bone2); }
.sum-text { color: var(--bone2); max-width: 36ch; }
.sum-text b { color: var(--bone); font-weight: 600; }
.departures { border-collapse: collapse; width: 100%; padding: 0; font: 700 15px/20px var(--mono); text-transform: uppercase; letter-spacing: .06em; }
.departures th, .departures td { text-align: left; padding: 14px var(--pad); border-bottom: 1px solid var(--line); font-weight: 700; }
.departures thead th { font-weight: 400; font-size: 12px; color: var(--bone2); padding-top: 18px; padding-bottom: 10px; }
.departures tbody th { font: 900 22px/24px var(--display); font-variation-settings: "wdth" 70; letter-spacing: 0; }
.departures .clock { color: var(--aq); font-variant-numeric: tabular-nums; font-size: 20px; }
.departures tr.night .clock { color: var(--bone2); }
.departures tbody tr:last-child > * { border-bottom: 0; }
.departures td:last-child { color: var(--bone2); font-weight: 400; }

/* ── why ──────────────────────────────────────────────────────────────────── */
.why { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.why .cell:first-child { display: flex; flex-direction: column; gap: 16px; }
.why-body { display: flex; flex-direction: column; gap: 16px; font-size: 18px; line-height: 28px; color: var(--bone2); }

/* ── the tagline, word by word ───────────────────────────────────────────── */
.tagline { padding: 96px var(--pad); border-bottom: 1px solid var(--line); }
.tagline .words {
  font: 900 clamp(34px, 5.6vw, 84px)/1 var(--display); text-transform: uppercase;
  font-variation-settings: "wdth" 100; max-width: 30ch;
}
/* Each sentence its own block, balanced: a line of the tagline never holds a
   single stranded word ("STOPPED" alone on a 3440 screen). */
.tagline .line { display: block; text-wrap: balance; }
.tagline .line + .line { margin-top: .12em; }
.tagline .w { color: color-mix(in srgb, var(--bone) 20%, transparent); transition: color 1s var(--ease); }
.tagline .w.on { color: var(--bone); }

/* ── vibes ────────────────────────────────────────────────────────────────── */
.vibes { grid-template-columns: minmax(0, 1fr); }
.vibes-head { display: flex; flex-direction: column; gap: 16px; }
.vibes-head > p:not(.label) { color: var(--bone2); max-width: 52ch; }
.vibes-head > .textlink { align-self: flex-start; }
/* Seventeen vibes and the tile that closes the grid: eighteen, so six across,
   three across, or two, and never a hole. */
.vibe-list { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1080px) { .vibe-list { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.vibe { container-type: inline-size; }
.vibe-all { background: var(--aqua); color: var(--ink); }
.vibe-all > a > span:last-child { color: var(--ink); }
.vibe-n { font: 900 88px/1 var(--display) !important; letter-spacing: -.02em !important; color: var(--ink) !important; font-variation-settings: "wdth" 70; }
@media (hover: hover) { .vibe-all:hover { background: var(--bone); color: var(--onyx); } .vibe-all:hover .vibe-n, .vibe-all:hover > a > span:last-child { color: var(--onyx) !important; } }
.vibe { display: flex; flex-direction: column; justify-content: space-between; gap: 28px; min-height: 176px; transition: background-color .5s var(--ease), color .5s var(--ease); }
.vibe b {
  /* Sized to the card (cqi): "ELECTRONIC" is 7.2 times its font size wide, and
     wider still on hover, so the longest word always fits six across. */
  font: 900 clamp(16px, calc((100cqi - 48px) / 8.4), 30px)/.95 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70;
  transition: font-variation-settings .8s var(--ease);
}
.vibe span { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.vibe:hover { background: var(--bone); color: var(--onyx); }
.vibe:hover span { color: var(--onyx); }
/* Widens a little, not to 120: "ELECTRONIC" ran out of its card and was cut. */
.vibe:hover b { font-variation-settings: "wdth" 84; }
/* A card that goes somewhere: the link is the whole card. */
.vibe:has(> a) { padding: 0; }
.vibe > a { flex: 1; display: flex; flex-direction: column; justify-content: space-between; gap: 28px; padding: var(--pad); color: inherit; text-decoration: none; }
.vibe > a:focus-visible { outline-offset: -4px; }

/* ── the vibe directory ───────────────────────────────────────────────────── */
.directory { grid-template-columns: minmax(0, 1fr); }
.dir-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.dir-head h2 { margin-right: auto; }
.dir-filter { flex: 1 1 320px; max-width: 520px; }
.dir-filter input {
  width: 100%; background: transparent; color: var(--bone); border: 1px solid var(--line); border-radius: 0;
  padding: 12px 14px; font: 400 16px/24px var(--body); transition: border-color .5s var(--ease);
}
.dir-filter input::placeholder { color: color-mix(in srgb, var(--bone) 55%, transparent); }
.dir-filter input:hover { border-color: var(--bone2); }
.dir-filter input:focus-visible { outline: 2px solid var(--aq); outline-offset: -1px; border-color: var(--aq); }
.dir-count { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
/* The directory as a timetable: one place to a row, its name and count on the
   left, its stations on the right in numbered columns, hairlines between. */
.vplaces { display: block; border-top: 1px solid var(--line); background: var(--onyx); }
.vplace {
  display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: 16px 32px;
  padding: 24px var(--pad); border-bottom: 1px solid var(--line);
}
.vplace[hidden], .dir-none[hidden] { display: none; }
.vp-head { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; text-decoration: none; color: var(--bone); align-self: start; position: sticky; top: 76px; }
.vp-head b { font: 900 clamp(24px, 2.6vw, 40px)/1 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; overflow-wrap: anywhere; transition: color .5s var(--ease); }
.vp-meta { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.vp-go { margin-top: 6px; font: 700 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--aq); }
@media (hover: hover) { .vp-head:hover b { color: var(--aq); } .vp-head:hover .vp-go { text-decoration: underline; text-underline-offset: 3px; } }
/* Two columns as a grid, not CSS columns: a station that opens in place grows
   its own row, and nothing jumps from one column to the other. */
.vst { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 32px; align-items: start; counter-reset: st var(--from, 0); }
.vst li { counter-increment: st; min-width: 0; border-bottom: 1px solid color-mix(in srgb, var(--bone) 12%, transparent); }
/* A station's name: a link to it in the app, and (with script) the button that
   opens what it says about itself, as its row does in the app. */
.vst > li > a {
  display: flex; gap: 12px; align-items: baseline; width: 100%; min-height: 44px; padding: 10px 0;
  font-size: 15px; line-height: 22px; color: var(--bone); text-decoration: none; cursor: pointer;
  transition: color .3s var(--ease);
}
.vst > li > a::before { content: counter(st, decimal-leading-zero); flex: none; width: 3ch; font: 400 12px/22px var(--mono); color: var(--aq); }
.vst > li > a > span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A station a browser cannot play (an http-only stream): it says where it does. */
.vst .mac { flex: none; font: 400 12px/22px var(--mono); font-style: normal; letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.vp-go.mac { color: var(--bone2); }
.sp-links .sp-mac { display: inline-flex; align-items: center; min-height: 32px; padding: 0 12px; border: 1px dashed color-mix(in srgb, var(--bone) 40%, transparent); font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.js .vst > li > a::after { content: "+"; flex: none; width: 2ch; text-align: right; font: 400 16px/22px var(--mono); color: var(--bone2); }
.vst > li > a[aria-expanded="true"] { color: var(--aq); }
.vst > li > a[aria-expanded="true"] > span { white-space: normal; overflow-wrap: anywhere; }
.js .vst > li > a[aria-expanded="true"]::after { content: "–"; color: var(--aq); }
.vst > li > a:focus-visible { outline-offset: -2px; }
@media (hover: hover) { .vst > li > a:hover { color: var(--aq); } }
/* What the station says about itself. Indented to the names' own column. */
.sp { padding: 2px 0 18px calc(3ch + 12px); display: grid; gap: 10px; animation: sp-in .3s var(--ease) both; }
@keyframes sp-in { from { opacity: 0; transform: translateY(-4px); } }
.sp-where, .sp-none, .sp-claim { font: 400 12px/18px var(--mono); letter-spacing: .04em; color: var(--bone2); }
.sp-where { text-transform: uppercase; }
.sp-head { display: flex; gap: 12px; align-items: center; }
.sp-logo { flex: none; width: 44px; height: 44px; object-fit: cover; background: color-mix(in srgb, var(--bone) 8%, transparent); }
.sp-desc { font-size: 15px; line-height: 23px; color: var(--bone); overflow-wrap: anywhere; }
.sp-chips, .sp-links { display: flex; flex-wrap: wrap; gap: 6px 8px; }
.sp-chips span { padding: 3px 8px; border: 1px solid var(--line); font: 400 12px/16px var(--mono); letter-spacing: .04em; text-transform: uppercase; color: var(--bone2); }
.sp-links a {
  display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px; border: 1px solid var(--line);
  font: 700 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; text-decoration: none; color: var(--bone);
  transition: background-color .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.sp-links a.sp-play { background: var(--bone); color: var(--onyx); border-color: var(--bone); }
@media (hover: hover) {
  .sp-links a:hover { background: var(--bone); color: var(--onyx); border-color: var(--bone); }
  .sp-links a.sp-play:hover { background: var(--aqua); border-color: var(--aqua); color: var(--ink); }
}
.sp-claim a { color: var(--aq); }
@media (pointer: coarse) { .sp-links a { min-height: 44px; padding: 0 14px; } .sp-claim a { display: inline-block; padding: 12px 0; } }
@media (prefers-reduced-motion: reduce) { .sp { animation: none; } .vst > li > a { transition: none; } }
.vp-more { margin-top: 0; }
.vp-more[open] summary { margin-bottom: 0; }
.vp-more summary {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer; list-style: none;
  font: 700 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--aq);
}
.vp-more summary::-webkit-details-marker { display: none; }
.vp-more summary::before { content: "+"; font-size: 16px; }
.vp-more[open] summary::before { content: "–"; }
.vp-more .vst { --from: 8; }
@media (max-width: 760px) {
  .vplace { grid-template-columns: minmax(0, 1fr); gap: 12px; padding: 20px var(--pad); }
  .vp-head { position: static; }
  .vst { grid-template-columns: minmax(0, 1fr); }
}
.dir-none { color: var(--bone2); }
.vibe-others ul { display: flex; flex-wrap: wrap; gap: 1px; background: var(--line); grid-column: 1 / -1; }
.vibe-others { grid-template-columns: minmax(0, 1fr); }
.vibe-others li { flex: 1 1 180px; display: flex; }
/* Every link fills its whole cell, so a row with one two-line name has no
   grey showing under its neighbours. */
.vibe-others li > a { flex: 1; }
.vibe-others a { display: block; background: var(--onyx); padding: 16px var(--pad); text-decoration: none; font: 700 13px/18px var(--mono); letter-spacing: .06em; text-transform: uppercase; transition: background-color .5s var(--ease), color .5s var(--ease); }
.vibe-others a:hover { background: var(--bone); color: var(--onyx); }
/* A vibe in parts (Rock): the parts of the world, each with what it holds. */
.vibe-regions li { flex: 1 1 240px; }
.vibe-regions a { padding: 22px var(--pad); }
.vibe-regions a b { display: block; font: 900 clamp(20px, 2vw, 28px)/1.05 var(--display); font-variation-settings: "wdth" 70; letter-spacing: 0; margin-bottom: 8px; }
.vibe-regions a span { font: 400 12px/16px var(--mono); letter-spacing: .06em; color: var(--bone2); }
.vibe-regions a:hover span { color: var(--onyx); }

/* ── features ─────────────────────────────────────────────────────────────── */
.features { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Six cards: three across, so no row ends in an empty cell. */
.features.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.features-head { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 16px; }
.card { display: flex; flex-direction: column; gap: 12px; }
.card h3 { font: 900 22px/1.05 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; }
.card p:not(.num) { color: var(--bone2); }
.num { font: 400 12px/16px var(--mono); letter-spacing: .08em; color: var(--aq); }
.tag { margin-left: 8px; padding: 2px 6px; border: 1px solid var(--line); color: var(--bone); }
.card-wide { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: var(--pad); align-items: center; }
.card-wide > div { display: flex; flex-direction: column; gap: 12px; }

/* ── how ──────────────────────────────────────────────────────────────────── */
.how { grid-template-columns: minmax(0, 1fr); }
.how-head { display: flex; flex-direction: column; gap: 16px; }
.steps { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.steps li { display: flex; flex-direction: column; gap: 10px; }
.steps .n { font: 900 64px/1 var(--display); font-variation-settings: "wdth" 70; color: var(--aq); }
.steps h3 { font: 900 22px/1.05 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; }
.steps p { color: var(--bone2); }
.steps a { color: var(--aq); }

/* ── where it runs ────────────────────────────────────────────────────────── */
.platforms { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.platforms h2 { grid-column: 1 / -1; }
.platform { display: flex; flex-direction: column; gap: 12px; }
.platform h3 { font: 900 26px/1 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; }
.platform p:not(.label):not(.note) { color: var(--bone2); }
.beta-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; }
.beta-row .note { align-self: center; }
.note { font: 400 12px/16px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--bone2); border: 1px solid var(--line); align-self: flex-start; padding: 4px 8px; }

/* ── support ──────────────────────────────────────────────────────────────── */
.support-cta { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
.support-cta .cell:first-child { display: flex; flex-direction: column; gap: 16px; }
.support-body { display: flex; flex-direction: column; gap: 20px; justify-content: center; color: var(--bone2); font-size: 18px; line-height: 28px; }
.support-body .btn { align-self: flex-start; }

/* ── the support page ─────────────────────────────────────────────────────── */
.support-hero { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
/* The waves in red above the ask, where the column stood empty. */
.support-hero .intro { justify-content: flex-start; }
/* It fills whatever the column has above the words, edge to edge, instead of
   floating in the middle with a gap over it. */
.support-hero .intro::before {
  content: ""; display: block; flex: 1 1 140px; min-height: 140px; margin: calc(-1 * var(--pad)) calc(-1 * var(--pad)) 8px;
  background: url("assets/patterns/halftone-waves.png") 0 0 / 1600px 220px repeat-x;
  animation: htdrift 80s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .support-hero .intro::before { animation: none; } }
/* A comma's tail reached down into the hollow line under it. */
.final .display { line-height: 1; }
.rule { display: flex; flex-direction: column; gap: 16px; }
.rule p:not(.label) { color: var(--bone2); }
.tiers { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.tiers-head { grid-column: 1 / -1; display: flex; flex-direction: column; gap: 16px; }
.tier { display: flex; flex-direction: column; gap: 14px; }
.tier h3 { font: 900 clamp(22px, 2.6vw, 30px)/1 var(--display); overflow-wrap: anywhere; text-transform: uppercase; font-variation-settings: "wdth" 70; }
.price { font: 400 13px/20px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.price b { font: 900 48px/1 var(--display); font-variation-settings: "wdth" 70; color: var(--bone); margin-right: 6px; }
.tier ul { display: flex; flex-direction: column; gap: 8px; flex: 1; color: var(--bone2); }
.tier li { padding-left: 16px; position: relative; }
.tier li::before { content: "—"; position: absolute; left: 0; color: var(--aq); }
/* Not a link until the platform is live: no dead buttons. */
.btn-off { background: none; color: var(--bone2); border: 1px solid var(--line); cursor: default; align-self: flex-start; }
.btn-off:hover { background: none; }
.costs, .shop { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.shop .cell:first-child { display: flex; flex-direction: column; gap: 16px; }
.tier .btn { align-self: flex-start; }
.costs .cell:first-child { display: flex; flex-direction: column; gap: 16px; }
.costs-body { display: flex; flex-direction: column; gap: 16px; color: var(--bone2); font-size: 18px; line-height: 28px; }
.free { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.free h2 { grid-column: 1 / -1; }
.free a { color: var(--aq); }
.card h3 a { color: inherit; text-decoration: none; }
.card h3 a:hover { color: var(--aq); }
.links .cell[aria-current="page"] { background: var(--bone); color: var(--onyx); }

/* ── the journal ──────────────────────────────────────────────────────────── */
.featured { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.feature { display: flex; flex-direction: column; gap: 12px; padding: 0 0 var(--pad); }
.feature img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.feature .label, .feature h2 { padding: 0 var(--pad); }
.feature h2 { font: 900 24px/1.02 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; text-wrap: balance; }
.feature { position: relative; }
.feature h2 a { color: inherit; text-decoration: none; }
.feature h2 a::after { content: ""; position: absolute; inset: 0; }
.feature:has(h2 a):hover h2 { color: var(--aq); }
.feature:has(h2 a:focus-visible) { outline: 2px solid var(--aq); outline-offset: -2px; }
.feature h2 a:focus-visible { outline: none; }
.stories { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.stories > h2 { grid-column: 1 / -1; }
.story { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 18px; align-items: start; }
.story img, .story .duo { width: 112px; height: 112px; object-fit: cover; flex: none; }
.story .meta { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--aq); margin-bottom: 8px; }
.story h3 { font: 900 22px/1.05 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; margin-bottom: 8px; }
.story p:not(.meta) { color: var(--bone2); }
/* A story with its own page: the whole card is the link, the title says so. */
.story { position: relative; }
.story.no-image { grid-template-columns: minmax(0, 1fr); }
.story h3 a { color: inherit; text-decoration: none; }
.story h3 a::after { content: ""; position: absolute; inset: 0; }
/* A link in the summary stays its own link, above the card's. */
.story p a { position: relative; z-index: 1; }
.story:has(h3 a):hover h3, .story h3 a:focus-visible { color: var(--aq); }
.story h3 a:focus-visible { outline: none; }
.story:has(h3 a:focus-visible) { outline: 2px solid var(--aq); outline-offset: -2px; }
.aboutrow { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.aboutrow .cell { display: flex; flex-direction: column; gap: 12px; }
.aboutrow .cell p:not(.label) { color: var(--bone2); }
.figures { display: grid !important; grid-template-columns: 1fr 1fr; gap: 16px; margin: 0; }
.figures dt { font: 400 12px/14px var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--bone2); }
.figures dd { font: 900 30px/1 var(--display); font-variation-settings: "wdth" 70; }
.sidelinks { display: grid; gap: 10px; }
.steps-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.foot-links a[aria-current="page"] { color: var(--aq); }

/* ── long reading: privacy, terms, docs, the journal ──────────────────────── */
/* One column: the big word, then its introduction full width. Two columns left
   an empty cell beside the intro, the grid showing through as a grey block. */
.legal-hero { grid-template-columns: minmax(0, 1fr); }
.legal-hero .intro .lede { max-width: 60ch; }
.legal-hero h1 { font-size: clamp(56px, 12vw, 180px); }
.prose { grid-template-columns: minmax(0, 1fr); }
.prose > .cell { padding: 40px var(--pad) 64px; }
.prose .body { max-width: 72ch; }
/* Beside a Journal post, on a wide screen, the red halftone stands in the
   column the text does not use, and stays in view while you read. */
@media (min-width: 1081px) {
  .prose > .cell { display: grid; grid-template-columns: minmax(0, 72ch) minmax(0, 1fr); gap: 64px; }
  .prose > .cell::after {
    content: ""; position: sticky; top: 96px; align-self: start; justify-self: end;
    width: min(100%, 420px); height: min(76vh, 840px);
    background: url("assets/patterns/halftone-column.png") 50% 0 / cover no-repeat;
    -webkit-mask: linear-gradient(#000 70%, transparent); mask: linear-gradient(#000 70%, transparent);
  }
}
.prose h1 { display: none; }            /* the page's own title says it */
.prose h2 {
  font: 900 clamp(26px, 3.4vw, 40px)/1 var(--display); text-transform: uppercase;
  font-variation-settings: "wdth" 70; margin: 48px 0 16px; text-wrap: balance;
}
.prose h3 { font: 700 16px/24px var(--mono); text-transform: uppercase; letter-spacing: .04em; margin: 32px 0 8px; }
.prose p, .prose li { color: var(--bone2); font-size: 17px; line-height: 28px; }
.prose p + p, .prose p + ul, .prose ul + p, .prose p + ol, .prose ol + p, .prose table + p { margin-top: 14px; }
.prose strong { color: var(--bone); font-weight: 600; }
.prose ul, .prose ol { padding-left: 22px; margin-top: 10px; display: grid; gap: 6px; }
.prose ul { list-style: square; }
.prose ol { list-style: decimal; }
.prose li::marker { color: var(--aq); }
.prose a { color: var(--aq); }
.prose code { font: 400 14px/1 var(--mono); color: var(--bone); background: color-mix(in srgb, var(--bone) 8%, transparent); padding: 2px 5px; }
/* A block of code (the station claim file): scrolls inside its own box, never the page. */
.prose pre { max-width: 100%; overflow-x: auto; margin: 16px 0; padding: 16px; border: 1px solid var(--line); background: color-mix(in srgb, var(--bone) 4%, transparent); }
.prose pre code { background: none; padding: 0; line-height: 1.6; white-space: pre; }
.prose code { overflow-wrap: anywhere; }
.prose table { width: 100%; border-collapse: collapse; margin: 18px 0; font-size: 15px; line-height: 22px; display: block; overflow-x: auto; }
.prose th, .prose td { text-align: left; vertical-align: top; padding: 10px 12px; border: 1px solid var(--line); }
.prose th { font: 700 12px/16px var(--mono); text-transform: uppercase; letter-spacing: .06em; color: var(--bone); }
.prose td { color: var(--bone2); }
.prose blockquote { margin: 18px 0; padding: 14px 18px; border: 1px solid var(--line); }
.prose blockquote p { color: var(--bone); }
.prose hr { border: 0; height: 1px; background: var(--line); margin: 40px 0; }
.prose figure { margin: 28px 0; }
.prose figure img { width: 100%; height: auto; }
.prose figcaption { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); margin-top: 10px; }

/* ── the waitlist forms ───────────────────────────────────────────────────── */
.beta { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
/* The desktop window with the phone standing in front of it, bottom right. */
.devices { grid-template-columns: minmax(0, 1fr); margin: 0; }
.devices .cell:first-child { padding-top: 48px; padding-bottom: 48px; }
.devices img { display: block; height: auto; }
.devices .desk { width: 82%; }
.devices .phone { width: 22%; margin: -34% 2% 0 auto; position: relative; border-radius: 28px;
  border: 5px solid #1d1c1c; box-shadow: 0 24px 60px rgba(0,0,0,.6); }
.devices figcaption { font: 400 13px/20px var(--mono); color: var(--bone2); }
@media (max-width: 760px) { .devices .desk { width: 100%; } .devices .phone { width: 38%; margin-top: -22%; border-radius: 18px; border-width: 3px; } }
/* A screenshot of the app in its own window, shadow and all: shown whole, on the onyx. */
.shot { grid-template-columns: minmax(0, 1fr); margin: 0; }
.shot img { display: block; width: 100%; max-width: 1313px; height: auto; margin: 0 auto; }
.shot figcaption { font: 400 13px/20px var(--mono); color: var(--bone2); }
.beta-what { display: flex; flex-direction: column; gap: 16px; }
.beta-what ul { display: grid; gap: 10px; list-style: square; padding-left: 20px; color: var(--bone2); }
.beta-what li::marker { color: var(--aq); }
/* The cell fills its column; only what is in it is held to a readable width —
   capping the cell itself left the rest of the row showing as a grey block. */
.wait-form { display: flex; flex-direction: column; gap: 22px; }
.wait-form > * { max-width: 640px; width: 100%; }
.wait-form > .btn { width: auto; }
.wait-form .field { display: flex; flex-direction: column; gap: 8px; border: 0; margin: 0; padding: 0; min-width: 0; }
.wait-form label, .wait-form legend { font: 700 13px/18px var(--mono); letter-spacing: .06em; text-transform: uppercase; }
.wait-form legend { padding: 0; margin-bottom: 8px; }
.wait-form .opt { color: var(--bone2); font-weight: 400; margin-left: 6px; }
.wait-form .field-hint { color: var(--bone2); font-size: 13px; line-height: 18px; margin-top: 6px; }
.wait-form input[type=email], .wait-form input[type=text], .wait-form input[type=url], .wait-form textarea {
  width: 100%; background: transparent; color: var(--bone); border: 1px solid var(--line); border-radius: 0;
  padding: 12px 14px; font: 400 16px/24px var(--body); transition: border-color .5s var(--ease);
}
.wait-form textarea { resize: vertical; min-height: 96px; }
.wait-form input::placeholder, .wait-form textarea::placeholder { color: color-mix(in srgb, var(--bone) 55%, transparent); }
.wait-form input:hover, .wait-form textarea:hover { border-color: var(--bone2); }
.wait-form input:focus-visible, .wait-form textarea:focus-visible { outline: 2px solid var(--aq); outline-offset: -1px; border-color: var(--aq); }
.wait-form input[aria-invalid=true] { border-color: #FF8A7A; }
.wait-form .choice { display: flex; align-items: center; gap: 12px; min-height: 44px; font: 400 16px/24px var(--body); text-transform: none; letter-spacing: 0; cursor: pointer; }
.wait-form .choice input { width: 20px; height: 20px; margin: 0; accent-color: var(--aq); }
.wait-form .choice.age { margin-top: 8px; }
.wait-form .btn { align-self: flex-start; border: 0; cursor: pointer; }
.wait-form .btn[disabled] { opacity: .6; cursor: progress; }
.field-error { color: #FF8A7A; font: 400 14px/20px var(--body); }
.field-error[hidden], .form-status:empty { display: none; }
.form-status { font: 400 16px/24px var(--body); padding: 14px 16px; border: 1px solid var(--line); }
.form-status.ok { border-color: var(--aq); color: var(--bone); }
.form-status.bad { border-color: #FF8A7A; }
/* Clipped to nothing, not display:none: some bots skip fields they can tell are hidden.
   Not pushed off-screen either, which a layout audit reads as overflow. */
.hp { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.wait-form.sent .field, .wait-form.sent .btn { display: none; }

/* ── a Journal post ───────────────────────────────────────────────────────── */
.post-hero { grid-template-columns: minmax(0, 1fr); }
.post-hero .cell { display: flex; flex-direction: column; gap: 18px; padding-top: 40px; padding-bottom: 32px; }
.post-hero h1 { grid-column: auto; padding: 0; max-width: 18ch; font-size: clamp(36px, 8cqi, 104px); }
.post-hero .meta { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.post-image .cell { padding: 0; background: #000; }
.post-image img { width: 100%; height: auto; max-height: 72vh; object-fit: cover; }
.post .prose p:first-child { font-size: 21px; line-height: 32px; color: var(--bone); }
.post-nav { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.post-nav a { display: flex; flex-direction: column; gap: 8px; text-decoration: none; color: var(--bone);
  font: 900 20px/1.05 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; }
.post-nav a:hover span:last-child { color: var(--aq); }
.post-nav a:nth-child(3) { text-align: right; }

/* ── questions ────────────────────────────────────────────────────────────── */
.faq { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
/* Its own cell, so it cannot size to it (cqi): set to fit the 5fr column. */
.faq h2 { font-size: clamp(32px, 4.4vw, 72px); }
.qa { padding: 0; }
.qa details { border-bottom: 1px solid var(--line); }
.qa details:last-child { border-bottom: 0; }
.qa summary {
  cursor: pointer; list-style: none; padding: 18px var(--pad); min-height: 56px;
  font: 700 16px/22px var(--mono); text-transform: uppercase; letter-spacing: .04em;
  display: flex; justify-content: space-between; gap: 16px;
}
.qa summary::-webkit-details-marker { display: none; }
.qa summary::after { content: "+"; color: var(--aq); flex: none; }
.qa details[open] summary::after { content: "−"; }
.qa details p { padding: 0 var(--pad) 20px; color: var(--bone2); max-width: 62ch; }
.qa a { color: var(--aq); }

/* ── final ────────────────────────────────────────────────────────────────── */
.final { grid-template-columns: minmax(0, 1fr); }
.final h2 { padding: 48px var(--pad) 32px; font-size: clamp(44px, 8.4vw, 150px); max-width: 16ch; }
.final-go { display: flex; justify-content: flex-start; }

/* ── footer ───────────────────────────────────────────────────────────────── */
/* Four lists under four words: where to listen, what to read, the project, the
   small print. Written into every page by scripts/build-footer.mjs. The widths
   are on the grid and the type, never on a cell, so no grey shows beside one. */
.foot { grid-template-columns: minmax(0, 3fr) repeat(4, minmax(0, 2fr)); }
.foot .cell { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.foot .brand { display: inline-flex; align-items: center; min-height: 44px; }
.foot-note { font: 400 13px/20px var(--mono); color: var(--bone2); max-width: 30ch; }
.foot-links { list-style: none; margin: 0; padding: 0; }
.foot-links a { display: inline-block; font: 400 13px/44px var(--mono); letter-spacing: .08em; text-transform: uppercase; text-decoration: none; padding: 0 6px; margin-left: -6px; }
/* Only where there is a pointer: on a phone the highlight stayed on after a tap. */
@media (hover: hover) { .foot-links a:hover { background: var(--bone); color: var(--onyx); } }
.foot .foot-end { grid-column: 1 / -1; flex-direction: row; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 0 24px; font: 400 12px/18px var(--mono); color: var(--bone2); }
.foot-end a { color: inherit; line-height: 44px; }
@media (max-width: 1100px) {
  .foot { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .foot-brand { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .foot { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ── tablets and phones ───────────────────────────────────────────────────── */
@media (max-width: 1080px) {
  .links { display: none; }
  .island .burger { display: flex; position: relative; width: 56px; justify-content: center; cursor: pointer; border: 0; color: var(--bone); }
  .burger span { position: absolute; left: 18px; right: 18px; height: 2px; background: currentColor; transition: transform .5s var(--ease), top .5s var(--ease); }
  .burger span:first-child { top: 23px; } .burger span:last-child { top: 31px; }
  .island[data-open="true"] .burger span:first-child { top: 27px; transform: rotate(45deg); }
  .island[data-open="true"] .burger span:last-child { top: 27px; transform: rotate(-45deg); }
  .vibe-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .aboutrow, .steps-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The departures table ran 40px off a 768 screen beside its heading. */
  .board { grid-template-columns: minmax(0, 1fr); }
  .features.three { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  :root { --pad: 16px; }
  .island .go { display: none; }
  .island .cell { padding: 0 14px; }
  .hero, .board, .why, .support-cta, .faq, .platforms, .features, .card-wide,
  .support-hero, .tiers, .costs, .shop, .free, .legal-hero,
  .featured, .stories, .aboutrow, .beta, .features.three { grid-template-columns: minmax(0, 1fr); }
  .globe { grid-row: auto; }
  /* One word, as big as a phone allows: "JOURNAL" ran past a 390pt screen. */
  .legal-hero h1 { font-size: 12.4vw; }
  .fit { white-space: normal; font-size: clamp(40px, 14vw, 88px); line-height: .86; }
  /* Condensed, so the longest word ("UNOWNED.") still fits a phone whole. */
  .fit, .js .fit.stretch.in { font-variation-settings: "wdth" 70; }
  .steps, .steps-4 { grid-template-columns: minmax(0, 1fr); }
  .story { grid-template-columns: 80px minmax(0, 1fr); gap: 14px; }
  .story img, .story .duo { width: 80px; height: 80px; }
  .post-nav { grid-template-columns: minmax(0, 1fr); }
  .post-nav span.cell { display: none; }
  .post-nav a:nth-child(3) { text-align: left; }
  .post .prose p:first-child { font-size: 19px; line-height: 28px; }
  .lede { font-size: 19px; line-height: 28px; }
  .tagline { padding: 64px var(--pad); }
  /* Condensed on a phone: at full width "BROADCASTING." alone ran 7px past the
     screen and gave the page a sideways scroll. */
  .tagline .words { font-variation-settings: "wdth" 70; font-size: clamp(28px, 9vw, 48px); }
  /* "SOMEWHERE" alone outran a phone at the desktop minimum. */
  .final h2 { font-size: clamp(28px, 9vw, 48px); }
  .departures th, .departures td { padding: 12px var(--pad); }
  .departures td:last-child { display: none; }
  .departures thead th:last-child { display: none; }
  .vibe { min-height: 136px; }
  .vibe b { font-size: 21px; }
  .lb-st { display: none; }
}
/* The smallest phones (320pt): the ring alone carries the brand, so the live
   bar has room for a whole time and city, and the vibe names step down. */
@media (max-width: 380px) {
  .brand-word { display: none; }
  /* One long word ("SOMEWHERE") outran a 320pt cell at the 32px floor. */
  .display { font-size: clamp(26px, 11cqi, 110px); }
  .vibe b { font-size: clamp(14px, 5vw, 18px); }
}
@media (pointer: coarse) { .btn { min-height: 48px; } }

/* ══ texture (the lab's studies, live since 25 Sept 2026) ═════════════════════ */

/* 01 · Grain. A film grain over every page, drawn once as a 200px tile (Craft:
   Noise) so scrolling costs nothing. Fixed, so it does not move with the page.
   Screen, not overlay: overlay on near-black multiplies to almost nothing, and
   the grain was invisible on the onyx it was meant for. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 40; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E") 0 0 / 200px 200px repeat; opacity: .12; mix-blend-mode: screen;
}

/* On bone the grain darkens instead of lightening. */
:root[data-theme="light"] body::after { mix-blend-mode: multiply; opacity: .08; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) body::after { mix-blend-mode: multiply; opacity: .08; } }

/* 02 · The stepped frame. aural.js draws a heavy outline that steps round any
   [data-frame] block, once, when it comes into view. Wide screens only: on a
   phone the block is the whole width and the frame would only crowd it. */
[data-frame] { position: relative; }
@media (min-width: 761px) { [data-frame] { padding: 44px 48px 56px; }
  /* The frame steps in to 93% of the width below 82% of the height; text in
     that corner stops short of it instead of running under the line. */
  [data-frame] > p:last-child { max-width: min(62ch, 84%); } }
.stepframe { position: absolute; inset: 14px; width: calc(100% - 28px); height: calc(100% - 28px); pointer-events: none; overflow: visible; }
/* --len is the path's measured length (aural.js). Until the block is seen the
   whole line is offset out of view; then it slides in. No script: no --len,
   so the dash is "none" and the frame simply shows. */
.stepframe path { fill: none; stroke: var(--bone); stroke-width: 5; stroke-linecap: square; stroke-dasharray: var(--len, none); stroke-dashoffset: var(--len, 0); }
.stepframe.in path { transition: stroke-dashoffset 2.2s var(--ease); stroke-dashoffset: 0; }
@media (max-width: 760px) { .stepframe { display: none; } }

/* 03 · Diagonal bands. The page tilts where it says something it means: mast red
   for the argument, aqua for the places, a stamp for what is live. */
.bands { position: relative; overflow: hidden; padding: 72px 0; border-bottom: 1px solid var(--line); }
.band-strip {
  /* Wide enough that the tilt never shows its ends, even at 1920. */
  margin: 0 -12%; padding: 22px 64px; white-space: nowrap; overflow: hidden;
  font: 900 clamp(30px, 5vw, 84px)/.9 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70;
  color: var(--ink); background: var(--mast); transform: rotate(-3.5deg);
}
.band-strip.places { background: var(--aqua); transform: rotate(2.5deg); margin-top: -14px; }
.band-strip span { display: inline-block; animation: bandslide 60s linear infinite; }
.band-strip.places span { animation-direction: reverse; }
@keyframes bandslide { to { transform: translateX(-50%); } }
/* The on-air light: a lit box like the one over a studio door, with the time in
   a city where somebody is on the air right now (aural.js turns it over). */
.stamp {
  position: absolute; right: 6%; top: 18px; z-index: 2; transform: rotate(6deg);
  display: grid; grid-template-columns: auto auto; column-gap: 10px; align-items: center;
  padding: 10px 14px; background: var(--ink); color: var(--bone-fixed);
  border: 2px solid var(--aqua); box-shadow: 6px 6px 0 var(--aqua), 0 0 28px rgba(2, 232, 205, .3);
  font: 700 13px/1.2 var(--mono); letter-spacing: .12em; text-transform: uppercase;
}
.stamp .lamp { grid-row: span 2; width: 12px; height: 12px; border-radius: 50%; background: var(--aqua); box-shadow: 0 0 10px 2px rgba(2, 232, 205, .7); animation: lamp 2.4s ease-in-out infinite; }
@keyframes lamp { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.stamp-k { color: var(--aqua); font-size: 12px; }
.stamp-v { font-variant-numeric: tabular-nums; }
/* The radio waves behind the bands: Melton's drawing, one image across the
   whole section, still, a whisper of the ink. Only the words move here. */
.bands::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: var(--bone); opacity: .08;
  -webkit-mask: url("assets/patterns/waves-a.png") 50% 50% / cover no-repeat;
  mask: url("assets/patterns/waves-a.png") 50% 50% / cover no-repeat;
}
.bands { isolation: isolate; }
@media (prefers-reduced-motion: reduce) { .stamp .lamp { animation: none; } }
@media (max-width: 760px) { .bands { padding: 64px 0 56px; } .stamp { right: 16px; top: 10px; font-size: 12px; } }

/* 04 · Outline type: filled and hollow words in one headline. */
.hollow { color: transparent; -webkit-text-stroke: 2px currentColor; -webkit-text-stroke-color: var(--bone); }
.display .aq { color: var(--aq); }
@media (max-width: 760px) { .hollow { -webkit-text-stroke-width: 1.5px; } }

/* 05 · The vibe icons (scripts/vibe-art.mjs, art/vibes/): Melton's drawings,
   one line weight in one square frame, coloured by currentColor. Pointing at a
   card wipes its icon up into view again, bottom to top, the way a level meter
   rises; each vibe's own page does it once on arrival. */
.vibe-art { display: block; width: auto; height: 88px; max-width: 100%; color: var(--bone2); transition: color .5s var(--ease); }
.vibe:hover .vibe-art { color: var(--onyx); animation: iconwipe .7s var(--ease); }
.vibe a:focus-visible .vibe-art { color: var(--aq); animation: iconwipe .7s var(--ease); }
@keyframes iconwipe { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
.vibe-hero { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.vibe-hero h1 { grid-column: 1 / -1; }
.vibe-hero-art { display: flex; align-items: center; justify-content: center; padding: 40px var(--pad); }
.vibe-art.big { height: min(260px, 60vw); }
.vibe-art.big { color: var(--aq); animation: iconwipe 1.4s var(--ease) both; }

/* 06 · Halftone duotone: a photograph printed in two colours through a dot
   screen. The picture goes grey and multiplies over the ink; a dot screen
   multiplies over that. Pointing at it lets the real photograph through. */
.duo { position: relative; display: block; isolation: isolate; overflow: hidden; background: var(--aqua); }
.duo.mast { background: var(--mast); }
.duo img { filter: grayscale(1) contrast(1.35) brightness(1.05); mix-blend-mode: multiply; transition: filter .6s var(--ease); }
.duo::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .55; mix-blend-mode: multiply;
  background: radial-gradient(circle at center, rgba(12, 11, 11, .9) 0 34%, transparent 36%) 0 0 / 5px 5px;
  transition: opacity .6s var(--ease);
}
:is(a, article):hover .duo img, .duo:hover img { filter: none; mix-blend-mode: normal; }
:is(a, article):hover .duo::after, .duo:hover::after { opacity: 0; }

/* 07 · The echo wall: a mast and the rings it throws off, repeated, for section
   breaks. aural.js is not involved; it is one small SVG tile. */
.echo-wall {
  height: 180px; border-bottom: 1px solid var(--line); background-color: var(--onyx);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120' viewBox='0 0 120 120' fill='none' stroke-linecap='square'%3E%3Cg stroke='%23F7F4EE' stroke-opacity='.3' stroke-width='1.5'%3E%3Cpath d='M60 58L50 100M60 58L70 100M53 86H67M56 72H64M47 100H73'/%3E%3C/g%3E%3Cg stroke='%2302E8CD' stroke-width='1.5'%3E%3Cpath d='M50 48A14 14 0 0 1 70 48' stroke-opacity='.9'/%3E%3Cpath d='M42 40A26 26 0 0 1 78 40' stroke-opacity='.6'/%3E%3Cpath d='M34 32A38 38 0 0 1 86 32' stroke-opacity='.35'/%3E%3Cpath d='M26 24A50 50 0 0 1 94 24' stroke-opacity='.18'/%3E%3C/g%3E%3Ccircle cx='60' cy='56' r='2.5' fill='%23E5382C'/%3E%3C/svg%3E"); background-size: 120px 120px;
}

/* 08 · The pattern: Melton's terrain-from-orbit, in its own colours, the middle
   half of the drawing at two copies across a laptop screen (it is cut into
   blocks, so the join reads as one more), as a band between sections. Once a page, never behind text, never near the globe. */
.pattern-band {
  height: clamp(120px, 15vw, 240px); border-bottom: 1px solid var(--line);
  background: var(--onyx) url("assets/patterns/band.webp") 0 0 / auto 100% repeat-x;
}

@media (prefers-reduced-motion: reduce) {
  .stepframe.in path { transition: none; }
  .band-strip span, .vibe-art, .vibe:hover .vibe-art, .vibe-art.big { animation: none; }
}

/* ── still, for anyone who asked ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js .stretch, .js .stretch.in { font-variation-settings: "wdth" 100; transition: none; }
  .live { animation: none; }
  .tagline .w { transition: none; }
  .vibe, .vibe b, .btn, .go, .menu { transition: none; }
  .lb, .globe img { transition: none; }
}

/* ── 09 · The signal pass (studies, 26 Sept) ──────────────────────────────── */
/* From a constructivist brief: what it asked for that the page did not have
   yet, in the page's own type and colours. */

/* Index numbers on the sections, as a poster numbers its panels. Drawn by CSS,
   so the words stay the words; the empty alt keeps a screen reader from
   reading "zero one slash" before each one. */
.links, .menu nav { counter-reset: panel; }
.links .cell::before, .menu a:not(.menu-go)::before {
  counter-increment: panel; content: counter(panel, decimal-leading-zero) "/" / "";
  font: 400 12px/1 var(--mono); letter-spacing: .02em; color: var(--aq);
}
.links .cell::before { margin-right: 6px; translate: 0 -5px; }
.links .cell:hover::before, .links .cell[aria-current="page"]::before { color: inherit; }
.menu a:not(.menu-go)::before { display: block; margin-bottom: 8px; font-size: 12px; letter-spacing: .08em; }

/* The masthead rule: one heavy line of mast red under the bar, the only rule on
   the page thicker than a hairline. */
.island { border-bottom: 3px solid var(--mast); }
.menu { inset: 59px 0 0; }

/* A tuning dial under each clock on the board: the 24 hours, the daylight
   drawn heavier, and a red needle where the city is now. */
.departures .clock { position: relative; padding-bottom: 26px; }
.departures .clock::before, .departures .clock::after { content: ""; position: absolute; bottom: 14px; pointer-events: none; }
.departures .clock::before {
  left: var(--pad); right: var(--pad); height: 3px;
  background: linear-gradient(90deg, var(--line) 0 25%, color-mix(in srgb, var(--bone) 55%, transparent) 25% 83.34%, var(--line) 83.34%);
}
.departures .clock::after {
  left: calc(var(--pad) + (100% - 2 * var(--pad)) * var(--day, 0)); width: 2px; height: 13px; bottom: 9px;
  background: var(--mast); translate: -1px 0;
}
.departures tr:not([style]) .clock::after { display: none; }

/* Renewal terms beside every price and every subscribe button, in plain words
   (California's auto-renewal law wants them right there, not in the Terms). */
.renew { font: 400 13px/20px var(--body); color: var(--bone2); max-width: 48ch; margin-top: 8px; }

/* ── what AuralFM stands for (27 Sept) ────────────────────────────────────── */
/* Melton's line as the argument, numbered like a poster's points. After
   worldwidefm.net's plain, typographic structure; in this page's own type. */
.manifesto { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.manifesto-head { display: flex; flex-direction: column; gap: 16px; }
.manifesto .rules { display: grid; gap: 1px; background: var(--line); margin: 0; padding: 0; list-style: none; }
.manifesto .rules li { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 8px 16px; align-items: baseline; }
.manifesto .num { grid-row: span 2; font: 700 14px/1 var(--mono); letter-spacing: .08em; color: var(--aq); }
.manifesto b { font: 900 clamp(22px, 2.4vw, 34px)/1.05 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; text-wrap: balance; }
.manifesto .rules p { grid-column: 2; color: var(--bone2); max-width: 52ch; }
.support-price { font: 400 16px/24px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.support-price b { font: 900 clamp(40px, 5vw, 64px)/1 var(--display); color: var(--bone); font-variation-settings: "wdth" 70; margin-right: 8px; }
@media (max-width: 1080px) { .manifesto { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 760px) { .manifesto .rules li { grid-template-columns: 40px minmax(0, 1fr); } }

/* ── on paper: the one bone sheet ─────────────────────────────────────────────
   After the collage posters the brand keeps (Mentaleria, the Public Theater's
   redactions, the ticket and the duotone jungle): bone paper with its grain,
   a halftone Earth in onyx over a mast-red wedge,
   highlighter bars under the words, and registration marks at the corners. */
:root { --paper: #EDE6D8; --ink-soft: rgba(12, 11, 11, .72); }
:root[data-theme="light"] { --paper: #EDE6D8; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) { --paper: #EDE6D8; } }
.paper {
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
  background: var(--paper); color: var(--ink);
  border-bottom: 1px solid var(--line);
}
/* Grain: fractal noise, printed at a whisper. */
.paper::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: .35; mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .05  0 0 0 0 .04  0 0 0 0 .04  0 0 0 .55 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}
.paper .label { color: var(--ink); }
.paper-copy { padding: 64px var(--pad) 64px; display: flex; flex-direction: column; gap: 24px; container-type: inline-size; }
.paper .display { color: var(--ink); font-size: clamp(32px, 9cqi, 96px); }
/* The highlighter: each line its own red bar, as if laid down by hand. */
.hi { margin: 0; max-width: 34ch; font: 500 clamp(20px, 2.1vw, 26px)/1.5 var(--body); }
.hi span {
  background: var(--mast); color: var(--ink); padding: 2px 8px;
  -webkit-box-decoration-break: clone; box-decoration-break: clone;
}
.paper-rules { display: grid; border-bottom: 1px solid rgba(12, 11, 11, .28); }
.paper-rules li { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 12px; padding: 16px 0; border-top: 1px solid rgba(12, 11, 11, .28); font-size: 16px; line-height: 24px; color: var(--ink-soft); }
.paper-rules b { font: 700 14px/24px var(--mono); color: var(--mast); }
.paper-rules strong { color: var(--ink); font-weight: 700; }

/* The words the feed kept from you, in mast red. */
.paper .red { color: var(--mast); white-space: nowrap; }

.paper-art { position: relative; min-height: 560px; display: grid; place-items: center; padding: 40px 24px; }
.paper-art .wedge {
  position: absolute; inset: 0; background: var(--mast);
  clip-path: polygon(22% 0, 100% 0, 100% 100%, 0 100%);
}
/* The picture's own frame: square-ish, never wider than it can hold together. */
.paper-stage { position: relative; width: min(100%, 620px); aspect-ratio: 1 / 1.02; }
.paper-globe { position: absolute; left: 50%; top: 50%; translate: -50% -50%; width: 100%; aspect-ratio: 1; display: block; }
.paper-stage .log {
  position: absolute; left: 0; bottom: 0; margin: 0; max-width: 64%;
  font: 400 12px/18px var(--mono); letter-spacing: .02em; color: var(--ink);
  background: var(--paper); padding: 8px 10px; box-shadow: 4px 4px 0 var(--ink);
}
/* Label boxes pinned over pictures, here and on the hero. */
.pin {
  position: absolute; z-index: 2; margin: 0; padding: 4px 10px;
  font: 700 12px/16px var(--mono); letter-spacing: .08em; text-transform: uppercase;
  background: var(--aqua); color: var(--ink); pointer-events: none;
}
.paper-stage .pin { left: 4%; top: 2%; rotate: -4deg; background: var(--paper); color: var(--ink); box-shadow: 0 0 0 2px var(--ink), 4px 4px 0 2px var(--ink); }
.globe .pin.p1 { left: 16px; top: 44px; }
.globe .pin.p2 { right: 16px; bottom: 44px; background: var(--bone-fixed); }
/* Registration marks. */
.reg { position: absolute; width: 28px; height: 28px; pointer-events: none; }
.reg::before, .reg::after { content: ""; position: absolute; background: var(--ink); }
.reg::before { left: 13px; top: 0; width: 2px; height: 100%; }
.reg::after { top: 13px; left: 0; height: 2px; width: 100%; }
.reg.g1 { right: -8px; top: -8px; } .reg.g2 { left: 70%; bottom: -8px; }

@media (max-width: 1080px) {
  .paper { grid-template-columns: minmax(0, 1fr); }
  .paper-art { min-height: 0; padding: 32px var(--pad) 40px; }
}
@media (max-width: 760px) {
  .paper-copy { padding: 48px var(--pad) 40px; }
  .paper-stage .log { max-width: none; right: 0; font-size: 12px; line-height: 16px; }
}

/* ── keep it independent: the red sheet ──────────────────────────────────────
   After Goldsmiths' "Membership matters": the ask on the brand's loudest
   colour, onyx on mast red (4.9:1), with a halftone Earth in its corner. */
.support-cta.red .cell { background: var(--mast); color: var(--ink); }
.support-cta.red .label, .support-cta.red .support-price span { color: var(--ink); }
.support-cta.red .display, .support-cta.red .support-price b { color: var(--ink); }
.support-cta.red p { color: var(--ink); }
.support-cta.red .renew { color: rgba(12, 11, 11, .78); }
.support-cta.red .btn { background: var(--ink); color: var(--bone-fixed); }
.support-cta.red .btn:hover { background: var(--bone-fixed); color: var(--ink); }
.support-cta.red :focus-visible { outline-color: var(--ink); }
.support-cta.red .cell:first-child { position: relative; overflow: hidden; min-height: 460px; }
.support-globe { position: absolute; right: -40px; bottom: -200px; width: 380px; aspect-ratio: 1; pointer-events: none; }
.support-cta.red .display { position: relative; z-index: 1; }
@media (max-width: 760px) { .support-cta.red .cell:first-child { min-height: 340px; } .support-globe { width: 240px; right: -40px; bottom: -130px; } }

/* ── share what you hear ──────────────────────────────────────────────────── */
.card-studio { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: var(--pad); align-items: center; }
.card-studio > div { display: flex; flex-direction: column; gap: 12px; }
.studio-globe { width: 200px; aspect-ratio: 1; justify-self: center; }
@media (max-width: 760px) { .card-studio { grid-template-columns: minmax(0, 1fr); } .studio-globe { width: 160px; } }
/* The app as it is: the whole window, its own corners and shadow, uncropped,
   as the docs show theirs. */
.appshot { width: 100%; height: auto; }

/* The red halftone: Melton's radio waves through a dot screen, drifting. Where
   the topography strip was, and in the gaps a grid leaves at the end of a row. */
.halftone-band {
  --tw: 1600px; height: 220px; border-bottom: 1px solid var(--line);
  background: var(--onyx) url("assets/patterns/halftone-waves.png") 0 0 / var(--tw) 220px repeat-x;
  animation: htdrift 80s linear infinite;
}
@media (max-width: 760px) { .halftone-band { --tw: 1164px; height: 160px; background-size: var(--tw) 160px; } }
@keyframes htdrift { to { background-position-x: calc(-1 * var(--tw)); } }
@media (prefers-reduced-motion: reduce) { .halftone-band { animation: none; } }
.card-share .sharecard { width: min(100%, 360px); justify-self: center; box-shadow: 10px 10px 0 var(--mast); }

/* ── phones: long words that would outrun their cell ─────────────────────── */
.manifesto .display { font-size: clamp(30px, 9.4cqi, 104px); }

/* ── from the Journal: the featured story ────────────────────────────────────
   One story on the front page, its cover standing on a mast-red block the way
   the share card does, the title as big as a section heading, and the next
   few as a ledger beside it. The cover is shown as made: no filter. */
.journal-feature { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.jf-cover { position: relative; display: block; padding: 40px 52px 52px 40px; }
.jf-cover img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; box-shadow: 12px 12px 0 var(--mast); transition: translate .5s var(--ease), box-shadow .5s var(--ease); }
@media (hover: hover) { .jf-cover:hover img { translate: -4px -4px; box-shadow: 16px 16px 0 var(--mast); } }
.jf-cover .pin { left: 24px; top: 24px; rotate: -4deg; }
.jf-cover.jf-none { min-height: 280px; background: var(--mast); }
.jf-body { display: flex; flex-direction: column; justify-content: center; gap: 16px; container-type: inline-size; }
.jf-body .display { font-size: clamp(30px, 8cqi, 84px); }
.jf-body .display a { color: inherit; text-decoration: none; }
@media (hover: hover) { .jf-body .display a:hover { color: var(--aq); } }
.jf-body .lede { font-size: 18px; line-height: 28px; color: var(--bone2); max-width: 56ch; }
.jf-go { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; }
.jf-more { grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 9fr); gap: 16px 32px; align-items: start; }
.jf-more ol { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px 32px; }
.jf-more a { display: flex; flex-direction: column; gap: 6px; text-decoration: none; padding-top: 12px; border-top: 3px solid var(--bone); }
.jf-when { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--aq); }
.jf-more b { font: 900 20px/1.1 var(--display); text-transform: uppercase; font-variation-settings: "wdth" 70; transition: color .5s var(--ease); }
@media (hover: hover) { .jf-more a:hover b { color: var(--aq); } .jf-more a:hover { border-top-color: var(--aq); } }
@media (max-width: 1080px) { .jf-more, .jf-more ol { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 760px) {
  .journal-feature { grid-template-columns: minmax(0, 1fr); }
  .jf-cover { padding: 24px 32px 32px 16px; }
}
@media (prefers-reduced-motion: reduce) { .jf-cover img { transition: none; } }

/* ── tighter at wide sizes ────────────────────────────────────────────────
   Melton, 8 Oct 2026: "everything is so large" on a wide screen; tighten the
   text and the flow, as Linear does, and keep the look. Measured at 1680 by
   1000 the front page ran 12 screens: headings at 110px, the closing line at
   141, the argument 87 characters to a line. Here the type still shouts, a
   size down; a line stops at about 62 characters; sections sit closer. It
   comes to 10.8 screens. "Listen in." and the globe are as they were, and so
   is everything under 1280px. */
@media (min-width: 1280px) {
  .display { font-size: clamp(32px, 9cqi, 84px); }
  .manifesto .display { font-size: clamp(30px, 8cqi, 80px); }
  .faq h2 { font-size: clamp(32px, 3.6vw, 56px); }
  .final h2 { font-size: clamp(44px, 6.4vw, 112px); padding-top: 40px; padding-bottom: 28px; }
  .tagline { padding-block: 64px; }
  .tagline .words { font-size: clamp(34px, 4.2vw, 64px); }
  .bands { padding-block: 56px; }
  .band-strip { font-size: clamp(30px, 3.8vw, 64px); padding-block: 18px; }
  /* On the paragraphs, not their cell: a cell narrower than its column lets
     the grid's grey show beside it (it did, 117px of it). */
  .why-body p { max-width: 62ch; }
  .paper-copy { padding-block: 48px; }
  .devices .cell:first-child { padding-block: 32px; }
  .devices .desk { width: 56%; }
  .devices .phone { width: 15%; margin-top: -23%; }

  /* The hero in one screen. The globe was a square as wide as its column: 971px
     on a screen 1000 tall, so the page opened on a planet with its bottom cut
     off and the numbers out of sight. It is now as tall as the window leaves
     under the bar and "Listen in." (which is about 14vw tall), never under
     460px, and never wider than it was. The words get the room it gives up,
     and stop at a readable width.
     Only the hero that holds the globe: the other pages' heroes share the
     class and are one column.
  */
  .hero:has(> .globe) { grid-template-columns: min(58%, max(460px, calc(100svh - 14vw - 62px))) minmax(0, 1fr); }
  .hero:has(> .globe) .intro :is(.lede, .proof) { max-width: 52ch; }

  /* The long sections: the two pictures in "What it does" were 567 and 450px
     tall, each in a row of its own. They are 400 and 340.
     Capped by width, not height: a picture that has not loaded yet has no
     height to cap, and collapsed to nothing. */
  .card-wide .appshot { width: min(100%, 656px); justify-self: start; }
  .card-share .sharecard { width: min(100%, 272px); }

  /* Two things the pass above broke, seen in Melton's screenshots.
     The phone stood in front of the desktop window, bottom right. Shrinking
     both left it at the far edge of the page, on its own. The pair is
     centred and overlaps as it did. */
  .devices .desk { margin-left: 16.5%; }
  .devices .phone { margin: -23% 16.5% 0 auto; }
  /* The closing line's cell was 16ch wide, and a ch follows the type: at the
     smaller size it stopped short and the grid's grey showed beside it. The
     cell runs the full width and the words keep to their column. */
  .final h2 { max-width: none; padding-right: max(var(--pad), calc(100% - 17ch)); }

  /* The next longest sections. */
  .vibe > a { gap: 14px; padding-block: 18px; }
  .vibe { min-height: 0; }
  .departures th, .departures td { padding-block: 10px; }
  .departures thead th { padding-top: 14px; padding-bottom: 8px; }
  .departures .clock { padding-bottom: 22px; }
  .departures .clock::before, .departures .clock::after { bottom: 10px; }
  .journal-feature { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
  .jf-cover { padding: 28px 40px 40px 28px; }
  .paper-copy { padding-block: 40px; gap: 18px; }
}

/* A row of cards that stops short of the edge left the grid's own grey showing
   as a solid block (the roadmap: five cards in rows of three, two in a row of
   three). The rest of the row is filled with the page colour. Counted from the
   second child, because each section's heading is the first. */
@media (min-width: 1081px) {
  .features.three:has(> .card:last-child:nth-child(3n+2))::after,
  .features.three:has(> .card:last-child:nth-child(3n))::after,
  .features:not(.three):has(> .card:last-child:not(.card-wide, .card-studio):nth-child(4n+2))::after,
  .features:not(.three):has(> .card:last-child:not(.card-wide, .card-studio):nth-child(4n+3))::after,
  .features:not(.three):has(> .card:last-child:not(.card-wide, .card-studio):nth-child(4n))::after {
    content: ""; background: var(--onyx); grid-column: auto / -1;
  }
}

/* ══ the next direction (15 Oct 2026) ════════════════════════════════════════
   After the A24 and AGDA study: the boxes go, the type gets quieter and larger,
   and one colour is left to press. What changes, for every page at once:
   - Headings in Inter, the app's own interface face, medium weight, sentence
     case, tight tracking. Body stays Space Grotesk, labels Space Mono.
   - No boxes. The grid keeps its columns but shows no grey between cells; a
     hairline above each section is the only rule.
   - The bar: the brand and the live read-out on the left, on one line; the
     sections on the right beside Listen.
   - Aqua (#02E8CD, onyx on it) is the colour to press; the neon green is for
     "live" only; mast red stays in the posters.
   - Motion: 250ms ease-out for colour and movement. */
@font-face {
  font-family: "Inter"; src: url("assets/fonts/InterVariable.woff2") format("woff2-variations");
  font-weight: 100 900; font-display: swap;
}
:root {
  --display: "Inter", "Space Grotesk", system-ui, sans-serif;
  --out: cubic-bezier(.215, .61, .355, 1);
  --press: #02E8CD; --press-hover: #5CF2E0;
  --live: #10F205;
}

/* ── type ───────────────────────────────────────────────────────────────── */
:is(.display, .menu a, .pick-name, .numbers dd, .sum-big, .departures tbody th, .tagline .words,
    .vibe-n, .vibe b, .vp-head b, .vibe-regions a b, .card h3, .steps .n, .steps h3, .platform h3,
    .tier h3, .price b, .feature h2, .story h3, .figures dd, .prose h2, .post-nav a, .band-strip,
    .manifesto b, .support-price b, .jf-more b, .paper .display) {
  font-weight: 500; text-transform: none; font-variation-settings: normal; letter-spacing: -.035em;
}
.display { line-height: 1; }
.fit { line-height: .8; letter-spacing: -.055em; }
.js .stretch, .js .stretch.in { font-variation-settings: normal; }
:is(.card h3, .steps h3, .platform h3, .story h3, .tier h3, .feature h2, .jf-more b, .manifesto b, .vibe b) { letter-spacing: -.02em; line-height: 1.12; }
.vibe b { font-size: clamp(17px, calc((100cqi - 48px) / 7), 24px); }
.vibe:hover b { font-variation-settings: normal; }
/* The second half of a headline steps back instead of going hollow. */
.hollow { color: var(--bone2); -webkit-text-stroke: 0; }
.display .aq { color: inherit; }
/* Labels are eyebrows: one small grey line above what they name. */
.label { color: var(--bone2); letter-spacing: .06em; }
.num, .story .meta, .jf-when, .steps .n { color: var(--bone2); }

/* ── no boxes ───────────────────────────────────────────────────────────── */
.grid, .island, .numbers, .vibe-list, .steps, .links, .menu nav, .vibe-others ul, .manifesto .rules { gap: 0; background: transparent; }
.grid { border-bottom: 0; border-top: 1px solid var(--line); }
.grid > .cell { padding-block: 32px; }
.island { border-bottom: 1px solid var(--line); }
.departures th, .departures td { border-bottom-color: var(--line); }

/* ── the bar ────────────────────────────────────────────────────────────── */
.island { display: flex; align-items: center; gap: 8px; padding-inline: 8px; background: color-mix(in srgb, var(--onyx) 92%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.island .cell { background: transparent; }
.island > .brand { flex: none; }
.livebar, .livelink { flex: 0 1 auto; min-width: 0; font: 400 12px/16px var(--mono); letter-spacing: .06em; white-space: nowrap; }
.livelink .lb, .lb-now { white-space: nowrap; }
.livelink:hover { background: transparent; color: var(--bone); }
.livelink::after { content: "→"; margin-left: 10px; color: var(--live); transition: translate .25s var(--out); }
@media (hover: hover) { .livelink:hover::after { translate: 4px 0; } }
.lb-st, .livelink:hover .lb-st { color: var(--live); }
.links { margin-left: auto; flex: none; }
.links .cell::before { content: none; }
.links .cell { font: 500 15px/1 var(--body); letter-spacing: 0; text-transform: none; opacity: .8; padding: 0 14px; transition: opacity .25s var(--out); }
.links .cell:hover, .links .cell[aria-current="page"] { background: transparent; color: var(--bone); opacity: 1; }
.links .cell[aria-current="page"] { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 1px; }
.island .themebtn { background: transparent; flex: none; }
.themebtn:hover { background: transparent; color: var(--bone); }
.go { flex: none; background: transparent !important; color: var(--bone); border: 1px solid currentColor; min-height: 40px !important; margin-inline: 8px;
  font: 500 15px/1 var(--body); letter-spacing: 0; text-transform: none; transition: background-color .25s var(--out), color .25s var(--out); }
.go:hover { background: var(--bone) !important; color: var(--onyx); }
.menu a { font: 500 34px/1.05 var(--display); letter-spacing: -.035em; text-transform: none; background: var(--onyx); }
.menu a::before { content: none !important; }
.menu .menu-go { background: var(--press); color: var(--ink); }
@media (max-width: 1080px) { .island .burger { margin-left: auto; } }

/* Over the globe on the front page: no ground, no rule, the words in bone. */
body:has(.hero-globe) .island { position: fixed; inset: 0 0 auto; }
.island.over { background: transparent; border-bottom-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; color: var(--bone-fixed); }
.island.over :is(.cell, .livelink, .links .cell, .themebtn, .go) { color: var(--bone-fixed); }
.island.over .go:hover { background: var(--bone-fixed) !important; color: var(--ink); }
.island.over .burger { color: var(--bone-fixed); }

/* ── buttons ────────────────────────────────────────────────────────────── */
.btn { background: var(--press); color: var(--ink); gap: 10px; font: 500 16px/20px var(--body); letter-spacing: .005em; text-transform: none; transition: background-color .25s var(--out), transform .25s var(--out); }
.btn:hover { background: var(--press-hover); }
.btn.ghost { background: transparent; color: var(--bone); border: 1px solid currentColor; }
.btn.ghost:hover { background: var(--bone); color: var(--onyx); }
.textlink { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; }
.vibe, .vibe-art, .btn, .go, .menu, .qa summary { transition-duration: .25s; }

/* ── the front page's first screen: the globe is the picture ────────────── */
.hero-globe { position: relative; height: 100svh; min-height: 620px; overflow: hidden; isolation: isolate; color: var(--bone-fixed);
  background: #000 url("assets/globe/stars-a.png") 0 0 / 600px 600px; border-top: 0; }
.hero-globe::before { content: ""; position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background: url("assets/globe/stars-b.png") 200px 120px / 600px 600px; animation: twinkle 7s ease-in-out infinite alternate; }
.hero-globe::after { content: ""; position: absolute; inset: auto 0 0; height: 42%; z-index: -1; pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, .88), rgba(0, 0, 0, 0)); }
.hero-globe .globe { position: absolute; inset: 0; z-index: -1; grid-row: auto; background: transparent; }
.hero-globe .globe::before { content: none; }
.hero-globe .globe img { position: absolute; left: 50%; top: 46%; width: min(118vh, 112vw); height: auto; aspect-ratio: 1; translate: -50% -50%; }
.hero-globe .globe-go { bottom: auto; top: 96px; }
.hero-globe .globe-pick { left: auto; right: var(--pad); bottom: auto; top: 88px; max-width: 420px; }
@media (hover: none) { .hero-globe .globe-live { pointer-events: none; } }
.hero-foot { position: absolute; left: var(--pad); right: var(--pad); bottom: clamp(20px, 3vw, 48px); }
.hero-actions { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 16px var(--pad); margin-bottom: 20px; }
.hero-actions p { max-width: 34ch; font-size: 18px; line-height: 1.4; color: rgba(247, 244, 238, .86); }
.hero-actions .btns { display: flex; flex-wrap: wrap; gap: 12px; }
.hero-actions .btn.ghost { color: var(--bone-fixed); }
.hero-actions .btn.ghost:hover { background: var(--bone-fixed); color: var(--ink); }
.hero-globe h1.fit { display: block; padding: 0; color: var(--bone-fixed); white-space: nowrap; }
@media (max-width: 760px) {
  .hero-globe h1.fit { font-size: 20vw; white-space: nowrap; }
  .hero-actions p { font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) { .hero-globe::before { animation: none; } }
.numbers-section { grid-template-columns: minmax(0, 1fr); }
.numbers-section .numbers { border-top: 0; }
.numbers-section .numbers .cell { padding-top: 16px; border-top: 1px solid var(--line); margin-inline: var(--pad); padding-inline: 0; }
.numbers-section .numbers dd { font-size: clamp(44px, 6.4vw, 96px); line-height: .9; letter-spacing: -.05em; }
@media (min-width: 761px) { .numbers-section .numbers .cell + .cell { margin-left: 0; } .numbers-section .numbers { column-gap: var(--pad); padding-inline: var(--pad); } .numbers-section .numbers .cell { margin-inline: 0; } }
/* The neon is for the dark: on a light bar it reads at 1.3:1, so there the
   station and the arrow take the teal. */
:root[data-theme="light"] .island:not(.over) .lb-st { color: var(--aq); }
:root[data-theme="light"] .island:not(.over) .livelink::after { color: var(--aq); }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .island:not(.over) .lb-st,
  :root:not([data-theme="dark"]) .island:not(.over) .livelink::after { color: var(--aq); }
}
.livelink { overflow: hidden; }
.livelink .lb { min-width: 0; overflow: hidden; }
.lb-st { max-width: 24ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 1240px) { .lb-st { display: none; } }

/* ── the support page: one switch, the price, what each tier gets ─────────── */
.support-head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); align-items: end; padding: 64px var(--pad) 48px; }
.support-head h1 { grid-column: 1 / span 8; font-size: clamp(52px, 8.4vw, 132px); line-height: .9; letter-spacing: -.055em; }
.support-intro { grid-column: 9 / span 4; display: grid; gap: 14px; }
.support-intro .lede { font-size: 18px; line-height: 1.45; color: var(--bone2); }
.plan { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding: 40px var(--pad) 0; border-top: 1px solid var(--line); }
.plan-pick { grid-column: 1 / span 4; display: grid; gap: 18px; align-content: start; }
.seg { display: flex; width: max-content; max-width: 100%; margin: 0; padding: 0; border: 1px solid var(--bone); }
.seg label { position: relative; }
.seg input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }
.seg span { display: inline-flex; align-items: center; min-height: 44px; padding: 0 16px; font: 400 12px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; transition: background-color .25s var(--out), color .25s var(--out); }
.seg input:checked + span { background: var(--bone); color: var(--onyx); }
.seg input:focus-visible + span { outline: 2px solid var(--aq); outline-offset: 2px; }
.plan-price { font: 400 14px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.plan-price b { font: 500 clamp(56px, 7vw, 104px)/.9 var(--display); letter-spacing: -.05em; color: var(--bone); margin-right: 8px; font-variant-numeric: tabular-nums; }
.perks { grid-column: 6 / span 7; counter-reset: perk; margin: 0; padding: 0; list-style: none; }
.perks li { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 4px var(--pad); padding: 20px 0; border-top: 1px solid var(--line); counter-increment: perk; }
.perks li::before { content: counter(perk, decimal-leading-zero); grid-row: span 2; font: 400 12px/24px var(--mono); color: var(--bone2); }
.perks b { font: 500 22px/1.2 var(--display); letter-spacing: -.02em; }
.perks span { color: var(--bone2); }
/* Out of the chosen tier: the name steps back and says so, at full contrast. */
.perks li.out b { color: var(--bone2); font-weight: 400; }
.perks li.out::after { content: "Not in this tier"; grid-column: 2; font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.plan-bar { grid-column: 1 / -1; position: sticky; bottom: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px var(--pad);
  margin: 40px calc(-1 * var(--pad)) 0; padding: 12px var(--pad); border-top: 1px solid var(--line);
  background: color-mix(in srgb, var(--onyx) 94%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.plan-bar .label b { color: var(--bone); font-weight: 400; }
.rule-row { grid-template-columns: repeat(12, minmax(0, 1fr)); }
.rule-row > .cell:first-child { grid-column: 1 / span 3; }
.rule-row > .cell:last-child { grid-column: 4 / span 9; display: grid; gap: 20px; }
.rule-row h2 { font-size: clamp(36px, 5vw, 72px); }
.rule-row p:not(.label) { color: var(--bone2); max-width: 56ch; }
@media (max-width: 900px) {
  .support-head h1, .support-intro, .plan-pick, .perks, .rule-row > .cell:first-child, .rule-row > .cell:last-child { grid-column: 1 / -1; }
  .support-intro { margin-top: 24px; }
  .perks { margin-top: 40px; }
}

/* ── long reading: one column, set off-centre ─────────────────────────────── */
/* A24's Notes: the title as a poster, the text in a 66-character column at
   columns 3 to 9 of 12. AGDA's: the type of piece as a small tag, the writer
   named. The red halftone column beside the text is retired. */
@media (min-width: 1081px) { .prose > .cell { display: block; } .prose > .cell::after { content: none; } }
.post-hero, .post-image, .post .prose, .hear { border-top: 0; }
.post-hero .cell { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding-top: 64px; padding-bottom: 40px; }
.post-hero .cell > * { grid-column: 3 / span 8; }
.post-hero h1 { max-width: none; font-size: clamp(44px, 6.6vw, 96px); line-height: .94; letter-spacing: -.045em; margin: 12px 0 20px; }
.post-hero .tag { margin: 0 10px 0 0; padding: 2px 8px; border: 1px solid currentColor; color: var(--bone); }
.standfirst { font: 400 22px/1.4 var(--body); color: var(--bone2); max-width: 40ch; }
.byline { margin-top: 20px; }
.byline b { color: var(--bone); font-weight: 400; }
.post-image .cell { padding: 0 var(--pad) 48px; background: transparent; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); }
.post-image img { grid-column: 2 / span 10; max-height: none; }
.post .prose > .cell { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding-top: 0; }
.post .prose .body { grid-column: 3 / span 7; max-width: none; }
.post .prose p, .post .prose li { font-size: 20px; line-height: 1.55; color: var(--bone); }
.post .prose p:first-child { font-size: 20px; line-height: 1.55; }
.post .prose h2 { font-size: 30px; line-height: 1.15; letter-spacing: -.025em; margin: 1.8em 0 .5em; }
.hear .cell { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding-top: 0; }
.hear .cell > * { grid-column: 3 / span 7; justify-self: start; }
.hear .cell > .label { padding-top: 16px; border-top: 1px solid var(--line); justify-self: stretch; }
.hear .cell > p:not(.label) { margin: 12px 0 16px; color: var(--bone2); }
@media (max-width: 900px) {
  .post-hero .cell > *, .post-image img, .post .prose .body, .hear .cell > * { grid-column: 1 / -1; }
}
/* On a phone the ring carries the brand, so the live line has room for a
   whole time and city. */
@media (max-width: 760px) { .island .brand-word { display: none; } }
.globe-go { white-space: nowrap; }

/* ── the bar, second pass ───────────────────────────────────────────────────
   The live line is a link and needs no arrow: next to the half moon an arrow
   read as "press the half moon". Without the sections (tablet and phone) the
   half moon sits at the right edge beside the menu, and the live line keeps
   its time and city. */
.livelink::after { content: none; }
.livelink .lb-now { flex: 0 1 auto; }
.livelink .lb-now b { flex: none; }
@media (max-width: 1080px) {
  .island .themebtn { margin-left: auto; width: 44px; }
  .island .burger { margin-left: 0; width: 44px; }
  .island .themebtn + .burger, .island .themebtn ~ .burger { margin-left: 0; }
}

/* ── community to community, on the page's own ground ──────────────────────
   The bone sheet, the red highlighter, the wedge and the registration marks
   are gone; the layout stays. The halftone Earth is drawn in the page's ink. */
.paper { background: var(--onyx); color: var(--bone); border-top: 1px solid var(--line); border-bottom: 0; }
.paper::before { content: none; }
.paper .label { color: var(--bone2); }
.paper .display { color: var(--bone); }
.paper .red { color: var(--bone2); }
.hi { font: 400 clamp(19px, 1.8vw, 22px)/1.5 var(--body); color: var(--bone2); max-width: 44ch; }
.hi span { background: none; color: inherit; padding: 0; }
.paper-rules { border-bottom-color: var(--line); }
.paper-rules li { border-top-color: var(--line); color: var(--bone2); }
.paper-rules b { font: 400 12px/24px var(--mono); color: var(--bone2); }
.paper-rules strong { color: var(--bone); font-weight: 500; }
.paper-art .wedge, .paper .reg { display: none; }
.paper-stage .pin { rotate: none; background: transparent; color: var(--bone2); box-shadow: none; border: 1px solid var(--line); font-weight: 400; }
.paper-stage .log { background: color-mix(in srgb, var(--onyx) 88%, transparent); color: var(--bone2); box-shadow: none; border-top: 1px solid var(--line); padding: 12px 0 0; }

/* ── the ticker: two lines sliding past, level ──────────────────────────── */
.bands { padding: 0; border-top: 1px solid var(--line); border-bottom: 0; overflow: hidden; }
.bands::before { content: none; }
.band-strip { margin: 0; padding: 20px var(--pad); transform: none; background: transparent; color: var(--bone);
  font: 500 clamp(28px, 4vw, 56px)/1.05 var(--display); letter-spacing: -.035em; }
.band-strip.places { transform: none; margin-top: 0; background: transparent; color: var(--bone2); border-top: 1px solid var(--line); }
.stamp { position: static; transform: none; display: flex; align-items: center; gap: 10px; width: max-content; margin: 0; padding: 20px var(--pad) 0;
  background: transparent; border: 0; box-shadow: none; color: var(--bone2); font: 400 12px/16px var(--mono); letter-spacing: .06em; }
.stamp .lamp { width: 8px; height: 8px; background: var(--live); box-shadow: none; }
.stamp-k { color: var(--bone2); }
.stamp-v { color: var(--bone); }
@media (max-width: 760px) { .bands { padding: 0; } .stamp { right: auto; top: auto; } }

/* ── the Journal, A24's Notes and AGDA's Discover ───────────────────────────
   Covers shown as made, no halftone, no red block behind them. Each story a
   card: the cover at 16:10, the kind and date in small type, the title. */
.jf-cover img { box-shadow: none; aspect-ratio: 16 / 10; }
@media (hover: hover) { .jf-cover:hover img { translate: none; box-shadow: none; opacity: .9; } }
.jf-cover .pin { rotate: none; left: 16px; top: 16px; background: var(--onyx); color: var(--bone); border: 1px solid var(--line); font-weight: 400; }
.jf-more ol { gap: 40px var(--pad); }
.jf-more a { border-top: 0; padding-top: 0; gap: 10px; }
.jf-more a img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; margin-bottom: 6px; transition: opacity .25s var(--out); }
@media (hover: hover) { .jf-more a:hover img { opacity: .85; } .jf-more a:hover { border-top-color: transparent; } }
.jf-when { color: var(--bone2); }

/* The Journal page: the three leads, then every story, with room between. */
.featured { gap: 48px var(--pad); padding: 48px var(--pad) 72px; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.featured > .feature { padding: 0; gap: 14px; }
.feature img { aspect-ratio: 16 / 10; }
.feature .label, .feature h2 { padding: 0; }
.feature h2 { font-size: clamp(22px, 2vw, 30px); line-height: 1.15; letter-spacing: -.025em; }
.stories { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 56px var(--pad); padding: 0 var(--pad) 80px; }
.stories > h2 { padding: 48px 0 0; }
.stories > .story { padding: 0; display: flex; flex-direction: column; gap: 14px; }
.story-cover { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; }
.story .meta { color: var(--bone2); margin-bottom: 0; }
.story h3 { font-size: 24px; line-height: 1.15; margin-bottom: 6px; }
.story p:not(.meta) { font-size: 16px; line-height: 1.5; }
@media (max-width: 1080px) { .featured, .stories { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) { .featured, .stories { grid-template-columns: minmax(0, 1fr); } .story { grid-template-columns: none; } }
.story .story-cover { width: 100%; height: auto; }

/* ── Learn ──────────────────────────────────────────────────────────────────
   The library's index (AGDA's Discover: types as pills, a filter, a search)
   and a piece (A24's article column, with the facts beside it). */
.lx-index > section, .lx article { padding-inline: var(--pad); }
.lx-hero { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); align-items: end; padding-block: 64px 48px; }
.lx-hero h1 { grid-column: 1 / span 7; font-size: clamp(64px, 12vw, 180px); line-height: .85; letter-spacing: -.055em; }
.lx-hero > div { grid-column: 8 / span 5; display: grid; gap: 12px; }
.lx-hero .lede { font-size: 18px; line-height: 1.45; color: var(--bone2); }
.lx-paths { padding-block: 0 56px; }
.lx-paths ul { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--pad); margin-top: 16px; }
.lx-paths a { display: grid; gap: 10px; padding: 24px; border: 1px solid var(--line); text-decoration: none; min-height: 180px; align-content: space-between; transition: border-color .25s var(--out); }
.lx-paths a b { font: 500 clamp(26px, 2.6vw, 40px)/1.05 var(--display); letter-spacing: -.035em; }
.lx-paths a span:not(.label) { color: var(--bone2); }
@media (hover: hover) { .lx-paths a:hover { border-color: var(--bone); } }
.lx-library { border-top: 1px solid var(--line); padding-block: 24px 80px; }
.lx-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin-bottom: 32px; }
.lx-tools h2 { margin-right: auto; }
.lx-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.lx-filters button { min-height: 36px; padding: 0 12px; border: 1px solid var(--line); background: transparent; color: var(--bone); cursor: pointer;
  font: 400 12px/1 var(--mono); letter-spacing: .06em; text-transform: uppercase; transition: background-color .25s var(--out), color .25s var(--out); }
.lx-filters button[aria-pressed="true"] { background: var(--bone); color: var(--onyx); border-color: var(--bone); }
@media (pointer: coarse) { .lx-filters button { min-height: 44px; } }
.lx-search input { width: min(320px, 100%); min-height: 44px; padding: 0 14px; border: 1px solid var(--line); background: transparent; color: var(--bone); font: 400 16px/1 var(--body); }
.lx-search input:focus-visible { outline: 2px solid var(--aq); outline-offset: 2px; }
.lx-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 40px var(--pad); }
.lx-card[hidden] { display: none; }
.lx-card a { display: grid; gap: 10px; padding-top: 16px; border-top: 1px solid var(--line); text-decoration: none; }
.lx-card b { font: 500 24px/1.15 var(--display); letter-spacing: -.025em; transition: color .25s var(--out); }
.lx-sum { color: var(--bone2); font-size: 16px; line-height: 1.5; }
@media (hover: hover) { .lx-card a:hover b { color: var(--aq); } }
.lx-none { color: var(--bone2); }
.lx-sections { border-top: 1px solid var(--line); padding-block: 32px 64px; }
.lx-sections ul { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 16px var(--pad); }
.lx-sections li { display: flex; justify-content: space-between; align-items: baseline; padding-top: 10px; border-top: 1px solid var(--line); }
.lx-sections b { font: 500 22px/1 var(--display); }
.lx .tag { margin: 0 10px 0 0; padding: 2px 8px; border: 1px solid currentColor; color: var(--bone); }
/* A piece */
.lx-head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding-block: 64px 40px; }
.lx-head > * { grid-column: 3 / span 8; }
.lx-head .label a { color: inherit; }
.lx-head h1 { font-size: clamp(44px, 6.6vw, 96px); line-height: .94; letter-spacing: -.045em; margin: 12px 0 20px; }
.lx-draft { margin-top: 20px; font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--mast); }
.lx-body { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--pad); padding-bottom: 64px; }
.prose-x { grid-column: 3 / span 7; font: 400 19px/1.6 var(--body); }
.prose-x > * + *, .prose-x section > * + * { margin-top: 1em; }
.prose-x h2 { font: 500 28px/1.15 var(--display); letter-spacing: -.025em; margin-top: 1.8em; }
.prose-x ul, .prose-x ol { padding-left: 1.2em; }
.prose-x ul { list-style: square; }
.prose-x ol { list-style: decimal; }
.prose-x li + li { margin-top: .4em; }
.prose-x a { color: var(--aq); }
.prose-x table { width: 100%; border-collapse: collapse; font-size: 16px; display: block; overflow-x: auto; }
.prose-x th, .prose-x td { text-align: left; padding: 10px 12px 10px 0; border-bottom: 1px solid var(--line); vertical-align: top; }
.prose-x th { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.lx-side { grid-column: 10 / span 3; align-self: start; position: sticky; top: 88px; display: grid; gap: 20px; }
.lx-facts { margin: 0; display: grid; }
.lx-facts div { padding: 12px 0; border-top: 1px solid var(--line); }
.lx-facts dt { font: 400 12px/16px var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); }
.lx-facts dd { margin: 4px 0 0; font-size: 16px; line-height: 1.4; }
.lx-box { padding: 20px 24px; border: 1px solid var(--line); }
.lx-box h2 { margin-top: 0 !important; font-size: 13px; font-family: var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--bone2); font-weight: 400; }
.lx-steps ol { list-style: none; padding: 0; counter-reset: step; }
.lx-steps li { counter-increment: step; display: grid; grid-template-columns: 48px 1fr; padding: 14px 0; border-top: 1px solid var(--line); margin: 0 !important; }
.lx-steps li::before { content: counter(step, decimal-leading-zero); font: 400 12px/30px var(--mono); color: var(--bone2); }
.lx-check .lx-q { border-top: 1px solid var(--line); }
.lx-check .lx-q:last-child { border-bottom: 1px solid var(--line); }
.lx-q summary { display: grid; grid-template-columns: 48px 1fr auto; gap: 0; align-items: baseline; min-height: 56px; padding: 14px 0; cursor: pointer; list-style: none; }
.lx-q summary::-webkit-details-marker { display: none; }
.lx-q summary::after { content: "+"; font: 400 18px/1 var(--mono); color: var(--aq); }
.lx-q[open] summary::after { content: "−"; }
.lx-n { font: 400 12px/1.6 var(--mono); color: var(--bone2); }
.lx-q p { margin: 0 0 16px 48px; color: var(--bone2); }
.lx-timeline ol { list-style: none; padding: 0; }
.lx-timeline li { display: grid; grid-template-columns: 96px 1fr; gap: var(--pad); padding: 18px 0; border-top: 1px solid var(--line); margin: 0 !important; }
.lx-year { font: 500 28px/1 var(--display); letter-spacing: -.03em; }
.lx-timeline li p { margin: 0; }
.lx-term { position: relative; padding-top: 8px; border-top: 1px solid var(--line); margin-top: 32px !important; }
.lx-term h2 { margin-top: 12px !important; }
.lx-anchor { position: absolute; right: 0; top: 16px; font: 400 14px/1 var(--mono); color: var(--bone2); text-decoration: none; padding: 8px; }
.lx-sources ol { font-size: 15px; color: var(--bone2); }
.lx-lessons ol, .lx-items ol { list-style: none; padding: 0; counter-reset: les; }
.lx-lessons li, .lx-items li { counter-increment: les; margin: 0 !important; }
.lx-lessons a, .lx-items a { display: grid; grid-template-columns: 48px 1fr; gap: 4px 0; padding: 16px 0; border-top: 1px solid var(--line); text-decoration: none; color: var(--bone); }
.lx-lessons a::before, .lx-items a::before { content: counter(les, decimal-leading-zero); grid-row: span 2; font: 400 12px/28px var(--mono); color: var(--bone2); }
.lx-lessons b, .lx-items b { font: 500 22px/1.2 var(--display); letter-spacing: -.02em; }
.lx-lessons span { color: var(--bone2); font-size: 16px; }
.lx-next { display: grid; grid-template-columns: 1fr 1fr; gap: var(--pad); padding: 0 0 64px; }
.lx-next a { display: grid; gap: 6px; padding-top: 16px; border-top: 1px solid var(--line); text-decoration: none; }
.lx-next a:last-child { text-align: right; }
.lx-next b { font: 500 22px/1.2 var(--display); }
@media (max-width: 1080px) { .lx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .lx-hero h1, .lx-hero > div, .lx-head > *, .prose-x, .lx-side { grid-column: 1 / -1; }
  .lx-side { position: static; margin-top: 40px; }
  .lx-paths ul, .lx-grid { grid-template-columns: minmax(0, 1fr); }
  .lx-timeline li { grid-template-columns: 72px 1fr; }
}
@media (max-width: 1080px) { .island .burger span { left: 12px; right: 12px; } }

/* ══ red, the accent (15 Oct 2026, second pass) ══════════════════════════════
   Aqua stays the colour to press. Red is the accent everywhere else: labels,
   numbers, links, focus. Mast red on onyx reads 4.6:1; on a light page the
   text red is deeper (#C8291E, 5.5:1) so small type still passes. The dark
   teal is retired. */
:root { --aq: #E5382C; --red-ink: #E5382C; }
:root[data-theme="light"] { --aq: #C8291E; --red-ink: #C8291E; }
@media (prefers-color-scheme: light) { :root:not([data-theme="dark"]) { --aq: #C8291E; --red-ink: #C8291E; } }
.label { color: var(--red-ink); }
:is(.num, .manifesto .num, .paper-rules b, .steps .n, .perks li::before, .lx-n) { color: var(--red-ink); }
.paper .label, .paper-rules b { color: var(--red-ink); }
/* The bar's red rule comes back once the bar has a ground of its own. */
.island:not(.over) { border-bottom: 3px solid var(--mast); }
.paper-stage .pin { background: var(--press); color: var(--ink); border-color: var(--press); font-weight: 700; }

/* ── decolonize your ears: one straight line instead of the drawn frame ──── */
.why .why-head { display: flex; flex-direction: column; gap: 16px; margin: 40px 0 40px var(--pad); padding: 0 var(--pad) 0 20px; border-left: 3px solid var(--mast); }
.why .why-head .stepframe { display: none; }

/* ── the tagline, stacked, with the Earth beside it ─────────────────────── */
.tagline { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--pad); align-items: center; padding: 72px var(--pad); border-top: 1px solid var(--line); border-bottom: 0; }
.tagline .words { max-width: 14ch; font-size: clamp(36px, 5vw, 76px); line-height: 1.02; letter-spacing: -.04em; }
.tagline .line + .line { margin-top: .5em; }
.tagline-art { margin: 0; justify-self: center; width: min(100%, 520px); }
.tagline-art img { width: 100%; height: auto; clip-path: circle(41.5% at 50% 49.5%); }
@media (max-width: 760px) { .tagline { grid-template-columns: minmax(0, 1fr); padding: 56px var(--pad); } .tagline-art { width: min(80%, 360px); } .tagline .words { font-size: clamp(30px, 9vw, 44px); } }

/* ── where it runs: each picture under its own words ────────────────────── */
.platform { gap: 14px; }
.platform-shot { display: block; height: auto; margin-top: auto; padding-top: 24px; }
.platform-shot.phone { width: min(220px, 56%); border-radius: 28px; border: 5px solid #1d1c1c; padding-top: 0; margin-top: 24px; box-shadow: 0 18px 48px rgba(0, 0, 0, .35); }
.platform-shot.desk { width: 100%; max-width: 640px; }
@media (min-width: 761px) { .platforms .platform { justify-content: flex-start; } }

/* ── keep it independent: the halftone Earth smaller, and whole ─────────── */
.support-globe { width: 260px; right: 32px; bottom: 24px; }
@media (max-width: 760px) { .support-globe { width: 180px; right: 16px; bottom: 16px; } .support-cta.red .cell:first-child { min-height: 420px; } }

/* ── questions: lighter ─────────────────────────────────────────────────── */
.qa summary { font: 500 17px/1.4 var(--body); text-transform: none; letter-spacing: 0; }

/* ── the last word: the Earth in the corner, contour lines behind ───────── */
.final { position: relative; overflow: hidden; isolation: isolate; min-height: 520px; align-content: center; }
.final > .cell { background: transparent; position: relative; }
.final-topo { position: absolute; inset: 0; z-index: -2; pointer-events: none; background: var(--bone); opacity: .09;
  -webkit-mask: url("assets/patterns/topo.svg") center / 1600px auto repeat; mask: url("assets/patterns/topo.svg") center / 1600px auto repeat; }
.final-globe { position: absolute; right: -14%; bottom: -46%; z-index: -1; width: min(820px, 64vw); height: auto; clip-path: circle(41.5% at 50% 49.5%); pointer-events: none; }
@media (max-width: 760px) { .final { min-height: 460px; } .final-globe { width: 92vw; right: -38%; bottom: -34%; } }
.final-globe { width: min(720px, 54vw); right: -8%; bottom: -52%; }

/* ── 15 Oct, third pass ─────────────────────────────────────────────────── */
/* The Earth beside the tagline and in the last section: the share card's
   globe, cloudless, drawn on a canvas (aural.js, data-earth). */
.tagline-art canvas { display: block; width: 100%; aspect-ratio: 1; }
.final-globe { width: min(640px, 48vw); aspect-ratio: 1; right: -6%; bottom: -34%; clip-path: none; }
.final-topo { opacity: .05; }
@media (max-width: 760px) { .final-globe { width: 80vw; right: -30%; bottom: -26%; } }
/* Keep it independent: the halftone lower, cut off at the bottom, never at the right. */
.support-globe { width: 300px; right: 40px; bottom: -120px; }
@media (max-width: 760px) { .support-globe { width: 200px; right: 24px; bottom: -80px; } }
/* Where it runs: the phone and the desktop at sizes that answer each other. */
.platforms { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
.platform-shot { margin-top: 28px; padding-top: 0; }
.platform-shot.phone { width: min(200px, 48%); margin-top: 28px; }
.platform-shot.desk { width: 100%; max-width: none; align-self: center; }
@media (max-width: 760px) { .platforms { grid-template-columns: minmax(0, 1fr); } .platform-shot.phone { width: 180px; } }
/* Red, dialled back: the eyebrows go back to grey; red stays for the numbers,
   the rules, the links and the sections that carry the argument. */
.label { color: var(--bone2); }
:is(.paper, .manifesto, .why) .label { color: var(--red-ink); }
.final-globe { bottom: -18%; right: -8%; }

/* ── 15 Oct, fourth pass ────────────────────────────────────────────────── */
/* The tagline's Earth turns, a hand can spin it, and aqua rings go out from
   it the way a signal does. */
.tagline-art { position: relative; }
.tagline-art canvas { position: relative; z-index: 1; cursor: grab; }
.tagline-art canvas:active { cursor: grabbing; }
.tagline-art .pulse { position: absolute; inset: 9%; border-radius: 50%; border: 2px solid var(--press); opacity: 0; pointer-events: none;
  animation: signal 4.5s var(--out) infinite; }
.tagline-art .pulse:nth-child(2) { animation-delay: 1.5s; }
.tagline-art .pulse:nth-child(3) { animation-delay: 3s; }
@keyframes signal { 0% { transform: scale(.96); opacity: .7; } 100% { transform: scale(1.45); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tagline-art .pulse { animation: none; } }
/* The city log beside the dot-screen Earth: a black card, white words, both themes. */
.paper-stage .log { background: #0C0B0B; color: #F7F4EE; border: 0; padding: 12px 14px; box-shadow: none; }
/* Keep it independent: the halftone Earth whole on a phone; on wider screens
   only its foot is cut, by the block's bottom edge. */
.support-globe { width: 300px; height: 300px; right: 40px; bottom: -70px; }
@media (max-width: 760px) {
  .support-globe { position: relative; display: block; right: auto; bottom: auto; width: 200px; height: 200px; margin: 28px auto 0; }
  .support-cta.red .cell:first-child { min-height: 0; }
}
/* Where it runs: the desktop picture larger. */
.platforms { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); }
/* The last word on a phone: no empty band above it. */
@media (max-width: 760px) {
  .final { min-height: 0; align-content: start; padding-bottom: 240px; }
  .final h2 { padding-top: 40px; }
  .final-globe { width: 78vw; right: -24%; bottom: -18%; }
}
