/* Hallmark · genre: modern-minimal · macrostructure: Marquee Hero · theme: Coral (tuned: rose accent from PAWS's nose)
 * enrichment: interactive 3D (three.js, shell fur) · nav: N5 floating pill · footer: Ft5 statement
 * tone: technical, deadpan · anchor hue: 65 (warm paper) · accent hue: 17
 * pre-emit critique: P4 H4 E5 S5 R4 V4
 * contrast: pass (40–41) · slop: pass (42–45) · honest: pass (46) · chrome: pass (47) · tokens: pass (48)
 * responsive: pass (49) · icons: pass (30) · mobile: pass (34, 49, 50–57)
 */
@import url("tokens.css");

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

html {
  overflow-x: clip;
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  overflow-x: clip;
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { margin: 0; font-family: var(--font-display); font-style: normal; font-weight: 700; }
p { margin: 0; }
img, video { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
[hidden] { display: none !important; }

:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 3px; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: calc(-1 * var(--space-3xl));
  left: var(--space-md);
  z-index: var(--z-modal);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  background: var(--color-ink);
  color: var(--color-paper);
  text-decoration: none;
}
.skip-link:focus-visible { top: var(--space-md); }

/* ------------------------------------------------------------------ nav */

.nav {
  position: fixed;
  top: var(--space-md);
  left: 50%;
  z-index: var(--z-sticky);
  display: inline-flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-2xs) var(--space-2xs) var(--space-2xs) var(--space-md);
  transform: translateX(-50%);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-pill);
  background: color-mix(in oklch, var(--color-paper) 82%, transparent);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  backdrop-filter: blur(14px) saturate(120%);
  box-shadow: var(--shadow-whisper);
  white-space: nowrap;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
}
.wordmark__mark {
  width: 1.9rem;
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.nav__links { display: none; gap: var(--space-lg); }
.nav__links a {
  color: var(--color-muted);
  text-decoration: none;
  transition: color var(--dur-short) var(--ease-out);
}
.nav__links a:hover { color: var(--color-ink); }

.nav__cta {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  padding: 0 var(--space-md);
  border-radius: var(--radius-pill);
  background: var(--color-ink);
  color: var(--color-paper);
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  transition: transform var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .nav__cta:hover { transform: translateY(-1px); } }
.nav__cta:active { transform: translateY(1px); }

@media (min-width: 40rem) {
  .nav__links { display: flex; }
}

/* Dark / light: one icon button, the moon while dark (the default), the sun
 * while light. aria-pressed says which; main.js flips and saves it. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin-right: calc(var(--space-xs) * -1);
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  transition: color var(--dur-short) var(--ease-out), background-color var(--dur-short) var(--ease-out);
}
.theme-toggle svg { width: 1.15rem; height: 1.15rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.theme-toggle__sun { display: none; }
:root[data-theme="light"] .theme-toggle__moon { display: none; }
:root[data-theme="light"] .theme-toggle__sun { display: block; }
@media (hover: hover) { .theme-toggle:hover { color: var(--color-ink); background: var(--color-paper-2); } }
.theme-toggle:active { transform: translateY(1px); }

/* ----------------------------------------------------------------- hero */

.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  align-content: end;
  min-height: min(90svh, 56rem);
  overflow: clip;
  background: radial-gradient(ellipse 60% 48% at 50% 36%, var(--color-stage-hi), var(--color-stage));
}

/* Back in the dark: his own eyes, huge, behind him (always dark: the hero is
 * .scheme-dark). The poster shows at once; the loop fades in over it once it
 * plays (main.js), and never under reduced motion. A scrim at the foot keeps
 * the title readable over the fur. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: var(--color-stage);
}
.hero__poster,
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}
/* Phones see a slice of the wide frame: his left eye, catchlight and all. */
@media (max-width: 40rem) {
  .hero__poster,
  .hero__video { object-position: 22% 45%; }
}
.hero__video { opacity: 0; transition: opacity 900ms var(--ease-out); }
.hero__video.is-playing { opacity: 1; }
.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, oklch(12% 0.008 50 / 0.82), oklch(12% 0.008 50 / 0) 42%),
    linear-gradient(to bottom, oklch(12% 0.008 50 / 0.45), oklch(12% 0.008 50 / 0) 18%);
}

/* A dark section re-applies the text colour with its own (dark) values: the
 * colour it would otherwise inherit was worked out with the page's. */
.scheme-dark { color: var(--color-ink); }

.hero__stage { position: absolute; inset: 0; z-index: 0; cursor: grab; touch-action: pan-y; }
.hero__stage:focus-visible { outline-offset: -8px; }
body.is-dragging-paws { cursor: grabbing; user-select: none; }

/* PAWS lives on one fixed canvas over the page: in the hero at the top,
   floating after the pointer further down. It never takes pointer events;
   paws-scene.js hit-tests him instead. */
.paws-canvas {
  position: fixed;
  inset: 0;
  z-index: var(--z-paws);
  width: 100%;
  height: 100%;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-long) var(--ease-out);
}
.paws-canvas.is-ready { opacity: 1; }

.hero__fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 20%;
}

.hero__loading {
  position: absolute;
  top: 38%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.hero__stage.is-ready .hero__loading,
.hero__stage.is-fallback .hero__loading { display: none; }

.hero__foot {
  position: relative;
  z-index: var(--z-raised);
  display: grid;
  gap: var(--space-md);
  padding: 0 var(--page-gutter) var(--space-xl);
  pointer-events: none;
}

.hero__title {
  max-width: 11ch;
  min-width: 0;
  font-size: var(--text-display);
  line-height: 0.98;
  letter-spacing: -0.035em;
  overflow-wrap: anywhere;
  text-wrap: balance;
}

.hero__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  color: var(--color-muted);
  font-size: var(--text-sm);
  pointer-events: auto;
}
.hero__hint-coarse { display: none; }
@media (pointer: coarse) {
  .hero__hint-fine { display: none; }
  .hero__hint-coarse { display: inline; }
}
.hero__count:empty { display: none; }
.hero.is-fallback .hero__controls { display: none; }

.toggle {
  min-height: 2.25rem;
  padding: 0 var(--space-sm);
  border: var(--rule-hair) solid var(--color-ink-soft);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-ink);
  font-size: var(--text-sm);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .toggle:hover { background: var(--color-paper); } }
.toggle:active { transform: translateY(1px); }
.toggle[aria-pressed="true"] { background: var(--color-ink); color: var(--color-paper); }

/* Speech bubble, placed next to his head by main.js. */
.bubble {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-bubble);
  max-width: min(17rem, 72vw);
  padding: var(--space-sm) var(--space-md);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  background: var(--color-paper);
  box-shadow: var(--shadow-whisper);
  line-height: 1.35;
  opacity: 0;
  transform: translate(var(--bx, 0px), var(--by, 0px));
  transition: opacity var(--dur-short) var(--ease-out);
  pointer-events: none;
}
.bubble.is-visible { opacity: 1; }

@media (min-width: 60rem) {
  .hero {
    min-height: min(100svh, 62rem);
    background: radial-gradient(ellipse 40% 60% at 66% 46%, var(--color-stage-hi), var(--color-stage));
  }
  .hero__fallback { object-position: 72% 50%; }
  .hero__loading { top: 48%; left: 66%; }
  .hero__foot { gap: var(--space-lg); padding-bottom: var(--space-2xl); }
}

/* ------------------------------------------------------------- contract */

.contract {
  display: grid;
  gap: var(--space-xl);
  padding: var(--space-3xl) var(--page-gutter) var(--space-2xl);
  border-top: var(--rule-thick) solid var(--color-rule-strong);
}

.contract__title,
.treasury__title,
.studio__title,
.socials__title,
.about__statement {
  font-size: var(--text-xl);
  line-height: 1.06;
  letter-spacing: -0.025em;
  overflow-wrap: anywhere;
  min-width: 0;
}

.contract__intro { display: grid; align-content: start; gap: var(--space-sm); max-width: 45ch; }
.contract__intro p { color: var(--color-muted); }

.contract__panel {
  display: grid;
  gap: var(--space-lg);
  padding: var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
}

.contract__badges { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.badge {
  padding: var(--space-3xs) var(--space-sm);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.badge--status { display: inline-flex; align-items: center; gap: var(--space-xs); color: var(--color-accent-ink); }
.badge--status::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}

.contract__address {
  font-family: var(--font-mono);
  font-size: clamp(1rem, 0.7rem + 1.2vw, 1.55rem);
  line-height: 1.3;
  letter-spacing: 0.01em;
  overflow-wrap: anywhere;
  min-width: 0;
}
.contract[data-state="pending"] .contract__address { color: var(--color-neutral); }

.contract__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm) var(--space-md); }
.contract__helper { color: var(--color-muted); font-size: var(--text-sm); }

.contract__links { display: flex; flex-wrap: wrap; gap: var(--space-xs) var(--space-lg); }
.contract__links a {
  font-weight: 700;
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
  white-space: nowrap;
  transition: text-decoration-thickness var(--dur-short) var(--ease-out);
}
.contract__links a:hover { text-decoration-thickness: 2px; }
.contract__links a::after { content: " ↗"; }
.link-soon { color: var(--color-neutral); white-space: nowrap; }

.contract__warning {
  max-width: 62ch;
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
  color: var(--color-muted);
  font-size: var(--text-sm);
}

