/* Card content styles. Uses --card-fg/--card-accent (per-hue, AA-paired in tokens.css),
   so text contrast holds on every flood automatically. */

/* three type roles */
.kicker {
  font-family: var(--font-mono);
  font-size: var(--step-kicker);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--card-accent);
  margin: 0;
}
/* inside the dark glass panel, brighten the accent so even dark accents (maroon) stay legible */
.panel .kicker { color: color-mix(in srgb, var(--card-accent) 55%, var(--paper)); }
.display {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--step-xl);
  line-height: 1.02;
  letter-spacing: -0.02em;
  margin: 0.2em 0 0;
  text-wrap: balance;
  overflow-wrap: anywhere;            /* never let a long word/number spill */
  min-width: 0;
}

/* ---- Overture ---- */
/* NOTE: the card (not .overture) is the size container, so numbers scale to the viewport and
   stay big/expansive. Prose gets its own readable max-width; numbers can run wider. */
.overture {
  grid-template-rows: auto 1fr auto; align-content: center; gap: var(--gap);
  max-width: min(92vw, 42rem); min-width: 0;
}
.overture__head { align-self: end; min-width: 0; }
.overture .display { max-width: 14ch; }               /* keep the title punchy */
.stats { display: grid; gap: var(--gap); margin: 0; padding: 0; list-style: none; align-content: center; min-width: 0; }
.stat { display: grid; gap: 0.15rem; min-width: 0; }
.stat__num {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.5rem, 15cqi, 8rem); line-height: 0.9; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  max-width: 100%; overflow-wrap: anywhere; min-width: 0;
}
.stat__label { font-size: var(--step-l); font-weight: 700; overflow-wrap: anywhere; }
.stat__sub { font-family: var(--font-mono); font-size: var(--step-kicker); color: var(--card-accent); letter-spacing: 0.08em; }
.overture__foot { align-self: start; font-size: var(--step-body); max-width: 26ch; opacity: 0.92; margin: 0; }

/* v2 overture — the three research questions */
.overture__questions {
  display: grid; gap: 0.55rem; margin: 0; padding: 0; list-style: none;
  counter-reset: q; max-width: 34rem; min-width: 0;
}
.overture__questions li {
  counter-increment: q; display: grid; grid-template-columns: auto 1fr; gap: 0.7rem;
  font-size: var(--step-body); opacity: 0.95; overflow-wrap: anywhere;
}
.overture__questions li::before {
  content: counter(q); font-family: var(--font-mono); font-size: var(--step-kicker);
  color: var(--card-accent); letter-spacing: 0.08em; padding-top: 0.2em;
}

/* v2 overture — questions-first compact variant (fits ~700px-tall laptop screens):
   slightly smaller display, questions are the PRIMARY content (largest after the title),
   numbers shrink to a strip */
.overture--compact .display { font-size: clamp(1.9rem, 8cqi, 3.2rem); }
/* rows: header / questions / foot / stats / window — the v1 `auto 1fr auto` template let the
   questions row STRETCH on tall phone screens (1fr row balloons, lis stretch, giant gaps).
   Compact variant hugs content instead: every row auto-sized. */
.overture--compact { grid-template-rows: none; gap: 1rem; align-content: safe center; }
.overture--compact .overture__questions { gap: 0.35rem; max-width: 30rem; }             /* tight WITHIN the list */
.overture--compact .overture__questions li {
  font-size: clamp(1.05rem, 4.2cqi, 1.45rem); font-weight: 600; line-height: 1.28;
  align-items: baseline;   /* number sits on the same baseline as the first text line */
}
.overture--compact .overture__questions li::before {
  font-size: 1.5em; line-height: 1;   /* no extra leading → baseline aligns with the text */
}
/* phones: the 4.2cqi clamp bottoms out → each question wraps to 3 tall lines. Tighten
   the list there so the numbered block doesn't sprawl. */
@media (max-width: 700px) {
  .overture--compact .overture__questions { gap: 0.25rem; max-width: none; }
  .overture--compact .overture__questions li { font-size: 1rem; line-height: 1.22; }
}
.overture--compact .stats {
  grid-template-columns: 1fr 1fr; gap: 0 2rem; align-content: end;
}
.overture--compact .stat__num {
  font-size: clamp(1.2rem, 4.5cqi, 1.8rem); line-height: 1;
}
.overture--compact .stat__label { font-size: var(--step-body); }
.overture--compact .overture__foot { font-size: var(--step-kicker); max-width: 44rem; opacity: 0.8; line-height: 1.4; }
.overture--compact .stats .stat { gap: 0.1rem; }

/* ---- Beat (generic panel card) ---- */
.beat { place-items: center; }
.beat[data-align="end"] { align-items: end; }      /* panel low; map marker (e.g. TL pin) shows above */
.beat[data-align="start"] { align-items: start; }
.beat .panel { display: grid; gap: 0.6rem; }
/* v2: bullet-list beat panels run wider — fewer wrapped lines, panels stay short on laptops */
.beat:has(.beat__items) .panel { inline-size: min(56ch, 100%); max-height: 100%; overflow-y: auto; align-content: start; }
.beat .display { font-size: var(--step-l); }
.beat__stat { display: grid; gap: 0.1rem; margin: 0.4rem 0 0; min-width: 0; }
.beat__stat .stat__num { font-size: clamp(2rem, 26cqi, 4.5rem); }   /* cqi = panel width */
.beat__body { margin: 0.4rem 0 0; font-size: var(--step-body); opacity: 0.92; overflow-wrap: anywhere; }

/* v2 bullet lists inside beat panels — mono counter, bold lead-in, staggered fly-in.
   Wider than the default 38ch panel: bullets wrap less, panels stay short on laptop screens. */
.beat__items { display: grid; gap: 0.55rem; margin: 0.5rem 0 0; padding: 0; list-style: none; counter-reset: b; min-width: 0; }
.beat__items > li {
  counter-increment: b; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.65rem;
  align-items: baseline;   /* counter sits on the first text line's baseline */
  font-size: var(--step-body); line-height: 1.4; opacity: 0.95; overflow-wrap: anywhere;
}
.beat__items > li::before {
  content: counter(b, decimal-leading-zero); font-family: var(--font-mono);
  font-size: var(--step-kicker); color: var(--card-accent); letter-spacing: 0.08em;
}
.beat__items strong { font-weight: 700; margin-right: 0.35em; }

/* ---- v2 bar-pair (Insight 1: Bayview vs Mission) ---- */
.barpair__panel { display: grid; gap: 0.55rem; padding-block: clamp(1rem, 2.5vw, 1.5rem); overflow-y: auto; inline-size: min(52ch, 100%); align-self: end; }
.barpair__panel .display { font-size: clamp(1.4rem, 5.5cqi, 2.4rem); }
.barpair__panel .beat__body { margin-top: 0.2rem; font-size: var(--step-kicker); }
.barpair__legend { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.barpair__chip {
  font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.08em;
  padding: 0.2em 0.7em; border-radius: 999px;
}
.barpair__chip--a { background: color-mix(in srgb, var(--card-accent) 25%, transparent); }
.barpair__chip--b { background: color-mix(in srgb, var(--card-fg) 18%, transparent); }
.barpair__row { display: grid; gap: 0.3rem; min-width: 0; }
/* the "same" row sits quiet and compact; the 311 row is the argument — bigger, louder */
.barpair__row--same .barpair__zone { height: 0.95rem; opacity: 0.82; }
.barpair__row--same .barpair__label { opacity: 0.65; }
.barpair__row--hero {
  margin-top: 0.55rem; padding-top: 0.55rem;
  border-top: 1px solid color-mix(in srgb, var(--card-fg) 22%, transparent);
}
.barpair__row--hero .barpair__label { opacity: 1; font-weight: 700; }
.barpair__row--hero .barpair__zone { height: 1.7rem; }
.barpair__row--hero .barpair__num { font-size: var(--step-body); }
.barpair__label { margin: 0; font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.1em; text-transform: uppercase; opacity: 0.85; }
.barpair__bars {
  display: grid; grid-template-columns: minmax(2rem, 1fr) max-content max-content;
  gap: 0.25rem 0.6rem; min-width: 0; align-items: center;
}
/* both bars share ONE grid (tracks are display:contents rows): the count/tag columns size to
   the widest cell across BOTH bars, so the two 1fr zones are exactly equal and fill %s are
   true proportions — and text can never be clipped; the bar shrinks instead. */
.barpair__track { display: contents; }
/* the plot zone: the fill grows inside the shared 1fr zone, width % is exact */
.barpair__zone { position: relative; width: 100%; height: 1.35rem; }
.barpair__zone .barpair__fill { position: absolute; inset-block: 0; left: 0; width: 0%; min-width: 0; }
.barpair__fill { height: 100%; border-radius: 3px; width: 0%; }
.barpair__track--a .barpair__fill { background: var(--card-accent); }
.barpair__track--b .barpair__fill { background: color-mix(in srgb, var(--card-fg) 72%, transparent); }
/* per-bar hood tag — color + name, no deduction needed */
.barpair__tag {
  font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.08em; text-transform: uppercase;
  opacity: 0.75; white-space: nowrap;
}
.barpair__num {
  font-variant-numeric: tabular-nums; font-weight: 700; font-size: var(--step-kicker);
  white-space: nowrap;
}
.insight-transition {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: grid;
  place-items: center;
  padding: var(--pad);
  border: 0;
  color: var(--paper);
  background: color-mix(in srgb, var(--ink) 44%, transparent);
  backdrop-filter: blur(14px);
  cursor: pointer;
  font: inherit;
}
.insight-transition span {
  max-inline-size: min(18ch, 100%);
  font-family: var(--font-display);
  font-size: clamp(2rem, 9cqi, 5.5rem);
  font-weight: 800;
  line-height: 1.02;
  text-align: center;
  text-wrap: balance;
}
.insight-transition:hover,
.insight-transition:focus-visible {
  background: color-mix(in srgb, var(--ink) 36%, transparent);
}
.insight-transition[hidden] { display: none; }

/* ---- v2 timeline (Insight 2: one block, both records, one time axis) ---- */
.timeline__panel { display: grid; gap: 0.5rem; overflow-y: auto; inline-size: min(78ch, 100%); align-self: end; }
.timeline__panel .display { font-size: clamp(1.4rem, 5.5cqi, 2.4rem); }
.timeline__where { margin: 0; font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.04em; opacity: 0.85; overflow-wrap: anywhere; }
.timeline__where strong { color: color-mix(in srgb, var(--card-accent) 55%, var(--paper)); }
.tl { display: grid; grid-template-columns: minmax(12ch, 17ch) minmax(0, 1fr); gap: 0.45rem 0.9rem; align-items: center; margin-top: 0.35rem; }
.tl__label { display: grid; gap: 0.1rem; font-size: var(--step-kicker); line-height: 1.25; opacity: 0.92; }
.tl__label strong, .tl__num {
  font-family: var(--font-display); font-weight: 800; font-size: clamp(1.4rem, 5cqi, 2rem);
  line-height: 1; letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.tl__label--cases strong { color: var(--sf-golden-hills); }
.tl__frac { display: flex; align-items: baseline; gap: 0.35rem; }
.tl__num { color: #6fdc9a; }
.tl__of { font-size: var(--step-body); font-weight: 700; }
.tl__strip { width: 100%; display: block; overflow: visible; border-bottom: 1px solid color-mix(in srgb, var(--card-fg) 22%, transparent); }
.tl__case { fill: var(--sf-golden-hills); opacity: 0.92; transform-box: fill-box; transform-origin: center; }
.tl__visit { transform-box: fill-box; transform-origin: center; stroke: rgba(0, 0, 0, 0.35); stroke-width: 1.2; }
.tl__visit--clean { fill: #6fdc9a; }
.tl__visit--issue { fill: var(--sf-imperial-gold); }
.tl__visit--severe { fill: var(--sf-sunset-coral); }
.tl__axis { width: 100%; display: block; overflow: visible; }
.tl__tick { stroke: color-mix(in srgb, var(--card-fg) 45%, transparent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tl__month { fill: var(--card-fg); opacity: 0.7; font-family: var(--font-mono); font-size: 22px; text-anchor: middle; }
.tl__legend { display: flex; flex-wrap: wrap; gap: 0.3rem 1rem; margin: 0.15rem 0 0; font-family: var(--font-mono); font-size: var(--step-kicker); opacity: 0.85; }
.tl__key { display: inline-flex; align-items: center; gap: 0.4rem; }
.tl__key::before { content: ''; width: 10px; height: 10px; border-radius: 50%; flex: none; }
.tl__key--case::before { background: var(--sf-golden-hills); width: 7px; height: 7px; }
.tl__key--clean::before { background: #6fdc9a; }
.tl__key--issue::before { background: var(--sf-imperial-gold); }
.tl__key--severe::before { background: var(--sf-sunset-coral); }
.timeline__panel .beat__body { margin-top: 0.3rem; }
/* phones: labels stack above their strips so the time axis gets the full panel width */
@media (max-width: 700px) {
  .tl { grid-template-columns: 1fr; gap: 0.25rem; }
  .tl > div:empty { display: none; }
  .tl__label { grid-template-columns: auto 1fr; align-items: baseline; gap: 0.4rem; }
  .tl__strip { margin-bottom: 0.35rem; }
}
.timeline__foot { margin: 0.1rem 0 0; font-size: var(--step-kicker); opacity: 0.75; }

/* ---- v2 close (verdict + "if we scale it" beats + agency tiles) ---- */
.beat.close .panel.close__panel { display: grid; gap: 0.55rem; overflow-y: auto; inline-size: min(60ch, 100%); align-content: start; }
.beat.close--wide .panel.close__panel { inline-size: min(96ch, 100%); }   /* verdict + tiles carry the doc's full text */
@media (min-width: 1000px) {
  .close--wide .tiles { grid-template-columns: repeat(3, 1fr); }
}
/* short laptop screens: the verbatim wording is long — tighten type and padding, never clip */
@media (max-height: 800px) {
  /* the stage padding (pad + 1.5rem top, pad + 3.5rem bottom) eats ~200px on a 720px screen —
     the nav only needs ~70px, so reclaim the rest for the panel */
  .cards > .close { padding-block: calc(var(--pad) * 0.5 + 1rem) calc(var(--pad) * 0.4 + 3.4rem); }
  .beat.close .panel.close__panel { gap: 0.4rem; padding: 1.25rem 1.5rem; }
  .close__panel .display { font-size: clamp(1.25rem, 4.5cqi, 1.8rem); }
  .close--wide .beat__items > li { font-size: 1rem; }
  .beat__sub li { font-size: 0.82rem; }
  .tile { padding: 0.5rem 0.65rem; font-size: 0.8rem; line-height: 1.3; }
  .tile strong { font-size: 0.92rem; }
}
.close__panel .display { font-size: clamp(1.5rem, 5.5cqi, 2.5rem); }
/* nested bullets under an answer (the agreed doc's sub-points) */
.beat__sub { display: grid; gap: 0.3rem; margin: 0.35rem 0 0.15rem; padding: 0 0 0 0.9rem; list-style: none; border-left: 2px solid color-mix(in srgb, var(--card-accent) 45%, transparent); }
.beat__sub li { font-size: var(--step-kicker); line-height: 1.4; opacity: 0.95; overflow-wrap: anywhere; }
.beat__sub strong { font-weight: 700; margin-right: 0.35em; }
/* agency tiles */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; margin: 0.5rem 0 0; padding: 0; list-style: none; }
.tile {
  display: grid; gap: 0.2rem; align-content: start; padding: 0.65rem 0.8rem; border-radius: 10px;
  background: color-mix(in srgb, var(--card-fg) 7%, transparent);
  border: 1px solid color-mix(in srgb, var(--card-fg) 14%, transparent);
  font-size: var(--step-kicker); line-height: 1.35; overflow-wrap: anywhere;
}
.tile strong { font-size: var(--step-body); color: color-mix(in srgb, var(--card-accent) 55%, var(--paper)); }
.close__caveat { margin: 0.55rem 0 0; font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.04em; opacity: 0.6; overflow-wrap: anywhere; }
@media (max-width: 700px) { .tiles { grid-template-columns: 1fr; } .tile { padding: 0.45rem 0.6rem; font-size: 0.8rem; } .tile strong { font-size: 0.95rem; } }

/* ---- v2 pale-out (Insight 3: 43% clean) ---- */
.paleout__panel {
  display: grid; gap: 0.5rem; overflow-y: auto; inline-size: min(52ch, 100%);
  align-self: end; justify-self: center; align-content: start;
}
.paleout__panel .display { font-size: clamp(1.4rem, 5.5cqi, 2.4rem); }
/* number + sentence flow as one unit: the % is never orphaned at a line/section break */
.paleout__stat { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.45rem; margin: 0.4rem 0 0; min-width: 0; }
.paleout__stat .paleout__num { font-size: clamp(2rem, 16cqi, 3.6rem); }
.paleout__statline { font-size: var(--step-body); opacity: 0.92; overflow-wrap: anywhere; min-width: 0; }
.paleout__statline strong { font-weight: 700; }
.paleout__legend { display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; margin: 0.45rem 0 0; font-family: var(--font-mono); font-size: var(--step-kicker); opacity: 0.85; }
.paleout__key { display: inline-flex; align-items: center; gap: 0.45rem; }
.paleout__key::before { content: ''; width: 10px; height: 10px; border-radius: 50%; flex: none; }
.paleout__key--clean::before { background: #6fdc9a; }
.paleout__key--flag::before { background: color-mix(in srgb, var(--card-fg) 55%, transparent); }
.paleout__panel .beat__body { font-size: var(--step-kicker); margin-top: 0.2rem; }

/* ---- Divergence beat ---- */
.divergence { display: grid; gap: 0.7rem; }
.divergence__row { display: grid; grid-template-columns: auto 1fr; align-items: baseline; gap: 0.6rem; margin: 0; }
.divergence__pct { font-size: clamp(2rem, 22cqi, 3.75rem); line-height: 1; }
.divergence__row--crowd .divergence__pct { color: var(--sf-golden-hills); }   /* complaints */
.divergence__row--camera .divergence__pct { color: color-mix(in srgb, var(--sf-bay-blue) 45%, white); } /* sweep — lightened for dark-panel contrast */
.divergence__row .stat__label { font-size: var(--step-body); font-weight: 600; align-self: center; }
.divergence__link {
  justify-self: start; margin-top: 0.3rem;
  font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.06em;
  color: var(--paper); text-decoration: underline; text-underline-offset: 3px;
}
.divergence__link:hover { color: var(--card-accent); }

/* ---- Hexbin hero ("Where it looked") ---- */
/* The engine (SVG faux-3D or deck.gl WebGL) mounts into .hexbin-stage, a full-card layer behind
   the panel. data-no-advance (set in JS) keeps taps/drags on the viz from skipping the card. */
.hexbin-stage { position: absolute; inset: 0; z-index: 0; pointer-events: auto; }
.hexbin-svg   { width: 100%; height: 100%; display: block; overflow: visible; pointer-events: auto; }
.hexbin-webgl { width: 100%; height: 100%; display: block; pointer-events: auto; cursor: crosshair; }   /* drag to orbit */
.hexbin-tooltip {
  position: absolute; left: 0; top: 0; z-index: 4;
  pointer-events: none;
  padding: 0.35rem 0.5rem;
  border: 1px solid color-mix(in srgb, var(--card-fg) 18%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--ink) 74%, transparent);
  color: var(--paper);
  box-shadow: 0 10px 30px rgba(0,0,0,.3);
  font-family: var(--font-mono);
  font-size: var(--step-kicker);
  letter-spacing: 0.04em;
  white-space: nowrap;
  backdrop-filter: blur(8px);
}
.hexbin-tooltip[hidden] { display: none; }
.hexbin-tooltip.is-pinned {
  border-color: color-mix(in srgb, var(--card-accent) 60%, var(--paper));
  background: color-mix(in srgb, var(--ink) 86%, transparent);
}
.hexbin-plane.is-drifting { animation: map-drift 26s ease-in-out infinite alternate; transform-origin: 50% 60%; }
.hexbin-cap { stroke: rgba(0,0,0,.25); stroke-width: 0.6; }
/* neighborhood/city outlines behind the columns for geographic legibility */
.hexbin-hood {
  fill: color-mix(in srgb, var(--card-fg) 3%, transparent);
  stroke: color-mix(in srgb, var(--sf-bay-teal) 64%, var(--paper));
  stroke-width: 1.05; stroke-opacity: 0.56; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.hexbin-compass {
  --compass-size: clamp(4.2rem, 8cqi, 5.4rem);
  --map-bearing: 0deg;
  --map-tilt: 55deg;
  position: absolute; inset-block-start: clamp(1rem, 4vh, 2.4rem); inset-inline-end: clamp(1rem, 4vw, 3rem);
  z-index: 2; inline-size: var(--compass-size); block-size: var(--compass-size);
  border: 1px solid color-mix(in srgb, var(--card-fg) 24%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 62%, transparent);
  box-shadow: 0 12px 32px rgba(0,0,0,.26);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--step-kicker);
  font-weight: 800;
  letter-spacing: 0.04em;
  pointer-events: none;
  backdrop-filter: blur(8px);
}
.hexbin-compass--plane {
  transform: perspective(520px) rotateX(var(--map-tilt)) rotateZ(var(--map-bearing));
  transform-origin: 50% 50%;
  transform-style: preserve-3d;
}
.hexbin-compass::before {
  content: ''; position: absolute; inset: 28%;
  border: 1px solid color-mix(in srgb, var(--paper) 22%, transparent);
  border-radius: 50%;
}
.hexbin-compass__label {
  position: absolute; line-height: 1; opacity: 0.88;
  transform: translate(-50%, -50%);
  text-shadow: 0 1px 7px rgba(0,0,0,.45);
}
.hexbin-compass__label--n { inset-block-start: 13%; inset-inline-start: 50%; color: color-mix(in srgb, var(--card-accent) 58%, var(--paper)); }
.hexbin-compass__label--e { inset-block-start: 50%; inset-inline-start: 86%; }
.hexbin-compass__label--s { inset-block-start: 87%; inset-inline-start: 50%; }
.hexbin-compass__label--w { inset-block-start: 50%; inset-inline-start: 14%; }
.hexbin-compass__needle {
  position: absolute; inset: 23%;
  transform: rotate(var(--north-rot, 0deg));
}
.hexbin-compass__needle::before {
  content: ''; position: absolute; inset-block: 6% 20%; inset-inline-start: 50%;
  inline-size: 2px; transform: translateX(-50%);
  border-radius: 99px;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--card-accent) 75%, var(--paper)) 0 50%,
    color-mix(in srgb, var(--paper) 62%, transparent) 50% 100%
  );
}
.hexbin-compass__needle::after {
  content: ''; position: absolute; inset-block-start: 0; inset-inline-start: 50%;
  transform: translateX(-50%);
  border-inline: 0.32rem solid transparent;
  border-block-end: 0.62rem solid color-mix(in srgb, var(--card-accent) 75%, var(--paper));
}
.hexbin-svg-compass {
  pointer-events: none;
}
.hexbin-svg-compass__ring {
  fill: color-mix(in srgb, var(--ink) 62%, transparent);
  stroke: color-mix(in srgb, var(--card-fg) 24%, transparent);
  stroke-width: 1.1;
  vector-effect: non-scaling-stroke;
}
.hexbin-svg-compass__needle {
  fill: color-mix(in srgb, var(--card-accent) 75%, var(--paper));
  stroke: color-mix(in srgb, var(--paper) 46%, transparent);
  stroke-width: 0.8;
  vector-effect: non-scaling-stroke;
}
.hexbin-svg-compass__label {
  fill: var(--paper);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 800;
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  stroke: rgba(0,0,0,.4);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
}
.hexbin-svg-compass__label--n {
  fill: color-mix(in srgb, var(--card-accent) 58%, var(--paper));
}

/* panel docked at the bottom; the prose scrolls if it ever exceeds the cap so it can never
   spill over the nav. "Hide text" collapses the prose to just the control bar for bare-viz study. */
.hexbin-card .panel {
  position: relative; z-index: 1;
  align-self: end; justify-self: center;
  inline-size: min(42ch, 100%); max-height: 80%;
  display: grid; grid-template-rows: minmax(0, 1fr);
  overflow: hidden;                       /* prose scrolls within the cap — never spills onto nav */
}
.hexbin-prose { display: grid; gap: 0.5rem; overflow-y: auto; min-height: 0; align-content: start; }
.hexbin-card[data-panel="min"] .hexbin-prose { display: none; }
.hexbin-card[data-panel="min"] .panel {
  background: none; border: none; box-shadow: none; backdrop-filter: none;
  inline-size: auto; max-height: none;
}
.hexbin-caption {
  margin: 0.7rem 0 0; font-family: var(--font-mono); font-size: var(--step-kicker);
  letter-spacing: 0.03em; line-height: 1.4; opacity: 0.8; overflow-wrap: anywhere;
}
.hexbin-fallback { margin: 0.6rem 0 0; color: var(--paper); font-size: var(--step-body); opacity: 0.9; }

/* stat chip (e.g., The Sweep's "7 in 10 blocks Excellent") */
.hexbin-chips { display: flex; align-items: baseline; gap: 1.6rem; margin: 0.15rem 0 0.1rem; flex-wrap: wrap; min-width: 0; }
.hexbin-chips .hexbin-chip { margin: 0; }
.hexbin-chip { display: flex; align-items: baseline; gap: 0.45rem; margin: 0.15rem 0 0.1rem; min-width: 0; }
.hexbin-chip strong {
  font-family: var(--font-display); font-weight: 800; font-size: clamp(1.8rem, 9cqi, 2.6rem);
  line-height: 1; letter-spacing: -0.02em; color: color-mix(in srgb, var(--card-accent) 55%, var(--paper));
}
.hexbin-chip span { font-size: var(--step-body); font-weight: 600; overflow-wrap: anywhere; }

/* ---- Scoring rubric ---- */
.rubric-card {
  place-items: center;
}
.rubric__panel {
  display: grid;
  gap: 0.55rem;
  inline-size: min(1100px, calc(100vw - var(--pad) * 2));
  max-height: min(86vh, 780px);
  overflow-y: auto;
  align-self: center;
  justify-self: center;
}
.rubric__panel .display {
  font-size: clamp(1.55rem, 4.2cqi, 2.7rem);
}
.rubric__panel .beat__body {
  max-inline-size: 72ch;
  font-size: var(--step-kicker);
  opacity: 0.9;
}
.rubric__categories {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(1rem, 2vw, 1.4rem);
  min-width: 0;
}
.rubric-category {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(13rem, 19rem);
  gap: 0.8rem;
  min-width: 0;
  align-content: start;
  align-items: start;
}
.rubric-category__content {
  display: grid;
  gap: 0.32rem;
  min-width: 0;
}
.rubric-category__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.7cqi, 1.85rem);
  line-height: 1.05;
  color: color-mix(in srgb, var(--card-accent) 52%, var(--paper));
}
.rubric-category__definition {
  margin: 0;
  font-size: var(--step-kicker);
  line-height: 1.45;
  opacity: 0.86;
}
.rubric-scale {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.32rem;
}
.rubric-scale__item {
  display: grid;
  grid-template-columns: 3.1rem minmax(0, 1fr);
  gap: 0.55rem;
  align-items: baseline;
  min-width: 0;
  font-size: var(--step-kicker);
}
.rubric-scale__item strong {
  display: inline-grid;
  place-items: center;
  min-height: 1.55rem;
  border-radius: 5px;
  background: color-mix(in srgb, var(--card-accent) 22%, transparent);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: var(--step-kicker);
}
.rubric-scale__item span {
  overflow-wrap: anywhere;
}
.rubric-examples {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.42rem;
  grid-column: 2;
  grid-row: 1;
  margin-top: 0;
}
.rubric-example {
  margin: 0;
  min-width: 0;
}
.rubric-example__image {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--card-fg) 18%, transparent);
  background: color-mix(in srgb, var(--ink) 42%, transparent);
}
.rubric-example figcaption {
  margin-top: 0.2rem;
  font-family: var(--font-mono);
  font-size: clamp(0.62rem, 1.15cqi, 0.74rem);
  line-height: 1.25;
  opacity: 0.86;
  overflow-wrap: anywhere;
}