@media (min-width: 60rem) {
  .contract { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-2xl); }
  .contract__panel { padding: var(--space-xl); }
}

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.75rem;
  padding: 0 var(--space-lg);
  border: var(--rule-hair) solid transparent;
  border-radius: var(--radius-pill);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: transform var(--dur-micro) var(--ease-out), background-color var(--dur-short) var(--ease-out);
}
.btn--primary { background: var(--color-ink); color: var(--color-paper); }
@media (hover: hover) { .btn--primary:hover:not(:disabled) { transform: translateY(-1px); } }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled {
  border-color: var(--color-rule);
  background: var(--color-paper);
  color: var(--color-neutral);
  cursor: not-allowed;
}

/* ----------------------------------------------------------------- about */

.about {
  display: grid;
  gap: var(--space-xl) var(--space-2xl);
  padding: var(--space-4xl) var(--page-gutter) var(--space-3xl);
}
.about__statement { max-width: 20ch; }
.about__body {
  display: grid;
  gap: var(--space-md);
  max-width: 58ch;
  color: var(--color-ink-soft);
  font-size: var(--text-md);
  line-height: 1.5;
}

.spec { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.spec caption {
  padding-bottom: var(--space-xs);
  caption-side: top;
  color: var(--color-muted);
  font-size: var(--text-sm);
  text-align: left;
}
.spec th, .spec td {
  padding: var(--space-sm) 0;
  border-top: var(--rule-hair) solid var(--color-rule);
  font-weight: 400;
  text-align: left;
  vertical-align: baseline;
}
.spec tr:last-child th, .spec tr:last-child td { border-bottom: var(--rule-hair) solid var(--color-rule); }
.spec th { width: 46%; color: var(--color-muted); }
.spec tr:last-child td { color: var(--color-accent-ink); font-weight: 700; }

@media (min-width: 60rem) {
  .about {
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    grid-template-areas: "statement statement" "body spec";
  }
  .about__statement { grid-area: statement; }
  .about__body { grid-area: body; }
  .about > .spec { grid-area: spec; align-self: start; }
}

/* -------------------------------------------------------------- treasury */

/* Data colours. tokens.css is shared with another job right now, so the
 * treasury's chart colours are scoped here; move them to tokens.css when free.
 * Two, both neutral, so the accent stays a highlighter: fees in (and the
 * reserve they leave) in warm taupe, spending in ink. Categories are told
 * apart by their names, not by colour (the bar list labels every row), so
 * an empty category can't push two look-alike colours together. Text never
 * wears these colours: marks only. Red is kept for "below the floor". The
 * studio's lines (.metro, below) draw the same money, so they share them. */
.treasury, .metro {
  --flow-in:     #928377; /* oklch(62% 0.025 62), 3.3:1 on paper */
  --flow-out:    #312d2a; /* = --color-ink-soft */
  --meter-track: #ded6ce; /* a light step of the taupe */
  --chart-grid:  #e2ddd8; /* hairlines, one step off the paper */
  --chart-axis:  var(--color-rule);
}
/* The same two neutrals on charcoal: taupe lifted (5.5:1 on the dark paper),
 * spending in the light ink (12:1), the tracks and grid one step off the paper. */
:root[data-theme="dark"] :is(.treasury, .metro) {
  --flow-in:     #a08f80; /* oklch(64% 0.03 62) */
  --flow-out:    #d5d0cb; /* = dark --color-rule-strong */
  --meter-track: #3a3330; /* oklch(31% 0.01 58) */
  --chart-grid:  #302a27;
}
.flow-in     { --swatch: var(--flow-in); }
.flow-out    { --swatch: var(--flow-out); }

.treasury {
  display: grid;
  gap: var(--space-2xl);
  padding: var(--space-3xl) var(--page-gutter);
  border-top: var(--rule-hair) solid var(--color-rule);
}

.treasury__head { display: grid; gap: var(--space-lg); }
.treasury__titles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-self: start;
  gap: var(--space-sm) var(--space-md);
}
.treasury__intro { display: grid; gap: var(--space-md); max-width: 60ch; }
.treasury__lede { color: var(--color-muted); text-wrap: pretty; }
.treasury__note {
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
  color: var(--color-ink-soft);
}
.treasury__note strong { color: var(--color-ink); }
.treasury__meta { color: var(--color-neutral); font-size: var(--text-sm); }

/* Sample data: inverted so it can't be mistaken for a status chip. */
.badge--sample {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  border-color: var(--color-ink);
  background: var(--color-ink);
  color: var(--color-paper);
  font-weight: 700;
}
.badge--sample::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}

/* KPI row: stat tiles on hairlines. Proportional figures at display size. */
.kpis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  border-top: var(--rule-hair) solid var(--color-rule-strong);
}
.kpi {
  display: grid;
  /* Label, value and note rows are shared across a row of tiles, so the
   * values line up even when one label wraps. */
  grid-row: span 3;
  grid-template-rows: subgrid;
  align-content: start;
  gap: var(--space-2xs);
  min-width: 0;
  padding: var(--space-md) var(--space-md) var(--space-lg) 0;
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.kpi:nth-child(even) { padding-left: var(--space-md); border-left: var(--rule-hair) solid var(--color-rule); }
.kpi dd { margin: 0; }
.kpi__label {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-self: end;
  gap: var(--space-3xs) var(--space-xs);
  color: var(--color-muted);
  font-size: var(--text-sm);
}
/* Sample figures are tagged inside each tile, so a cropped tile still says so. */
.kpi__sample {
  display: inline-block;
  padding: 0 0.4rem;
  border: var(--rule-hair) solid var(--color-ink);
  border-radius: var(--radius-pill);
  color: var(--color-ink);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.5;
  text-transform: uppercase;
}
.kpi__value {
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.025em;
  overflow-wrap: anywhere;
}
.kpi__unit { color: var(--color-muted); font-size: var(--text-base); font-weight: 400; letter-spacing: 0; }
.kpi__note { color: var(--color-muted); font-size: var(--text-sm); }

/* Blocks: each chart, table and list sits on a hairline with its heading. */
.treasury__grid { display: grid; gap: var(--space-2xl); }
.viz {
  display: grid;
  align-content: start;
  gap: var(--space-lg);
  min-width: 0;
  padding-top: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.viz__head {
  display: flex;
  flex-wrap: wrap;
  align-items: start;
  justify-content: space-between;
  gap: var(--space-sm) var(--space-lg);
}
.viz__titles { display: grid; gap: var(--space-2xs); max-width: 52ch; }
.viz__title { font-size: var(--text-md); line-height: 1.2; letter-spacing: -0.01em; }
.viz__sub { color: var(--color-muted); text-wrap: pretty; }
.viz__tools { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.viz__chart, .viz__table { display: grid; gap: var(--space-md); min-width: 0; }
.viz__source { color: var(--color-neutral); font-size: var(--text-sm); }
.viz__empty { color: var(--color-muted); }

/* Legend: the dependable identity channel. Keys mirror the marks. */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-lg);
  color: var(--color-ink-soft);
  font-size: var(--text-sm);
}
.legend li { display: inline-flex; align-items: center; gap: var(--space-xs); }
.legend__value { color: var(--color-muted); font-variant-numeric: tabular-nums; }
.key {
  display: inline-block;
  flex: none;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 2px;
  background: var(--swatch, var(--color-neutral));
}
.key--line { width: 1rem; height: 0; border-top: 1.5px dashed var(--color-muted); border-radius: 0; background: none; }

/* Marks are focusable stand-ins laid over each chart (the drawing itself is
 * one role="img"). The hit area is bigger than the mark. */
.hit { display: block; border-radius: var(--radius-sm); cursor: default; }
.hit:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }

/* The floating 3D PAWS follows the pointer over the page. While a chart mark
 * is hovered or focused, he steps aside (the canvas already fades), so he
 * never sits on the columns or the tooltip being read. The studio's lines
 * mark theirs [data-paws-aside]: every stop and figure, and each platform
 * (hovered, or a piece in it focused from the keyboard). */
body:has(#treasury .hit:hover, #treasury .hit:focus-visible, #treasury .bars__row:hover,
  .metro [data-paws-aside]:hover, .metro [data-paws-aside]:focus-visible, .metro [data-paws-aside] :focus-visible, .metro .metro__dep:hover, .metro .metro__table tr:hover) .paws-canvas { opacity: 0; }
/* Where nothing is hovered (main.js, stopgaps until the scene does it): on
 * touch screens, and until a mouse moves, he docks in the bottom-right
 * corner, which the studio's right-hand column (amounts, Sample tags, older
 * pieces, tables) scrolls through, so he steps aside while the studio is in
 * the bottom half of the screen. With reduced motion he stays in the hero,
 * and the scene leaves his last frame on the canvas once it has gone, so the
 * canvas is hidden while the hero is out of view. */
body.is-studio-in-dock:not(.has-mouse) .paws-canvas { opacity: 0; }
@media (pointer: coarse) { body.is-studio-in-dock .paws-canvas { opacity: 0; } }
body.is-paws-parked .paws-canvas { visibility: hidden; }

/* Tooltip: value first, label second, line keys. Enhances, never gates.
 * It sits above PAWS's canvas and his speech bubble, under the sticky nav. */
.tip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: calc(var(--z-paws) + 15);
  display: grid;
  gap: 0.15rem;
  width: max-content;
  max-width: min(17rem, 100%);
  padding: var(--space-xs) var(--space-sm);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  background: var(--color-paper);
  box-shadow: var(--shadow-whisper);
  color: var(--color-ink);
  font-size: var(--text-sm);
  line-height: 1.35;
  pointer-events: none;
}
.tip__title, .tip__label, .tip__note { color: var(--color-muted); }
.tip__row { display: flex; align-items: center; gap: var(--space-xs); }
.tip__key { flex: none; width: 0.85rem; height: 3px; border-radius: 2px; background: var(--swatch, var(--color-neutral)); }
.tip__value { font-weight: 700; font-variant-numeric: tabular-nums; }
.tip__hint { padding-top: 0.15rem; color: var(--color-neutral); font-family: var(--font-mono); font-size: 0.7rem; }