/* ---- v2 top-hex timeline ---- */
.tophex__panel {
  display: grid; gap: 0.55rem; overflow-y: auto; inline-size: min(76ch, 100%);
  align-self: end; justify-self: center; align-content: start;
}
.tophex__panel .display { font-size: clamp(1.4rem, 5.5cqi, 2.4rem); }
.tophex__summary {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem;
  margin: 0.15rem 0 0; font-size: var(--step-kicker); opacity: 0.9;
}
.tophex__summary strong {
  font-family: var(--font-display); font-size: clamp(1.8rem, 7cqi, 3rem);
  line-height: 1; color: color-mix(in srgb, var(--card-accent) 55%, var(--paper));
}
.tophex__chart {
  inline-size: 100%; display: block; margin-top: 0.35rem; overflow: visible;
}
.tophex__grid { stroke: color-mix(in srgb, var(--card-fg) 18%, transparent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tophex__axis-label,
.tophex__month {
  fill: var(--card-fg); opacity: 0.66; font-family: var(--font-mono); font-size: 24px;
}
.tophex__tick { stroke: color-mix(in srgb, var(--card-fg) 42%, transparent); stroke-width: 1; vector-effect: non-scaling-stroke; }
.tophex__bar {
  transform-box: fill-box; transform-origin: bottom;
  vector-effect: non-scaling-stroke;
}
.tophex__bar--issue { fill: var(--sf-sunset-coral); }
.tophex__bar--clean { fill: #6fdc9a; }
.tophex__day:hover .tophex__bar {
  stroke: var(--paper); stroke-width: 1.4;
}
.tophex__legend {
  display: flex; flex-wrap: wrap; gap: 0.35rem 1rem; margin: 0;
  font-family: var(--font-mono); font-size: var(--step-kicker); opacity: 0.9;
}
.tophex__key { display: inline-flex; align-items: center; gap: 0.45rem; }
.tophex__key::before { content: ''; width: 10px; height: 10px; border-radius: 2px; flex: none; }
.tophex__key--issue::before { background: var(--sf-sunset-coral); }
.tophex__key--clean::before { background: #6fdc9a; }

/* ---- v2 category severity map ---- */
.category-map {
  place-items: center;
}
.category-map__stage {
  position: absolute; inset: 0; z-index: 0; display: grid; place-items: center;
  padding: clamp(0.5rem, 2vw, 1.5rem) clamp(0.5rem, 3vw, 2rem) clamp(10rem, 22vh, 17rem);
  pointer-events: none;
}
.category-map__svg {
  inline-size: min(98vw, 1260px); block-size: min(86vh, 900px);
  overflow: visible; filter: drop-shadow(0 22px 42px rgba(0,0,0,0.22));
}
.category-map__hood {
  fill: color-mix(in srgb, var(--card-fg) 4%, transparent);
  stroke: color-mix(in srgb, var(--sf-bay-teal) 64%, var(--paper));
  stroke-width: 1.1; stroke-opacity: 0.56; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke;
}
.category-map__hex {
  stroke: rgba(0,0,0,0.34); stroke-width: 0.52; vector-effect: non-scaling-stroke;
  transition: fill 220ms ease, opacity 220ms ease, stroke 220ms ease;
}
.category-map__hex[data-empty="true"] {
  stroke: color-mix(in srgb, var(--card-fg) 18%, transparent);
}
.category-map__panel {
  display: grid; gap: 0.5rem; align-self: end; justify-self: center;
  inline-size: min(66ch, 100%); align-content: start;
}
.category-map__panel .display { font-size: clamp(1.45rem, 5.4cqi, 2.45rem); }
.category-map__field {
  display: grid; grid-template-columns: auto minmax(28rem, 1fr); align-items: center;
  gap: 0.7rem; font-family: var(--font-mono); font-size: var(--step-kicker);
}
.category-map__select {
  min-inline-size: 0; inline-size: 100%; border: 1px solid color-mix(in srgb, var(--card-fg) 28%, transparent);
  border-radius: 6px; padding: 0.48rem 0.65rem; color: var(--paper);
  background: color-mix(in srgb, var(--ink-2) 86%, var(--sf-bay-blue));
  color-scheme: dark;
  font: inherit;
}
.category-map__select option {
  color: var(--paper);
  background: var(--ink-2);
}
.category-map__select option:checked {
  color: var(--ink);
  background: var(--sf-golden-hills);
}
.category-map__summary {
  margin: 0; font-family: var(--font-mono); font-size: var(--step-kicker); opacity: 0.9;
}
.category-map__key {
  position: absolute; right: clamp(1rem, 4vw, 3rem); top: clamp(1rem, 4vh, 3rem);
  display: grid; grid-template-columns: auto minmax(8rem, 14rem) auto; align-items: center;
  gap: 0.55rem; padding: 0.55rem 0.7rem; border-radius: 7px;
  border: 1px solid color-mix(in srgb, var(--card-fg) 16%, transparent);
  background: color-mix(in srgb, var(--ink) 68%, transparent);
  color: var(--paper);
  box-shadow: 0 12px 34px rgba(0,0,0,0.24);
  backdrop-filter: blur(8px);
  font-family: var(--font-mono); font-size: var(--step-kicker); opacity: 0.95;
  white-space: nowrap;
}
.category-map__ramp {
  display: block; block-size: 0.75rem; border-radius: 999px;
  background: linear-gradient(90deg, rgb(239 245 236), rgb(145 214 155), rgb(246 200 91), rgb(231 92 74));
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.18);
}
.category-map:has(.insight-transition:not([hidden])) .category-map__stage {
  opacity: 0;
}

@media (max-width: 700px) {
  .category-map__stage {
    padding: clamp(1rem, 4vw, 3rem) clamp(1rem, 5vw, 4rem) clamp(18rem, 34vh, 25rem);
  }
  .category-map__svg {
    inline-size: min(95vw, 1080px); block-size: min(64vh, 700px);
  }
  .category-map__key {
    left: 50%; right: auto; top: clamp(1rem, 4vh, 3rem);
    transform: translateX(-50%);
  }
}

@media (max-width: 800px) {
  .rubric__panel {
    max-height: min(84vh, 760px);
  }
  .rubric__categories {
    grid-template-columns: 1fr;
  }
  .rubric-category {
    grid-template-columns: 1fr;
  }
  .rubric-examples {
    grid-column: auto;
    grid-row: auto;
    max-inline-size: 22rem;
  }
}

/* fog vignette — closes the frame in around a map marker (e.g. the sergeant's pulsing light).
   Sits over the shell map, below the panel; pointer-events none so tap-to-advance still works. */
.beat[data-fog]::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 72% 58% at 50% 42%, transparent 30%, rgba(5, 7, 9, 0.66) 100%);
}
.beat[data-fog] .panel { position: relative; z-index: 1; }

/* ---- What it saw (flat-rubric bars) ---- */
.algorithm-card .panel { max-height: 100%; overflow-y: auto; }   /* never spill onto the nav */
.rubric { display: grid; gap: 0.4rem; margin: 0.6rem 0 0; }
.rubric__row { display: grid; grid-template-columns: 8.5em 1fr auto; align-items: center; gap: 0.5rem; min-width: 0; }
.rubric__label { font-size: var(--step-kicker); overflow-wrap: anywhere; opacity: 0.92; }
.rubric__track { height: 12px; border-radius: 999px; background: color-mix(in srgb, var(--paper) 12%, transparent); overflow: hidden; }
.rubric__fill { display: block; height: 100%; border-radius: 999px; background: color-mix(in srgb, var(--paper) 55%, transparent); }
.rubric__fill[data-hot] { background: var(--sf-sunset-coral); }   /* Graffiti — the loud cosmetic one */
.rubric__num { font-family: var(--font-mono); font-size: var(--step-kicker); font-variant-numeric: tabular-nums; opacity: 0.9; }
.rubric__formula { margin: 0.7rem 0 0; font-family: var(--font-mono); font-size: var(--step-kicker); line-height: 1.45; opacity: 0.82; overflow-wrap: anywhere; }
.rubric__fold { margin: 0.55rem 0 0; font-size: var(--step-body); line-height: 1.4; }
.rubric__fold strong { color: color-mix(in srgb, var(--card-accent) 60%, var(--paper)); }

/* ---- Equity read (Bayview ↔ Mission ↔ income) ---- */
.equity-card .panel { align-self: end; justify-self: center; inline-size: min(44ch, 100%); max-height: 100%; overflow-y: auto; }
.equity-metric { margin: 0.45rem 0 0; }
.equity-take { margin-top: 0.55rem; }
.equity-legend { display: flex; gap: 1rem; margin: 0.2rem 0 0.4rem; font-family: var(--font-mono); font-size: var(--step-kicker); }
.equity-key { display: inline-flex; align-items: center; gap: 0.4rem; }
.equity-key::before { content: ''; width: 12px; height: 12px; border-radius: 3px; }
.equity-key--b::before { background: var(--sf-bay-teal); }
.equity-key--m::before { background: var(--sf-golden-hills); }
.equity-metric { margin: 0.55rem 0 0; }
.equity-metric__label { margin: 0 0 0.25rem; font-size: var(--step-kicker); opacity: 0.9; }
.equity-bars { display: grid; gap: 0.3rem; }
.equity-bar { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 0.5rem; }
.equity-bar__fill { height: 13px; border-radius: 999px; min-width: 3px; }
.equity-bar__val { font-family: var(--font-mono); font-size: var(--step-kicker); font-variant-numeric: tabular-nums; opacity: 0.92; }
.equity-take { margin-top: 0.7rem; }

/* ---- Four kinds of block (typology synthesis) ---- */
.typo-card .panel { align-self: end; justify-self: center; inline-size: min(46ch, 100%); max-height: 100%; overflow-y: auto; display: grid; gap: 0.45rem; }
.typo-row { display: grid; grid-template-columns: auto 1fr; gap: 0.55rem; align-items: start; }
.typo-swatch { width: 12px; height: 12px; border-radius: 3px; margin-top: 0.35rem; }
.typo-row--agree .typo-swatch { background: var(--sf-bay-teal); }
.typo-row--diverge .typo-swatch { background: var(--sf-sunset-coral); }
.typo-body { min-width: 0; }
.typo-head { margin: 0; font-size: var(--step-body); }
.typo-head strong { color: color-mix(in srgb, var(--card-accent) 55%, var(--paper)); }
.typo-hood { opacity: 0.85; }
.typo-sub { margin: 0.1rem 0 0.35rem; font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.02em; opacity: 0.9; }
.typo-sub .typo-311 { color: var(--sf-golden-hills); }
.typo-sub .typo-ai { color: color-mix(in srgb, var(--sf-bay-blue) 45%, white); }
.typo-stats { margin: 0.05rem 0 0; display: flex; flex-wrap: wrap; gap: 0.2rem 1rem; font-family: var(--font-mono); font-size: var(--step-kicker); }
/* source colors: 311 = gold (public), AI severe = blue (the model) — the comparison the card is about */
.typo-src strong { font-family: var(--font-display); font-size: 1.25em; letter-spacing: -0.01em; }
.typo-311 strong { color: var(--sf-golden-hills); }
.typo-ai strong { color: color-mix(in srgb, var(--sf-bay-blue) 45%, white); }
.typo-src span { opacity: 0.82; }
.typo-note { margin: 0.02rem 0 0; font-size: var(--step-kicker); opacity: 0.7; overflow-wrap: anywhere; }
.typo-take { margin-top: 0.5rem; }

/* ---- Caveats (quiet honesty card) ---- */
.caveats { align-content: center; gap: var(--gap); max-width: min(92vw, 46rem); min-width: 0; }
.caveats .display { font-size: var(--step-l); max-width: 20ch; }
.caveats__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7rem; }
.caveats__item { font-size: var(--step-body); line-height: 1.45; max-width: 54ch; overflow-wrap: anywhere; opacity: 0.94; }
.caveats__item strong { color: var(--card-accent); }