/* 2. Where the fees go: a labelled bar list. One row per category: its name
 * and what it pays for, an ink bar (scaled to the biggest category; 14px,
 * 4px rounded at the data end, square at the baseline), and its value and
 * share at the tip. Rows never touch, and each names itself. */
.bars { display: grid; margin: 0; padding: 0; list-style: none; border-top: var(--rule-hair) solid var(--color-rule); }
.bars__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name value" "bar bar";
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  padding: var(--space-sm) 0;
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.bars__name { grid-area: name; display: grid; min-width: 0; color: var(--color-ink); }
.bars__detail { color: var(--color-muted); font-size: var(--text-sm); }
.bars__track { grid-area: bar; display: block; height: 0.875rem; }
.bars__bar { display: block; height: 100%; min-width: 2px; border-radius: 0 4px 4px 0; background: var(--flow-out); }
.bars__value { grid-area: value; color: var(--color-muted); font-size: var(--text-sm); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.bars__value b { color: var(--color-ink); font-size: var(--text-base); font-weight: 700; }
.bars__row.is-empty .bars__value b { color: var(--color-muted); font-weight: 400; }

@media (min-width: 48rem) {
  .bars__row { grid-template-columns: minmax(10rem, 17rem) minmax(0, 1fr) 8.5rem; grid-template-areas: "name bar value"; }
}

/* 4. Week by week: one axis, two series, hairline grid. */
.weekly { position: relative; }
.weekly__svg { display: block; overflow: visible; }
.weekly__marks { position: absolute; inset: 0; }
.weekly__marks .hit { position: absolute; }
/* The ring stays inside the week's band, off the labels and ticks around it. */
.weekly__marks .hit:focus-visible { outline-offset: -2px; }
.weekly .grid { stroke: var(--chart-grid); stroke-width: 1; }
.weekly .axis { stroke: var(--chart-axis); stroke-width: 1; }
.weekly .tick { fill: var(--color-neutral); font-size: 12px; font-variant-numeric: tabular-nums; }
.weekly .col--in { fill: var(--flow-in); }
.weekly .col--out { fill: var(--flow-out); }
.weekly .cap { stroke: var(--color-muted); stroke-width: 1.5; stroke-dasharray: 4 3; }
.weekly .value {
  fill: var(--color-ink);
  font-size: var(--text-sm);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  paint-order: stroke;
  stroke: var(--color-paper);
  stroke-width: 4px;
  stroke-linejoin: round;
}
.weekly__band { fill: var(--color-paper-2); }

/* 3. The reserve: a same-ramp meter with the floor marked in ink. */
.reserve__figure { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-xs) var(--space-sm); }
.reserve__pct { font-size: var(--text-xl); font-weight: 700; line-height: 1; letter-spacing: -0.025em; }
.reserve__of { color: var(--color-muted); }
.meter { position: relative; padding: 0.375rem 0 1.75rem; }
.meter__track { height: 0.875rem; overflow: hidden; border-radius: 4px; background: var(--meter-track); }
.meter__fill { height: 100%; border-radius: 0 4px 4px 0; background: var(--flow-in); }
.meter.is-low .meter__fill { background: var(--color-focus); }
.meter__floor {
  position: absolute;
  top: 0;
  width: 2px;
  height: calc(0.875rem + 0.75rem);
  margin-left: -1px;
  background: var(--color-ink);
}
.meter__floor-label {
  position: absolute;
  top: calc(100% + var(--space-2xs));
  left: 50%;
  transform: translateX(-50%);
  color: var(--color-ink-soft);
  font-size: var(--text-sm);
  white-space: nowrap;
}
.meter__floor--start .meter__floor-label { left: 0; transform: none; }
.meter__floor--end .meter__floor-label { left: auto; right: 0; transform: none; }
/* The reserve's figures: its last row ("Above the floor") is ink, and turns
 * red only below the floor, beside the "Below the floor" chip. */
.spec--reserve tr:last-child td { color: var(--color-ink); }
.spec--reserve.is-low tr:last-child td { color: var(--color-focus); }

/* Table views share the .spec look: hairline rows, caption on top. */
.spec--table th[scope="row"] { width: auto; color: var(--color-ink-soft); }
.spec--table thead th { padding-top: 0; border-top: 0; color: var(--color-muted); font-size: var(--text-sm); }
.spec--table th, .spec--table td { padding-right: var(--space-md); }
.spec--table th:last-child, .spec--table td:last-child { padding-right: 0; }
.spec--table .num { text-align: right; white-space: nowrap; }
.spec--table tbody tr:last-child td { color: inherit; font-weight: 400; }
.spec.spec--table tfoot th, .spec.spec--table tfoot td,
.spec.spec--table tr.is-subtotal th, .spec.spec--table tr.is-subtotal td { color: var(--color-ink); font-weight: 700; }

/* 5. Recent payments. */
.ledger { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.ledger caption {
  padding-bottom: var(--space-xs);
  caption-side: top;
  color: var(--color-muted);
  font-size: var(--text-sm);
  text-align: left;
}
.ledger th, .ledger td {
  padding: var(--space-sm) var(--space-md) var(--space-sm) 0;
  border-top: var(--rule-hair) solid var(--color-rule);
  font-weight: 400;
  text-align: left;
  vertical-align: baseline;
}
.ledger th:last-child, .ledger td:last-child { padding-right: 0; }
.ledger thead th { padding-top: 0; border-top: 0; color: var(--color-muted); font-size: var(--text-sm); }
.ledger tbody tr:last-child td { border-bottom: var(--rule-hair) solid var(--color-rule); }
.ledger .num { text-align: right; white-space: nowrap; }
.ledger__date { color: var(--color-muted); white-space: nowrap; }
.ledger__cat { color: var(--color-ink-soft); white-space: nowrap; }
.ledger__cat .key { margin-right: var(--space-xs); }
.ledger__amount { font-weight: 700; }
.ledger__receipt { white-space: nowrap; }
.ledger__receipt a, .vault__addr a {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
.ledger__receipt a::after, .vault__addr a::after { content: " ↗"; font-family: var(--font-body); }
.ledger__receipt a:hover, .vault__addr a:hover { text-decoration-thickness: 2px; }
.ledger__none { color: var(--color-neutral); }

/* 6. The rules, numbered like the studio index, and the treasury address. */
.rules { display: grid; margin: 0; padding: 0; list-style: none; border-top: var(--rule-hair) solid var(--color-rule); }
.rules__item {
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: var(--space-sm);
  padding: var(--space-sm) 0;
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.rules__num { color: var(--color-neutral); font-family: var(--font-mono); font-size: var(--text-sm); line-height: 1.95; }
.vault {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
}
.vault__label { color: var(--color-muted); font-size: var(--text-sm); }
.vault__addr { overflow-wrap: anywhere; min-width: 0; }
.vault__addr.is-pending { color: var(--color-neutral); }

/* The payments block switches to cards by its own width, not the viewport's:
 * it is narrow on phones, and also in its column between about 960 and 1200px. */
.viz--ledger { container: ledger / inline-size; }

@container ledger (max-width: 40rem) {
  /* Each payment becomes a two-line card; roles in the markup keep it a
   * table for screen readers. */
  .ledger, .ledger caption, .ledger tbody { display: block; }
  .ledger thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .ledger tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "what what amount" "date cat receipt";
    gap: var(--space-2xs) var(--space-sm);
    padding: var(--space-sm) 0;
    border-top: var(--rule-hair) solid var(--color-rule);
  }
  .ledger tbody tr:last-child { border-bottom: var(--rule-hair) solid var(--color-rule); }
  .ledger td, .ledger tbody tr:last-child td { padding: 0; border: 0; }
  .ledger__what { grid-area: what; }
  .ledger__amount { grid-area: amount; }
  .ledger__date { grid-area: date; font-size: var(--text-sm); }
  .ledger__cat { grid-area: cat; font-size: var(--text-sm); white-space: normal; }
  .ledger__receipt { grid-area: receipt; font-size: var(--text-sm); text-align: right; }
}

@media (min-width: 60rem) {
  .treasury__head { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-2xl); }
  .kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); border-bottom: var(--rule-hair) solid var(--color-rule); }
  .kpi { padding: var(--space-lg) var(--space-lg) var(--space-lg) 0; border-bottom: 0; }
  .kpi:nth-child(even) { padding-left: 0; border-left: 0; }
  .kpi + .kpi { padding-left: var(--space-lg); border-left: var(--rule-hair) solid var(--color-rule); }
  .treasury__grid { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--space-2xl); }
  .viz--split { grid-column: 1 / -1; }
}

/* ---------------------------------------------------------------- studio */

/* The studio, line by line (js/flow.js): the treasury as a metro map. The
 * Treasury station branches into the reserve (a vault), the overheads (spurs
 * to a buffer stop) and one line per content type; a line's stops are its
 * pipeline's steps, and it ends at a platform of that channel's pieces, the
 * latest first. The data colours are the treasury's (.treasury, .metro above):
 * spending in ink (the lines), fees and the reserve in taupe (the dots riding
 * the lines, the vault). Stops are told apart by shape and by their words,
 * never by colour. Red only marks a reserve under its floor. Two layouts, by
 * the map's own width (container queries, not the viewport): lines run down
 * on phones and tablets, across on wide screens. */

.studio {
  display: grid;
  gap: var(--space-2xl);
  padding: var(--space-3xl) var(--page-gutter);
  border-top: var(--rule-hair) solid var(--color-rule);
}

.metro__head { display: grid; gap: var(--space-lg); }
.metro__titles { display: flex; flex-wrap: wrap; align-items: center; align-self: start; gap: var(--space-sm) var(--space-md); }
.metro__intro { display: grid; gap: var(--space-md); max-width: 60ch; }
.metro__lede { color: var(--color-muted); text-wrap: pretty; }
.metro__note { padding: var(--space-md) var(--space-lg); border-radius: var(--radius-md); background: var(--color-paper-2); color: var(--color-ink-soft); }
.metro__note strong { color: var(--color-ink); }
.metro__meta { color: var(--color-neutral); font-size: var(--text-sm); }
.metro.is-still .metro__pause { display: none; }
@media (min-width: 60rem) {
  .metro__head { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-2xl); }
}

/* The map's container: everything below sizes itself from its width. */
.viz--lines > .viz__chart { container: lines / inline-size; }
.metro__wrap {
  --across: 0;          /* read by flow.js: 1 when lines run across */
  --spine-col: 1.5rem;  /* the column the station's trunk runs down */
  --spine-w: 4px;
  --dot-col: 1.75rem;   /* phones: the column a line runs down */
  --board-w: 11.5rem;   /* wide: a line's name board */
  --car-h: 8.5rem;      /* a piece on a platform; the latest is bigger */
  --car-h-latest: 13.5rem;
  position: relative;
}

/* ---------------------------------------------------------------- legend */

.metro__legend { row-gap: var(--space-xs); }
.metro__key { display: inline-block; flex: none; }
.metro__key--line {
  width: 2rem;
  height: 8px;
  background:
    radial-gradient(circle, var(--flow-in) 0 3px, transparent 3.5px) 5px 50% / 8px 8px no-repeat,
    radial-gradient(circle, var(--flow-in) 0 3px, transparent 3.5px) 19px 50% / 8px 8px no-repeat,
    linear-gradient(var(--flow-out), var(--flow-out)) 0 50% / 100% 4px no-repeat;
}
.metro__key--express { box-sizing: border-box; width: 0.8rem; height: 0.8rem; border: 2px solid var(--flow-out); border-radius: 50%; background: var(--flow-in); }
.metro.is-still .metro__legend-express { display: none; }
.metro__legend .metro__legend-stops { flex-wrap: wrap; column-gap: var(--space-md); }
.metro__legend-stop { display: inline-flex; align-items: center; gap: var(--space-xs); }

/* Stops: a filled circle is paid, an open one is free (the studio's own
 * code), a bar is where it's posted, across the line. */
.metro__dot {
  display: block;
  flex: none;
  box-sizing: border-box;
  width: 0.875rem;
  height: 0.875rem;
  border: 3px solid var(--flow-out);
  border-radius: 50%;
  background: var(--color-paper);
  transition: scale var(--dur-micro) var(--ease-out), box-shadow var(--dur-short) var(--ease-out);
}
.metro__dot--provider { width: 1rem; height: 1rem; border: 0; background: var(--flow-out); box-shadow: 0 0 0 2px var(--color-paper); }
.metro__dot--platform { width: 1.25rem; height: 0.375rem; border: 0; border-radius: 2px; background: var(--flow-out); box-shadow: 0 0 0 2px var(--color-paper); }

/* ------------------------------------------------------------------- map */

.metro__map { display: grid; gap: var(--space-lg); margin: 0; padding: 0; list-style: none; }

/* The station's trunk runs down the left, under every line's start. */
.metro__spine {
  position: absolute;
  left: calc((var(--spine-col) - var(--spine-w)) / 2);
  z-index: 2;
  box-sizing: border-box;
  width: var(--spine-w);
  border-radius: var(--radius-pill);
  background: var(--color-ink);
  pointer-events: none;
}

.metro__row { position: relative; display: grid; grid-template-columns: var(--spine-col) minmax(0, 1fr); row-gap: var(--space-xs); }
.metro__row > :not(.metro__rail, .metro__express) { position: relative; z-index: 1; grid-column: 2; min-width: 0; }
/* A hairline between lines, kept off the trunk. */
.metro__row--line::before, .metro__row--planned::before, .metro__row--shelf::before {
  content: "";
  position: absolute;
  top: calc(-0.5 * var(--space-lg));
  right: 0;
  left: calc(var(--spine-col) + var(--space-sm));
  height: 1px;
  background: var(--chart-grid);
}

.metro__rail { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.metro__line { fill: none; stroke: var(--flow-out); stroke-linecap: round; stroke-linejoin: round; }
.metro__line.is-zero { stroke: var(--color-neutral); stroke-dasharray: 1 5; }
/* The reserve isn't spent, so it doesn't leave on a line: a dashed siding. */
.metro__line--vault { stroke: var(--flow-in); stroke-dasharray: 3 4; stroke-linecap: butt; }
.metro__arrow { fill: var(--flow-out); }
.metro__arrow.is-zero { fill: var(--color-neutral); }
.metro__coins { fill: none; stroke: var(--flow-in); stroke-linecap: round; }

/* A replayed payment on its way to the step it paid for. */
.metro__express {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 3;
  box-sizing: border-box;
  width: 0.875rem;
  height: 0.875rem;
  margin: -0.4375rem 0 0 -0.4375rem;
  border: 2px solid var(--flow-out);
  border-radius: 50%;
  background: var(--flow-in);
  box-shadow: 0 0 0 2px var(--color-paper);
  pointer-events: none;
  will-change: transform;
}

/* The station: the sign, everything collected, and where it all went. */
.metro__row--station { z-index: 3; }
.metro__row--station > .metro__station { grid-column: 1 / -1; }
/* The sign starts at the edge, over the trunk; the figure, when it wraps
 * under the sign, starts past the trunk instead of on it. */
.metro__station { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2xs) var(--space-md); padding-left: var(--spine-col); }
.metro__sign {
  display: inline-flex;
  align-items: center;
  margin-left: calc(-1 * var(--spine-col));
  min-height: 2.75rem;
  padding: 0 var(--space-lg);
  border-radius: var(--radius-pill);
  background: var(--color-ink);
  box-shadow: 0 0 0 4px var(--color-paper);
  color: var(--color-paper);
  font-size: var(--text-md);
  letter-spacing: -0.01em;
  transition: box-shadow var(--dur-short) var(--ease-out);
}
.metro__sign.is-landed { box-shadow: 0 0 0 4px var(--color-paper), 0 0 0 7px var(--flow-in); }

.metro__overview { display: grid; gap: var(--space-sm); margin-top: var(--space-xs); }
.metro__split { display: flex; gap: 2px; height: 0.875rem; }
.metro__seg { flex: 1 1 0; min-width: 2px; background: var(--flow-out); }
.metro__seg.is-kept { background: var(--flow-in); }
.metro__seg:first-child { border-radius: 4px 0 0 4px; }
.metro__seg:last-child { border-radius: 0 4px 4px 0; }
.metro__sums { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-2xs) var(--space-lg); }
.metro__sum { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.15rem 0.3em; color: var(--color-muted); font-size: var(--text-sm); }
.metro__sum b { color: var(--color-ink); font-size: var(--text-base); }
.metro__sum .key { margin-right: 0.2rem; }
.metro__sum .kpi__sample, .metro__dep .kpi__sample, .metro__vault-fact .kpi__sample { margin-left: var(--space-2xs); }
.metro__dep-head { padding-top: var(--space-xs); color: var(--color-muted); font-size: var(--text-sm); }

/* The departures board: every branch, its share of everything collected
 * and its SOL, in the map's order. */
/* One grid for the whole board: each row is a subgrid of it, so the shares,
 * the amounts and the tags line up in columns. */