/* ---- Complaints choropleth legend ---- */
.choropleth-card .choro-legend, .choropleth-card .beat__stat { transition: opacity 1.4s ease 0.3s; }
.choropleth-card:has(.panel.is-drained) .choro-legend { opacity: 0.3; }
.choropleth-card .beat__stat {
  margin-top: 0.2rem;
  gap: 0.1rem;
}
.choropleth-card .beat__stat .stat__num {
  font-size: clamp(1.2rem, 4.5cqi, 1.8rem);
  line-height: 1;
}
.choropleth-card .beat__stat .stat__label {
  font-size: var(--step-body);
}
.choropleth-note {
  margin: 0.25rem 0 0;
  padding-top: 0.55rem;
  border-top: 1px solid color-mix(in srgb, var(--card-fg) 16%, transparent);
  font-size: var(--step-kicker);
  line-height: 1.45;
  opacity: 0.84;
}
.choro-legend {
  position: absolute; z-index: 3;
  inset-inline-end: var(--pad);
  inset-block-end: calc(var(--pad) + 3.5rem);
  display: flex; align-items: center; gap: 0.5rem;
  inline-size: min(21rem, calc(100% - var(--pad) * 2));
  padding: 0.55rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--card-fg) 18%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 56%, transparent);
  backdrop-filter: blur(8px);
  box-shadow: 0 12px 36px rgba(0,0,0,.28);
}
.choro-legend__bar {
  flex: 1; height: 10px; border-radius: 999px; min-width: 80px;
  background: linear-gradient(90deg, #f2e6c4, #e6c179, #d29a3b, #b0741d, #7c4d12);
}
.choro-legend__label { font-family: var(--font-mono); font-size: var(--step-kicker); letter-spacing: 0.06em; opacity: 0.85; }
@media (max-width: 700px) {
  .choro-legend {
    inset-inline: var(--pad);
    inset-block-end: calc(env(safe-area-inset-bottom) + 4.6rem);
    inline-size: auto;
  }
}

/* ---- Share ---- */
.share { grid-template-rows: auto 1fr auto; justify-items: center; align-content: center; gap: var(--gap); }
.share__frame {
  max-height: 62cqh; aspect-ratio: 1080 / 1350;
  border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,.35);
}
.share__canvas { display: block; height: 100%; width: auto; max-width: 100%; }
.share__dl { color: var(--sf-on-light); background: var(--card-fg); border: none; text-decoration: none; }
.share__dl:hover { background: color-mix(in srgb, var(--card-fg) 85%, black); }