.metro__departures {
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr) auto auto auto;
  column-gap: var(--space-xs);
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: var(--rule-hair) solid var(--color-rule);
}
.metro__dep {
  display: grid;
  grid-column: 1 / -1;
  grid-template-columns: subgrid;
  align-items: center;
  min-height: 2.35rem;
  padding: 0.25rem 0;
  border-bottom: var(--rule-hair) solid var(--color-rule);
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.metro__dep-name { color: var(--color-ink); line-height: 1.3; overflow-wrap: break-word; }
.metro__dep-share { color: var(--color-ink); font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.metro__dep-sol { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.metro__dep-sol b { color: var(--color-ink); }
.metro__dep.is-zero :is(.metro__dep-share, .metro__dep-sol b) { color: var(--color-muted); font-weight: 400; }
.metro__dep > .metro__num { justify-self: start; }
.metro__dep-key { justify-self: start; width: 1.2rem; height: 5px; margin-left: 0.2rem; border-radius: 3px; background: var(--flow-out); }
.metro__dep-key.is-kept { width: 0.85rem; height: 0.85rem; margin-left: 0.35rem; border-radius: 2px; background: var(--flow-in); }

/* Boards: a line's name, its share of everything collected and its SOL. */
.metro__board { display: grid; align-content: start; row-gap: 0.15rem; }
.metro__board-top { display: grid; gap: 0.15rem; justify-items: start; min-width: 0; }
.metro__name { display: flex; align-items: center; gap: var(--space-xs); min-width: 0; font-size: var(--text-base); line-height: 1.3; letter-spacing: -0.01em; }
.metro__name > span:last-child { min-width: 0; overflow-wrap: break-word; }
.metro__num {
  display: inline-grid;
  flex: none;
  place-items: center;
  min-width: 1.6rem;
  height: 1.6rem;
  padding: 0 0.3rem;
  border: 2px solid var(--color-ink);
  border-radius: var(--radius-pill);
  color: var(--color-ink);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  line-height: 1;
}
.metro__fig { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.3em; color: var(--color-muted); font-size: var(--text-sm); }
.metro__fig b { color: var(--color-ink); font-size: var(--text-base); font-weight: 700; }
.metro__fig-sol, .metro__fig-share { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0 0.3em; }
.metro__board .metro__fig { display: grid; justify-items: start; gap: 0.05rem; }
.metro__fig .kpi__sample { margin-left: var(--space-2xs); }
.metro__detail { color: var(--color-muted); font-size: var(--text-sm); line-height: 1.4; text-wrap: pretty; overflow-wrap: break-word; }

/* Marks: focusable stand-ins with a full aria-label; the tooltip repeats it. */
.metro [role="img"] { border-radius: var(--radius-sm); cursor: default; }
.metro [role="img"]:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 3px; }

/* Stops */
.metro__stops { display: grid; margin: 0; padding: 0; list-style: none; }
.metro__stop-item { position: relative; min-width: 0; }
.metro__label > * { min-width: 0; max-width: 100%; }
.metro__stop { position: relative; display: grid; min-width: 0; }
.metro__label { display: grid; gap: 0.05rem; min-width: 0; font-size: var(--text-sm); line-height: 1.3; }
.metro__label b { color: var(--color-ink); font-size: 0.875rem; overflow-wrap: break-word; }
.metro__tool { color: var(--color-muted); overflow-wrap: break-word; }
/* A step's cost: its SOL and Sample tag on one row, its share of the line
 * under them. A grid, so it is as wide as its widest row, not the sum of them. */
.metro__cost { display: grid; grid-template-columns: auto auto; align-items: center; justify-content: end; justify-items: end; gap: 0.1rem 0.35rem; color: var(--color-ink); font-size: var(--text-sm); }
.metro__cost.is-free { grid-template-columns: auto; }
.metro__amount { white-space: nowrap; }
.metro__cost.is-free, .metro__cost.is-zero { color: var(--color-neutral); }
.metro__cost.is-zero b { font-weight: 400; }
.metro__share { grid-column: 1 / -1; display: flex; flex-wrap: wrap; justify-content: flex-end; column-gap: 0.25em; color: var(--color-muted); font-size: 0.75rem; line-height: 1.3; text-align: right; white-space: nowrap; }
.metro__stop:hover .metro__dot, .metro__stop:focus-visible .metro__dot { scale: 1.2; }
/* Where a replayed payment lands: a ring on the stop, and its receipt. */
.metro__stop.is-landed .metro__dot { scale: 1.25; box-shadow: 0 0 0 2px var(--color-paper), 0 0 0 4.5px var(--flow-in); }

.metro__receipt {
  position: absolute;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.1rem 0.35rem;
  width: max-content;
  padding: 0.2rem 0.55rem;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  background: var(--color-paper);
  box-shadow: var(--shadow-whisper);
  color: var(--color-muted);
  font-size: 0.75rem;
  line-height: 1.35;
  pointer-events: none;
  animation: metro-receipt var(--dur-short) var(--ease-out);
}
.metro__receipt b { color: var(--color-ink); white-space: nowrap; }
.metro__receipt .kpi__sample { font-size: 0.6rem; }
@keyframes metro-receipt { from { opacity: 0; } }
/* A receipt in a station's or a spur's line of words stands in for them. */
.metro__said-slot { position: relative; min-width: 0; }
.metro__said-slot .metro__receipt { top: 50%; left: 0; max-width: 100%; flex-wrap: nowrap; overflow: hidden; white-space: nowrap; transform: translateY(-50%); }
.metro__said-slot.has-receipt .metro__said { visibility: hidden; }

/* Spurs end at a buffer stop; a line with no pipeline yet at a barrier. */
.metro__end { display: grid; grid-template-columns: var(--dot-col) minmax(0, 1fr); align-items: center; column-gap: var(--space-xs); }
.metro__buffer { justify-self: center; width: 1.25rem; height: 0.375rem; border-radius: 2px; background: var(--flow-out); transition: box-shadow var(--dur-short) var(--ease-out); }
.metro__buffer.is-landed { box-shadow: 0 0 0 2px var(--color-paper), 0 0 0 4.5px var(--flow-in); }
.metro__barrier {
  justify-self: center;
  box-sizing: border-box;
  width: 1.5rem;
  height: 0.75rem;
  border: 1.5px solid var(--color-ink-soft);
  border-radius: 2px;
  background: repeating-linear-gradient(135deg, var(--color-ink-soft) 0 3px, var(--color-paper) 3px 6px);
}

/* The vault: the reserve, against its floor. */
.metro__vault {
  display: grid;
  gap: var(--space-2xs);
  justify-self: start;
  width: min(100%, 22rem);
  padding: var(--space-xs) var(--space-md) var(--space-sm);
  border: 2px solid var(--flow-in);
  border-radius: var(--radius-md);
  background: var(--color-paper);
}
.metro__vault .meter { padding-bottom: 1.6rem; }
.metro__vault-fact { display: flex; flex-wrap: wrap; align-items: center; gap: 0 0.3em; color: var(--color-muted); font-size: var(--text-sm); }
.metro__vault-fact b { color: var(--color-ink); }
.metro__vault.is-low .metro__vault-fact b { color: var(--color-focus); }
.metro__vault .badge { justify-self: start; }

/* -------------------------------------------------------------- platform */

.metro__platform { position: relative; min-width: 0; container-type: inline-size; }
.metro__cars {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  margin: 0;
  padding: 4px 4px var(--space-xs);
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 4px;
  scrollbar-width: thin;
  scrollbar-color: var(--color-rule) transparent;
}
/* Fades at the edges say there is more to scroll to. */
.metro__cars.has-after { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 4rem), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 4rem), transparent); }
.metro__cars.has-before { -webkit-mask-image: linear-gradient(to right, transparent, #000 2.5rem); mask-image: linear-gradient(to right, transparent, #000 2.5rem); }
.metro__cars.has-before.has-after {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 2.5rem, #000 calc(100% - 4rem), transparent);
  mask-image: linear-gradient(to right, transparent, #000 2.5rem, #000 calc(100% - 4rem), transparent);
}

.metro__car { --h: var(--car-h); flex: none; width: min(calc(var(--h) * var(--r)), 82cqi); scroll-snap-align: start; }
.metro__car.is-tall { --h: calc(var(--car-h) * 1.3); }
.metro__car.is-wide { --h: calc(var(--car-h) * 0.85); }
.metro__car.is-latest { --h: var(--car-h-latest); }
.metro__car.is-latest.is-tall { --h: calc(var(--car-h-latest) * 1.3); }
.metro__car.is-latest.is-wide { --h: calc(var(--car-h-latest) * 0.85); }
.metro__piece { display: grid; margin: 0; }
.metro__frame { position: relative; overflow: hidden; aspect-ratio: var(--r); border-radius: var(--radius-sm); background: var(--color-paper-2); }
.metro__car.is-latest .metro__frame { box-shadow: 0 0 0 2px var(--color-paper), 0 0 0 4px var(--color-ink); }
.metro__frame img, .metro__frame video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Over the picture and any player (which follows it in the markup, so its
 * controls follow it in the Tab order). */
.metro__play, .metro__open {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  cursor: pointer;
}
.metro__open { cursor: zoom-in; }
.metro__play:focus-visible, .metro__open:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -4px; }
/* A still's picture is inside its button: it goes under the button's focus
 * ring (the button is its own stacking context, z-index 1). */
.metro__open img { z-index: -1; }
/* A video that has started keeps its own controls for the mouse and touch.
 * Its play button stays on top as its keyboard handle: out of the pointer's
 * way, and out of sight unless it has keyboard focus. */
.metro__car--video.has-media .metro__play { pointer-events: none; }
.metro__car--video.has-media .metro__play .metro__icon { opacity: 0; }
.metro__car--video.has-media .metro__play:focus-visible .metro__icon { opacity: 1; }
.metro__frame video:focus-visible { outline-offset: -4px; }
/* A piece whose file won't load says so. */
.metro__missing {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  max-width: calc(100% - 1rem);
  padding: 0.2rem 0.6rem;
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: 1.3;
  text-align: center;
  translate: -50% -50%;
  pointer-events: none;
}
.metro__car.is-missing .metro__icon { display: none; }
.metro__car.is-missing :is(.metro__play, .metro__open) { cursor: default; }
/* A paper play disc: light on the warm paper, an ink triangle. */
.metro__icon {
  position: relative;
  display: block;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: color-mix(in oklch, var(--color-paper) 88%, transparent);
  box-shadow: 0 6px 16px -8px oklch(20% 0.01 50 / 0.5), 0 0 0 1px color-mix(in oklch, var(--color-ink) 10%, transparent);
  transition: scale var(--dur-micro) var(--ease-out), opacity var(--dur-short) var(--ease-out);
}
.metro__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  border-width: 0.5rem 0 0.5rem 0.8rem;
  border-style: solid;
  border-color: transparent transparent transparent var(--color-ink);
  translate: -35% -50%;
}
.metro__car.is-playing .metro__icon::after {
  width: 0.7rem;
  height: 0.85rem;
  border: 0;
  background: linear-gradient(to right, var(--color-ink) 0 33%, transparent 33% 67%, var(--color-ink) 67%);
  translate: -50% -50%;
}
@media (hover: hover) { .metro__play:hover .metro__icon { scale: 1.08; } }
/* Loops keep a small control in the corner, out of sight while they play
 * until it's hovered or focused, so the loop itself shows. */
.metro__play--loop { place-items: end; padding: 0.375rem; }
.metro__play--loop .metro__icon { width: 1.75rem; height: 1.75rem; }
.metro__play--loop .metro__icon::after { border-width: 0.3rem 0 0.3rem 0.5rem; }
.metro__car.is-playing .metro__play--loop .metro__icon { opacity: 0; }
.metro__car.is-playing .metro__play--loop .metro__icon::after { width: 0.45rem; height: 0.55rem; }
.metro__car.is-playing .metro__play--loop:hover .metro__icon, .metro__car.is-playing .metro__play--loop:focus-visible .metro__icon { opacity: 1; }

/* An answer from a stream: no picture, so a voice note. */
.metro__wave { position: absolute; inset: 24% 14%; display: flex; align-items: center; justify-content: space-between; }
.metro__wave span { width: 6%; height: calc(var(--n) * 10%); border-radius: 2px; background: var(--color-neutral); opacity: 0.45; }
.metro__car--audio.is-playing .metro__wave span { animation: metro-talk 0.7s var(--ease-in-out) infinite alternate; animation-delay: calc(var(--n) * -70ms); }
@keyframes metro-talk { from { scale: 1 0.45; } }
.metro__progress { position: absolute; right: 0; bottom: 0; left: 0; height: 3px; background: var(--color-rule); }
.metro__progress span { display: block; width: 0; height: 100%; background: var(--color-ink); }

.metro__cap { display: grid; gap: 0.1rem; min-width: 0; padding-top: var(--space-xs); font-size: var(--text-sm); line-height: 1.35; }
.metro__latest {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: var(--space-2xs);
  color: var(--color-accent-ink);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.metro__latest::before { content: ""; width: 0.4rem; height: 0.4rem; border-radius: var(--radius-pill); background: var(--color-accent); }
.metro__ptitle { display: -webkit-box; overflow: hidden; color: var(--color-ink); font-weight: 700; overflow-wrap: anywhere; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.metro__pmeta, .metro__pnote { overflow: hidden; color: var(--color-muted); text-overflow: ellipsis; white-space: nowrap; }
.metro__hint { padding: 0 4px; color: var(--color-neutral); font-size: 0.75rem; }

/* Arrows ride on the platform, level with the latest piece. */
.metro__row { --lead: var(--car-h-latest); }
.metro__row.is-tall { --lead: calc(var(--car-h-latest) * 1.3); }
.metro__row.is-wide { --lead: calc(var(--car-h-latest) * 0.85); }
.metro__navs { position: absolute; top: calc(4px + var(--lead) / 2); right: -0.25rem; left: -0.25rem; z-index: 2; display: flex; justify-content: space-between; translate: 0 -50%; pointer-events: none; }
.metro__nav {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: var(--rule-hair) solid var(--color-ink-soft);
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  box-shadow: var(--shadow-whisper);
  color: var(--color-ink);
  line-height: 1;
  cursor: pointer;
  pointer-events: auto;
  transition: background-color var(--dur-short) var(--ease-out), opacity var(--dur-short) var(--ease-out);
}
@media (hover: hover) { .metro__nav:hover:not(:disabled) { background: var(--color-paper-2); } }
.metro__nav:disabled { opacity: 0; pointer-events: none; }

/* An empty platform: the channel's own line about what's coming. */
.metro__empty { display: grid; align-content: center; gap: var(--space-2xs); min-height: 7rem; padding: var(--space-md) var(--space-lg); border-radius: var(--radius-md); background: var(--color-paper-2); }
.metro__empty-title { font-weight: 700; }
.metro__empty-text { max-width: 46ch; color: var(--color-ink-soft); }
.metro__empty-meta { color: var(--color-muted); font-size: var(--text-sm); }

/* ------------------------------------------------------- the table view */

/* In place: the station's branches and each line's steps become tables;
 * the platforms stay. The drawing and its motion go. */
.metro__table { display: none; min-width: 0; }
.metro.is-table .metro__table { display: block; overflow-x: auto; }
.metro.is-table :is(.metro__legend, .metro__rail, .metro__spine, .metro__overview, .metro__stops, .metro__vault .meter, .metro__end, .metro__express, .metro__receipt, .metro__said-slot) { display: none; }
.metro__table .spec { min-width: 0; }
.metro__table .spec td, .metro__table .spec th { overflow-wrap: break-word; }
/* Headers wrap, the numeric ones too ("Share of everything collected"), so
 * the SOL column fits on a phone; the numbers themselves never break. */
.metro__table thead th, .metro__table thead th.num { white-space: normal; }
@container lines (max-width: 40rem) {
  /* Phones: each branch’s board already says what it is. */
  .metro__table--branches :is(th, td):nth-child(2) { display: none; }
}
@container lines (max-width: 21rem) {
  /* The narrowest phones (and 400% zoom): a step's receipt is "SAMPLE paid
   * 0.6 SOL" (the date is in the step's tooltip), and the tables' columns are
   * tighter, so SOL still fits. */
  .metro__stop-item .metro__receipt-more { display: none; }
  .metro__table .spec :is(th, td) { padding-right: var(--space-xs); }
  .metro__table .spec :is(th, td):last-child { padding-right: 0; }
}
.metro__does { display: block; color: var(--color-muted); font-size: var(--text-sm); }

/* ------------------------------------------- phones and tablets: lines run down */

.metro__board { padding-left: var(--dot-col); }
.metro__row--shelf .metro__board { padding-left: 0; }
.metro__wrap.is-shelves { --spine-col: 0px; }
.metro__stops { max-width: 34rem; margin-top: var(--space-2xs); }
.metro__stop { grid-template-columns: var(--dot-col) minmax(0, 1fr) auto; align-items: center; column-gap: var(--space-xs); min-height: 2.35rem; padding: 0.2rem 0; }
.metro__stop > * { grid-row: 1; }
.metro__stop .metro__dot { grid-column: 1; justify-self: center; }
.metro__label { grid-column: 2; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.4rem; }
.metro__cost { grid-column: 3; }
/* A step's receipt sits just under its name, which stays, and stops short
 * of its cost (flow.js measures where): "SAMPLE 0.6 SOL paid · 4 Oct". */
.metro__stop-item .metro__receipt { top: var(--y, 100%); left: var(--x, calc(var(--dot-col) + var(--space-xs))); max-width: var(--w, calc(100% - var(--dot-col) - 7rem)); overflow: hidden; flex-wrap: nowrap; column-gap: 0.3rem; padding: 0 0.35rem; font-size: 0.7rem; line-height: 1.3; white-space: nowrap; }
.metro__stop-item .metro__receipt .kpi__sample { line-height: 1.3; }
/* On one line, the tag and "paid 0.6 SOL" keep their room; what follows gives way. */
.metro__receipt-paid { white-space: nowrap; }
.metro__receipt-more { min-width: 0; }
:is(.metro__stop-item, .metro__said-slot) .metro__receipt-more { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.metro__receipt-item { display: none; }
.metro__said-slot .metro__receipt-item { display: inline; }
.metro__platform { margin-top: var(--space-xs); }
.metro__end, .metro__vault { margin-top: var(--space-2xs); }
.metro__row--vault .metro__vault { margin-left: var(--dot-col); }
.metro__row--vault .metro__vault { width: auto; max-width: 22rem; justify-self: stretch; }

/* ------------------------------------------- wide screens: lines run across */

@container lines (min-width: 64rem) {
  .metro__wrap { --across: 1; --spine-col: 3rem; --spine-w: 1.5rem; --car-h: 9rem; --car-h-latest: 14rem; }
  .metro__spine { border: 3px solid var(--color-ink); background: var(--color-paper); }
  .metro__map { gap: var(--space-xl); }
  .metro__row--line::before, .metro__row--planned::before, .metro__row--shelf::before { top: calc(-0.5 * var(--space-xl)); }

  .metro__departures { grid-template-columns: 1.9rem minmax(0, 1fr) auto auto auto var(--space-lg) 1.9rem minmax(0, 1fr) auto auto auto; max-width: 66rem; }
  .metro__dep { grid-row: var(--r); grid-column: 1 / span 5; }
  .metro__dep.is-right { grid-column: 7 / span 5; }

  .metro__row { grid-template-columns: var(--spine-col) var(--board-w) minmax(0, 1.05fr) minmax(18rem, 1fr); row-gap: 0; }
  .metro__row--station, .metro__row--shelf { grid-template-columns: var(--spine-col) minmax(0, 1fr); row-gap: var(--space-xs); }
  .metro__row--shelf { grid-template-columns: var(--spine-col) var(--board-w) minmax(0, 1fr); }
  .metro__row--shelf > .metro__platform { grid-column: 3; margin-top: 0; }
  .metro__board { padding-left: 0; }
  .metro__row > .metro__board { grid-column: 2; padding-right: var(--space-md); }

  /* Each row has a band the line runs along (row 2): the board's name and
   * figure sit above it and its words below, as does every stop's. The band
   * sits level with the middle of the latest piece, and moves down for a
   * label too tall to fit above it. */
  .metro__row--line { --rail-y: calc(4px + var(--lead) / 2); grid-template-rows: minmax(calc(var(--rail-y) - 0.5rem), auto) 1rem auto minmax(3rem, 1fr); }
  .metro__row--vault, .metro__row--spur, .metro__row--planned { grid-template-rows: auto minmax(1rem, auto) auto 1fr; }
  .metro__row--line > .metro__board, .metro__row--vault > .metro__board, .metro__row--spur > .metro__board, .metro__row--planned > .metro__board { grid-row: 1 / 4; grid-template-rows: subgrid; }
  .metro__board-top { grid-row: 1; align-self: end; padding-bottom: 0.45rem; }
  .metro__board > .metro__detail { grid-row: 3; align-self: start; padding-top: 0.45rem; }

  /* Five steps fit from the narrowest width this layout starts at (a 64rem
   * map), "ElevenLabs" and all: no padding inside a stop, the gap between them. */
  .metro__row--line > .metro__stops { grid-column: 3; grid-row: 1 / 4; grid-template-rows: subgrid; grid-auto-columns: minmax(0, 1fr); grid-auto-flow: column; column-gap: var(--space-xs); max-width: none; margin: 0; padding-right: var(--space-md); }
  .metro__stop-item { grid-row: 1 / 4; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; }
  .metro__stop { grid-row: 1 / 4; grid-template-columns: minmax(0, 1fr); grid-template-rows: subgrid; justify-items: center; min-height: 0; padding: 0; text-align: center; }
  .metro__stop > * { grid-row: auto; }
  .metro__label { grid-row: 1; grid-column: auto; display: grid; align-self: end; padding-bottom: 0.55rem; }
  .metro__stop .metro__dot { grid-row: 2; grid-column: auto; align-self: center; }
  .metro__cost { grid-row: 3; grid-column: auto; grid-template-columns: auto; align-self: start; justify-content: center; justify-items: center; padding-top: 0.55rem; }
  .metro__share { display: flex; flex-wrap: wrap; justify-content: center; column-gap: 0.25em; text-align: center; white-space: nowrap; }
  .metro__dot--platform { width: 0.375rem; height: 1.25rem; }
  .metro__stop-item .metro__receipt { top: calc(100% + 0.5rem); left: 50%; max-width: 24rem; overflow: visible; flex-wrap: wrap; column-gap: 0.35rem; padding: 0.2rem 0.55rem; font-size: 0.75rem; line-height: 1.35; white-space: normal; transform: translateX(calc(-50% + var(--shift, 0px))); }
  .metro__stop-item .metro__receipt .kpi__sample { line-height: 1.5; }
  .metro__stop-item .metro__receipt-more { overflow: visible; white-space: normal; }
  .metro__receipt-item { display: inline; }
  .metro__row--line > .metro__table { grid-column: 3; grid-row: 1 / -1; padding-right: var(--space-lg); }
  .metro__row--line > .metro__platform, .metro__row--planned > .metro__platform { grid-column: 4; grid-row: 1 / -1; margin-top: 0; }
  .metro__row--line .metro__empty, .metro__row--planned .metro__empty { min-height: var(--car-h-latest); }

  .metro__end { grid-template-columns: auto minmax(0, 1fr); justify-self: start; margin-top: 0; column-gap: var(--space-sm); }
  .metro__buffer { width: 0.375rem; height: 1.25rem; }
  .metro__row--spur > .metro__end { grid-column: 3 / -1; grid-row: 2; align-self: center; justify-self: stretch; }
  .metro__row--planned > .metro__end { grid-column: 3; grid-row: 2; align-self: center; margin-left: 0; }
  .metro__row--vault > .metro__vault { grid-column: 3; grid-row: 2 / -1; align-self: start; width: min(100%, 22rem); margin: calc(0.5rem - 2px - var(--space-xs) - 0.375rem - 0.4375rem) 0 0; }
}

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

@media (prefers-reduced-motion: reduce) {
  .metro__car--audio.is-playing .metro__wave span { animation: none; }
}
.metro.is-still .metro__car--audio.is-playing .metro__wave span { animation: none; }

/* --------------------------------------------------------------- socials */

.socials {
  display: grid;
  gap: var(--space-md);
  padding: var(--space-3xl) var(--page-gutter) var(--space-4xl);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.socials__lede { max-width: 45ch; color: var(--color-muted); }
.socials__list { display: flex; flex-wrap: wrap; gap: var(--space-sm); padding-top: var(--space-sm); }

.chip {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-xs);
  min-height: 2.75rem;
  padding: var(--space-sm) var(--space-md);
  border: var(--rule-hair) solid var(--color-rule-strong);
  border-radius: var(--radius-sm);
  font-weight: 700;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
a.chip:hover { background: var(--color-paper-2); }
a.chip:active { transform: translateY(1px); }
a.chip::after { content: "↗"; font-weight: 400; }
.chip.is-soon { border-color: var(--color-rule); color: var(--color-muted); cursor: default; }
.chip__state { color: var(--color-neutral); font-size: var(--text-sm); font-weight: 400; }

@media (min-width: 60rem) {
  .socials { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); column-gap: var(--space-2xl); }
  .socials__title, .socials__lede { grid-column: 1; }
  .socials__list { grid-column: 2; grid-row: 1 / span 2; align-self: start; padding-top: 0; }
}

/* ---------------------------------------------------------------- footer */

.foot {
  display: grid;
  gap: var(--space-2xl);
  padding: var(--space-3xl) var(--page-gutter) var(--space-xl);
  background: var(--color-paper-2);
}
.foot__line {
  max-width: 13ch;
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.035em;
  overflow-wrap: anywhere;
  min-width: 0;
}
.foot__meta {
  display: grid;
  gap: var(--space-md);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule-strong);
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.foot .wordmark { color: var(--color-ink); }
.foot__legal { max-width: 72ch; }

@media (min-width: 60rem) {
  .foot__meta { grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline; gap: var(--space-xl); }
}

/* -------------------------------------------------------------- lightbox */

.lightbox {
  width: min(92vw, 28rem);
  max-height: 94dvh;
  padding: 0;
  border: 0;
  background: transparent;
  color: oklch(94% 0.007 72); /* on the dark backdrop, in either theme */
  overflow: visible;
}
.lightbox[open] { animation: lightbox-in var(--dur-long) var(--ease-out); }
/* Always a dim room behind the still, light theme or dark (ink would turn light in the dark theme). */
.lightbox::backdrop { background: oklch(14% 0.008 50 / 0.86); }
.lightbox__img { width: 100%; max-height: 84dvh; object-fit: contain; border-radius: var(--radius-md); }
.lightbox__caption { padding-top: var(--space-xs); }
.lightbox__close {
  position: absolute;
  top: var(--space-xs);
  right: var(--space-xs);
  min-height: 2.25rem;
  padding: 0 var(--space-sm);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  color: var(--color-ink);
  font-size: var(--text-sm);
  line-height: 1;
  cursor: pointer;
}
.lightbox__close:active { transform: translateY(1px); }
@keyframes lightbox-in { from { opacity: 0; transform: scale(0.96); } }

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 150ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 150ms !important;
  }
}

/* ---- community: idea box, made from your ideas, reactions */

/* js/community.js draws the idea box (#ideas) and "Made from your ideas"
 * (#made) right after the studio, and like and dislike under every piece.
 * The studio's section shell, head grid and title; hairline-ruled lists;
 * Geist Mono only for numbers and small uppercase labels; the accent only
 * as a highlighter (a dot, an underline), never a fill. */

.ideas, .made {
  display: grid;
  gap: var(--space-2xl);
  padding: var(--space-3xl) var(--page-gutter);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.ideas__head, .made__head { display: grid; gap: var(--space-lg); }
.ideas__titles, .made__titles { display: flex; flex-wrap: wrap; align-items: center; align-self: start; gap: var(--space-sm) var(--space-md); }
.ideas__title, .made__title {
  font-size: var(--text-xl);
  line-height: 1.06;
  letter-spacing: -0.025em;
  overflow-wrap: anywhere;
  min-width: 0;
}
.ideas__intro, .made__intro { display: grid; gap: var(--space-md); max-width: 60ch; }
.ideas__lede, .made__lede { color: var(--color-muted); text-wrap: pretty; }

/* The box: the form, then the ideas (side by side on wide screens). */
.ideas__body { display: grid; gap: var(--space-2xl); align-items: start; }

.ideas__form {
  position: relative;
  display: grid;
  gap: var(--space-sm);
  min-width: 0;
  padding: var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
}
.ideas__top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-2xs) var(--space-md); }
.ideas__label { font-weight: 700; }
.ideas__count { color: var(--color-neutral); font-family: var(--font-mono); font-size: var(--text-sm); font-variant-numeric: tabular-nums; }
.ideas__count.is-near { color: var(--color-accent-ink); }
.ideas__input {
  display: block;
  width: 100%;
  min-height: 7.5rem;
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border: var(--rule-hair) solid var(--color-rule-strong);
  border-radius: var(--radius-md);
  background: var(--color-paper);
  color: var(--color-ink);
  font: inherit;
  line-height: 1.45;
  resize: vertical;
}
.ideas__input::placeholder { color: var(--color-muted); opacity: 1; }
.ideas__input[aria-invalid="true"] { border-color: var(--color-focus); box-shadow: 0 0 0 1px var(--color-focus); }
.ideas__input:read-only { color: var(--color-muted); }
.ideas__fine { color: var(--color-muted); font-size: var(--text-sm); text-wrap: pretty; }
.ideas__check { min-height: 4.1rem; }
.ideas__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-sm) var(--space-md); padding-top: var(--space-2xs); }
.ideas__send[aria-disabled="true"] { border-color: var(--color-rule); background: var(--color-paper); color: var(--color-neutral); cursor: progress; transform: none; }
/* The reply, with an accent dot that hangs beside it when it wraps. */
.ideas__status { display: grid; flex: 1 1 12rem; grid-template-columns: auto minmax(0, 1fr); align-items: start; column-gap: var(--space-xs); min-width: 0; color: var(--color-ink); line-height: 1.4; text-wrap: pretty; }
.ideas__status::before {
  content: "";
  width: 0.45rem;
  height: 0.45rem;
  margin-top: 0.48em;
  border-radius: var(--radius-pill);
  background: var(--color-accent);
}
/* An empty status line stays in the page (it's a live region) but takes no room. */
.ideas__status:empty, .idea__msg:empty { position: absolute; }
.ideas__status:empty::before { content: none; }

.ideas__board { display: grid; gap: var(--space-md); min-width: 0; }
.ideas__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-xs) var(--space-md); }
.ideas__sort { display: flex; flex-wrap: wrap; gap: var(--space-xs); }
.ideas__total { color: var(--color-neutral); font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase; }
.ideas__list { display: grid; margin: 0; padding: 0; list-style: none; border-top: var(--rule-hair) solid var(--color-rule-strong); }
.ideas__list:empty { border-top: 0; }
.ideas__empty, .made__empty { max-width: 60ch; color: var(--color-muted); text-wrap: pretty; }
.ideas__more { justify-self: start; }
.ideas__more[aria-disabled="true"] { color: var(--color-neutral); cursor: progress; }
.ideas__closed {
  display: grid;
  align-content: center;
  min-height: 7rem;
  padding: var(--space-md) var(--space-lg);
  border-radius: var(--radius-md);
  background: var(--color-paper-2);
  font-weight: 700;
}

/* An idea: its votes down the left, then its title, pitch and meta. */
.idea {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: var(--space-md);
  padding: var(--space-md) 0;
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.vote { display: grid; justify-items: center; align-content: start; gap: var(--space-3xs); }
.vote__btn {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  color: var(--color-ink-soft);
  cursor: pointer;
  transition: background-color var(--dur-short) var(--ease-out), border-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .vote__btn:hover { border-color: var(--color-ink-soft); color: var(--color-ink); } }
.vote__btn:active { transform: translateY(1px); }
.vote__btn[aria-pressed="true"] { border-color: var(--color-ink); background: var(--color-ink); color: var(--color-paper); }
.vote__icon { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.vote__score { color: var(--color-ink); font-family: var(--font-mono); font-size: var(--text-sm); font-weight: 500; font-variant-numeric: tabular-nums; line-height: 1.6; }

.idea__body { display: grid; align-content: start; gap: var(--space-2xs); min-width: 0; padding-top: 0.2rem; }
.idea__title { font-size: var(--text-md); line-height: 1.25; letter-spacing: -0.01em; overflow-wrap: anywhere; text-wrap: pretty; }
.idea__pitch { color: var(--color-ink-soft); overflow-wrap: anywhere; text-wrap: pretty; }
.idea__note { color: var(--color-muted); font-size: var(--text-sm); overflow-wrap: anywhere; }
.idea__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-xs) var(--space-md); padding-top: var(--space-2xs); }
.idea__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3xs) 0.35em; color: var(--color-muted); font-size: var(--text-sm); }
.idea__status { color: var(--color-ink-soft); line-height: 1.45; }
.idea__see { min-height: 2rem; }
/* Made, with no piece on the site yet: said plainly where "See it" would be. */
.idea__later { color: var(--color-muted); font-size: var(--text-sm); }
.idea__msg { color: var(--color-accent-ink); font-size: var(--text-sm); }