/* short laptop screens: slide 1 drops the number strip entirely (the counts return on slides 2-3) */
@media (max-height: 760px) {
  .overture--compact .stats, .overture--compact .overture .stat__sub:last-child { display: none; }
}

/* per-card provenance footer — tiny, quiet, does not compete with content */
.card__source {
  position: absolute; left: var(--pad); right: auto; bottom: calc(var(--pad) * 0.35 + 0.6rem);
  max-width: none; white-space: nowrap; text-align: left; font-family: var(--font-mono); font-size: var(--step-kicker);
  letter-spacing: 0.08em; opacity: 0.55; color: var(--card-fg);
  text-decoration: none; pointer-events: auto;
}
.card__source:hover { opacity: 0.9; text-decoration: underline; }
/* phones: centered, in the band between the docked panel and the nav */
@media (max-width: 700px) {
  .card__source { left: 0; right: 0; white-space: normal; text-align: center; bottom: calc(env(safe-area-inset-bottom) + 3.7rem); }
}

/* ---- big screens (1600px+): panels ran narrow and type small. The panel's own font-size
   drives its ch-based width, so scaling it widens every panel; display/stat caps rise too. ---- */
@media (min-width: 1600px) {
  .panel { font-size: 1.2rem; }
  .beat:has(.beat__items) .panel { inline-size: min(60ch, 100%); }
  .barpair__panel, .paleout__panel { inline-size: min(56ch, 100%); }
  .beat.close .panel.close__panel { inline-size: min(66ch, 100%); }
  .beat.close--wide .panel.close__panel { inline-size: min(96ch, 100%); }
  .timeline__panel { inline-size: min(84ch, 100%); }
  .hexbin-card .panel { inline-size: min(46ch, 100%); }
  .overture { max-width: min(92vw, 54rem); }
  .overture--compact .display { font-size: clamp(2.2rem, 8cqi, 4rem); }
  .overture--compact .overture__questions { max-width: 40rem; }
  .overture--compact .overture__questions li { font-size: clamp(1.2rem, 4.2cqi, 1.8rem); }
  .overture--compact .stat__num { font-size: clamp(1.4rem, 4.5cqi, 2.3rem); }
  .barpair__panel .display, .timeline__panel .display, .paleout__panel .display { font-size: clamp(1.6rem, 5.5cqi, 3rem); }
  .beat .display { font-size: clamp(1.8rem, 5vw, 3.1rem); }
  .paleout__stat .paleout__num { font-size: clamp(2.4rem, 16cqi, 4.4rem); }
  .beat__stat .stat__num { font-size: clamp(2.4rem, 26cqi, 5.4rem); }
  .hexbin-chip strong { font-size: clamp(2rem, 9cqi, 3.2rem); }
}
@media (min-width: 2200px) {
  .panel { font-size: 1.4rem; }
}