/* Just sent, or found again: a moment of paper behind it and an accent
 * underline on its name. */
.idea.is-highlight::before, .made__card.is-highlight::before {
  content: "";
  position: absolute;
  inset: 0 calc(-1 * var(--space-sm));
  z-index: -1;
  border-radius: var(--radius-sm);
  animation: community-flash 2.6s var(--ease-out);
}
@keyframes community-flash { from { background-color: var(--color-paper-2); } }
.idea.is-highlight .idea__title, .made__card.is-highlight .made__name {
  text-decoration: underline;
  text-decoration-color: var(--color-accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}

/* Made from your ideas: a grid of the pieces, each with where it came from. */
.made__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr));
  gap: var(--space-xl) var(--space-lg);
  margin: 0;
  padding: 0;
  list-style: none;
}
.made__card { position: relative; isolation: isolate; display: grid; align-content: start; gap: var(--space-sm); min-width: 0; border-radius: var(--radius-sm); }
.made__card:focus-visible { outline-offset: 6px; }
/* One frame shape for every piece; the piece keeps its own (nothing cropped). */
.made__media { position: relative; overflow: hidden; aspect-ratio: 4 / 5; border-radius: var(--radius-sm); background: var(--color-paper-2); }
.made__media img, .made__media video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.made__media video:focus-visible { outline-offset: -4px; }
.made__media--audio { display: grid; align-content: end; min-height: 10rem; aspect-ratio: auto; padding: var(--space-md); }
.made__media--audio audio { position: relative; z-index: 1; width: 100%; }
.made__wave { position: absolute; inset: 18% 14% 45%; display: flex; align-items: center; justify-content: space-between; }
.made__wave span { width: 6%; height: calc(var(--n) * 10%); border-radius: 2px; background: var(--color-neutral); opacity: 0.45; }
.made__open, .made__play {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  cursor: pointer;
}
.made__open { cursor: zoom-in; }
.made__open img { z-index: -1; }
.made__open:focus-visible, .made__play:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -4px; }
/* A paper play disc with an ink triangle, as on the studio's platforms. */
.made__icon {
  position: relative;
  display: block;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--color-paper);
  box-shadow: var(--shadow-whisper), 0 0 0 1px var(--color-rule);
  transition: scale var(--dur-micro) var(--ease-out), opacity var(--dur-short) var(--ease-out);
}
.made__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  border-width: 0.5rem 0 0.5rem 0.8rem;
  border-style: solid;
  border-color: transparent transparent transparent var(--color-ink);
  translate: -35% -50%;
}
@media (hover: hover) { .made__play:hover .made__icon { scale: 1.08; } }
.made__play--loop { place-items: end; padding: var(--space-xs); }
.made__play--loop .made__icon { width: 1.75rem; height: 1.75rem; }
.made__play--loop .made__icon::after { border-width: 0.3rem 0 0.3rem 0.5rem; }
.made__media.is-playing .made__icon { opacity: 0; }
.made__media.is-playing .made__play:hover .made__icon, .made__media.is-playing .made__play:focus-visible .made__icon { opacity: 1; }
.made__media.is-playing .made__icon::after {
  width: 0.45rem;
  height: 0.55rem;
  border: 0;
  background: linear-gradient(to right, var(--color-ink) 0 33%, transparent 33% 67%, var(--color-ink) 67%);
  translate: -50% -50%;
}
.made__text { display: grid; gap: var(--space-3xs); min-width: 0; }
.made__name { font-size: var(--text-base); line-height: 1.3; overflow-wrap: anywhere; }
.made__from { color: var(--color-ink-soft); font-size: var(--text-sm); overflow-wrap: anywhere; }
.made__meta { color: var(--color-muted); font-size: var(--text-sm); }

/* Like and dislike: two small pills, a thumb and a count each. A count is
 * never cut: it is four characters at most (community.js's short()); under
 * a piece narrower than 8rem (the portrait ones, about 100px) the pills
 * tighten, so two counts up to 999 still share one row; past that the
 * dislike wraps under the like rather than lose a digit. The row's height is
 * kept while they're hidden (API down, counts not in yet), so nothing jumps. */
.metro__extra, .made__extra { container: react / inline-size; min-height: calc(1.75rem + var(--space-xs)); padding-top: var(--space-xs); }
.metro__car.is-missing .metro__extra { display: none; }
.react { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }
.react__btn {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 0.2rem;
  height: 1.75rem;
  padding: 0 0.45rem 0 0.35rem;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--color-muted);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--dur-short) var(--ease-out), color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out);
}
@media (hover: hover) { .react__btn:hover { border-color: var(--color-ink-soft); color: var(--color-ink); } }
.react__btn:active { transform: translateY(1px); }
.react__btn[aria-pressed="true"] { border-color: var(--color-ink); color: var(--color-ink); }
.react__icon { flex: none; width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linejoin: round; }
.react__btn[aria-pressed="true"] .react__icon { fill: currentColor; }
.react__n { white-space: nowrap; }
.react__n:empty { display: none; }
.react.is-error .react__btn { border-color: var(--color-accent); }
@container react (max-width: 8rem) {
  .react__btn { gap: var(--space-3xs); padding: 0 0.25rem 0 0.2rem; }
  .react__icon { width: 0.875rem; height: 0.875rem; }
}
/* Inside a platform's scroller the ring stays inside its 4px padding. */
.metro__extra .react__btn:focus-visible { outline-offset: 1px; }

/* The floating PAWS steps aside over the form, the list and the made pieces,
 * as he does over the studio's marks (the rule by the treasury's). */
body:has(#ideas [data-paws-aside]:hover, #ideas [data-paws-aside]:focus-within, #made [data-paws-aside]:hover, #made [data-paws-aside]:focus-within) .paws-canvas { opacity: 0; }

@media (min-width: 60rem) {
  .ideas__head, .made__head { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); gap: var(--space-2xl); }
  .ideas__body { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); }
  /* The form stays in reach while the list scrolls past. */
  .ideas__form { position: sticky; top: 6rem; padding: var(--space-xl); }
  .ideas__closed { grid-column: 1 / -1; }
}

@media (prefers-reduced-motion: reduce) {
  .idea.is-highlight::before, .made__card.is-highlight::before { animation: none; }
}
