/* ---- 00-base.css ---- */
/* ======================================================================
   site/css/00-base.css · OWNER: Agent A (core engine)
   Reset, base type, utilities (.sr-only .label .tnum .i .unk), the program scope ([data-prog] → --ink-*),
   bullets, .prog-badge, .prog-dot, .prog-u, .halftone.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */
/* ---------- 00 · reset and base ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--topbar-h) + var(--sched-bar-h) + var(--sp-4));
}
body {
  font-family: var(--font-body);
  font-size: var(--fs-base);
  font-weight: var(--wght-body);
  line-height: var(--lh-body);
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none;
}
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; text-align: inherit; }
a { color: var(--link); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
a:hover { color: var(--link-hover); text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-xs); }
::selection { background: var(--accent-tint); color: var(--text); }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--wght-head);
  letter-spacing: var(--track-head);
  line-height: var(--lh-head);
  color: var(--text);
  text-wrap: balance;
}
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); line-height: var(--lh-snug); }
h4 { font-size: var(--fs-md); line-height: var(--lh-snug); }
p, li, dd { text-wrap: pretty; }
strong, b { font-weight: var(--wght-strong); }
kbd {
  font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); line-height: 1.4;
  background: var(--kbd-bg); color: var(--text-muted);
  border: 1px solid var(--border-strong); border-bottom-width: 2px; border-radius: var(--radius-sm);
  padding: 1px 6px; white-space: nowrap;
}
code { font-family: var(--font-mono); font-size: max(0.9em, var(--fs-label)); background: var(--code-bg); padding: 1px 5px; border-radius: var(--radius-xs); }
hr { border: 0; border-top: 1px solid var(--border); margin: var(--sp-5) 0; }
[hidden] { display: none !important; }

/* ---------- utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: var(--z-toast);
  background: var(--primary); color: var(--primary-contrast);
  padding: 12px 18px; font-weight: var(--wght-strong); text-decoration: none;
}
.skip-link:focus { left: 0; }
.label {
  font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong);
  line-height: 1.25; letter-spacing: var(--track-label); text-transform: uppercase;
}
.tnum { font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.i {                                   /* stroke icon from the sprite: 24 grid, 2px, round caps */
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
.i-fill { fill: currentColor; stroke: none; }
/* unknowns are printed as unknowns: faint roman with a dashed-circle mark, never a guess, never italic Public Sans */
.unk { color: var(--text-faint); display: inline-flex; align-items: baseline; gap: 5px; }
p.unk, div.unk { display: flex; }   /* QA: a paragraph of unknown stays a block (two in a row never share a line) */
.unk::before {
  content: ""; width: 9px; height: 9px; flex: none; align-self: center;
  border: 1.5px dashed currentColor; border-radius: 50%;
}

/* ---------- program scope: one rule per program sets five local inks ----------
   Components read ONLY --ink-fill / --ink-text / --ink-on / --ink-tint / --ink-edge.
   A new program is one rule here plus its tokens and bullet symbol (Brand Fusion was the sixth).
   article.ev[data-p] (the engine's filter attribute) is also a scope. */
:root { --ink-fill: var(--rule-ink); --ink-text: var(--text); --ink-on: var(--primary-contrast); --ink-tint: var(--surface-alt); --ink-edge: var(--rule-ink); }
[data-prog="caw"], .ev[data-p="caw"] { --ink-fill: var(--prog-caw); --ink-text: var(--prog-caw-ink); --ink-on: var(--prog-caw-on); --ink-tint: var(--prog-caw-tint); --ink-edge: var(--prog-caw-edge); }
[data-prog="scw"], .ev[data-p="scw"] { --ink-fill: var(--prog-scw); --ink-text: var(--prog-scw-ink); --ink-on: var(--prog-scw-on); --ink-tint: var(--prog-scw-tint); --ink-edge: var(--prog-scw-edge); }
[data-prog="blink"], .ev[data-p="blink"] { --ink-fill: var(--prog-blink); --ink-text: var(--prog-blink-ink); --ink-on: var(--prog-blink-on); --ink-tint: var(--prog-blink-tint); --ink-edge: var(--prog-blink-edge); }
[data-prog="brandfusion"], .ev[data-p="brandfusion"] { --ink-fill: var(--prog-brandfusion); --ink-text: var(--prog-brandfusion-ink); --ink-on: var(--prog-brandfusion-on); --ink-tint: var(--prog-brandfusion-tint); --ink-edge: var(--prog-brandfusion-edge); }
[data-prog="fotofocus"], .ev[data-p="fotofocus"] { --ink-fill: var(--prog-fotofocus); --ink-text: var(--prog-fotofocus-ink); --ink-on: var(--prog-fotofocus-on); --ink-tint: var(--prog-fotofocus-tint); --ink-edge: var(--prog-fotofocus-edge); }
[data-prog="also"], .ev[data-p="also"] { --ink-fill: var(--prog-also); --ink-text: var(--prog-also-ink); --ink-on: var(--prog-also-on); --ink-tint: var(--prog-also-tint); --ink-edge: var(--prog-also-edge); }
/* a second program on the same entity (person, venue): split rings and a second bullet */
[data-prog2="caw"] { --ink-fill-2: var(--prog-caw); }
[data-prog2="scw"] { --ink-fill-2: var(--prog-scw); }
[data-prog2="blink"] { --ink-fill-2: var(--prog-blink); }
[data-prog2="brandfusion"] { --ink-fill-2: var(--prog-brandfusion); }
[data-prog2="fotofocus"], [data-prog2="also"] { --ink-fill-2: var(--prog-fotofocus-edge); }

/* program bullet: letter + shape + ink, an inline SVG from the sprite (<use href="#b-caw">).
   24px is the smallest size (its letter renders at 12px, the system floor). */
.bullet { width: 24px; height: 24px; flex: none; overflow: visible; }
.bullet.lg { width: 32px; height: 32px; }
.bullet.xl { width: 44px; height: 44px; }
/* program badge (engine contract .prog-badge[data-prog]): bullet + program name in the program's text ink */
.prog-badge {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  color: var(--ink-text);
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; line-height: 1.2;
}
/* prog-dot: the shape alone (no letter), for legends and pins where the name is adjacent */
.prog-dot { display: inline-block; width: 12px; height: 12px; flex: none; background: var(--ink-fill); clip-path: var(--shape-square); }
[data-prog="scw"] .prog-dot, .prog-dot[data-prog="scw"] { clip-path: var(--shape-circle); }
[data-prog="blink"] .prog-dot, .prog-dot[data-prog="blink"] { clip-path: var(--shape-diamond); width: 14px; height: 14px; }
[data-prog="brandfusion"] .prog-dot, .prog-dot[data-prog="brandfusion"] { clip-path: var(--shape-octagon); }
[data-prog="fotofocus"] .prog-dot, .prog-dot[data-prog="fotofocus"],
[data-prog="also"] .prog-dot, .prog-dot[data-prog="also"] { clip-path: var(--shape-hexagon); background: var(--ink-edge); }
/* plate underline: program names set in display type are underlined in their ink (never a full color field) */
.prog-u {
  text-decoration-line: underline; text-decoration-color: var(--ink-fill);
  text-decoration-thickness: 0.085em; text-underline-offset: 0.14em; text-decoration-skip-ink: none;
}
[data-prog="fotofocus"] .prog-u, .prog-u[data-prog="fotofocus"], [data-prog="also"] .prog-u, .prog-u[data-prog="also"] { text-decoration-color: var(--ink-edge); }

/* halftone screen: newsprint's own texture, used only where a picture is missing */
.halftone {
  background:
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--ink-fill) 38%, transparent) 0.9px, transparent 1.3px) 0 0 / 6px 6px,
    var(--ink-tint);
}

/* ---------- engine additions (Agent A) ---------- */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
/* ---- 10-shell.css ---- */
/* ======================================================================
   site/css/10-shell.css · OWNER: Agent A (core engine)
   Topbar, brand, Live pill, search and plan buttons, layout grid, TOC rail, sidebar, My Plan card,
   drawer + rail collapse, dock, to-top, toast.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 10 · shell: topbar ---------- */
.topbar {
  position: sticky; top: 0; z-index: var(--z-topbar);
  display: flex; align-items: center; gap: var(--sp-2);
  height: var(--topbar-h); padding: 0 var(--sp-3);
  background: var(--bg); border-bottom: 1px solid var(--border);
}
@supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))) {
  .topbar { background: var(--topbar-bg); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
}
.nav-toggle, .icon-btn {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: var(--tap); height: var(--tap); border-radius: var(--radius-md); color: var(--text);
}
.nav-toggle:hover, .icon-btn:hover { background: var(--surface-alt); }
.icon-btn .i { width: 20px; height: 20px; }
.nav-toggle .hb { position: relative; display: block; width: 20px; height: 14px; }
.nav-toggle .hb span {
  position: absolute; left: 0; width: 100%; height: 2px; background: currentColor;
  transition: transform 260ms var(--ease), opacity var(--speed) var(--ease);
}
.nav-toggle .hb-t { top: 0; } .nav-toggle .hb-m { top: 6px; } .nav-toggle .hb-b { bottom: 0; }
@media (max-width: 1023px) {
  body.nav-open .nav-toggle .hb-t { transform: translateY(6px) rotate(45deg); }
  body.nav-open .nav-toggle .hb-m { opacity: 0; }
  body.nav-open .nav-toggle .hb-b { transform: translateY(-6px) rotate(-45deg); }
}
@media (min-width: 1024px) {
  :root:not(.rail-collapsed) .nav-toggle .hb-t { transform: translateY(6px) rotate(45deg); }
  :root:not(.rail-collapsed) .nav-toggle .hb-m { opacity: 0; }
  :root:not(.rail-collapsed) .nav-toggle .hb-b { transform: translateY(-6px) rotate(-45deg); }
}
.brand {
  display: flex; align-items: center; gap: 10px; min-width: 0; height: var(--tap);
  color: var(--text); text-decoration: none;
}
.brand:hover { color: var(--text); }
.brand-mark { width: 32px; height: 32px; flex: none; }
.brand-name { display: block; height: 22px; width: auto; color: var(--text); }   /* the outlined SVG wordmark */
.brand-date { color: var(--text-muted); border-left: 1px solid var(--border-strong); padding-left: 12px; white-space: nowrap; }
.topbar-spacer { flex: 1; }
.live-pill {
  display: inline-flex; align-items: center; gap: 8px; height: 36px; padding: 0 14px 0 12px;
  border-radius: var(--radius-pill); background: var(--live-tint); color: var(--live-ink);
  text-decoration: none; white-space: nowrap;
}
.live-pill:hover { color: var(--live-ink); text-decoration: underline; }
.dot-live { position: relative; width: 9px; height: 9px; flex: none; border-radius: 50%; background: var(--live); }
.dot-live::after {
  content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 2px solid var(--live);
  opacity: 0; animation: cw-pulse var(--pulse) var(--ease-out) infinite;
}
@keyframes cw-pulse { 0% { transform: scale(0.5); opacity: 0.9; } 70%, 100% { transform: scale(1.35); opacity: 0; } }
.searchbtn {
  display: flex; align-items: center; gap: 10px; height: var(--tap); min-width: 280px; padding: 0 10px 0 12px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); color: var(--text-muted); font-size: var(--fs-sm);
}
.searchbtn:hover { border-color: var(--text); color: var(--text); }
.searchbtn kbd { margin-left: auto; }
.planbtn {
  display: inline-flex; align-items: center; gap: 8px; height: var(--tap); padding: 0 12px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  color: var(--text); font-size: var(--fs-sm); font-weight: var(--wght-strong); text-decoration: none; white-space: nowrap;
}
.planbtn:hover { border-color: var(--text); color: var(--text); background: var(--surface); }
.count {                                  /* ink count badge: plan count, dock badge */
  display: inline-grid; place-items: center; min-width: 22px; height: 22px; padding: 0 6px;
  border-radius: var(--radius-sm); background: var(--primary); color: var(--primary-contrast);
  font-size: var(--fs-label); font-weight: var(--wght-strong); font-variant-numeric: tabular-nums; line-height: 1;
}
.theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: block; }
:root[data-theme="dark"] .theme-toggle .moon { display: none; }
.search-icon-btn { display: none; }
@media (max-width: 1179px) { .brand-date { display: none; } .searchbtn { min-width: 220px; } }
@media (max-width: 1023px) {
  .searchbtn, .planbtn, .live-pill { display: none; }
  .search-icon-btn { display: inline-flex; }
  .topbar { padding: 0 var(--sp-1); }
}
@media (max-width: 359px) { .brand-name { height: 19px; } }

/* ---------- layout (SIG): rail | content, the divider painted on the grid ---------- */
.layout { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); }
@media (min-width: 1024px) {
  .layout {
    background: linear-gradient(to right, var(--sidebar-bg) calc(var(--sidebar-w) - 1px), var(--border) calc(var(--sidebar-w) - 1px) var(--sidebar-w), transparent var(--sidebar-w));
    transition: grid-template-columns 240ms var(--ease);
  }
  :root.rail-collapsed .layout { grid-template-columns: 0 minmax(0, 1fr); background: none; }
}
.content { width: 100%; max-width: var(--content-max); min-width: 0; margin: 0 auto; padding: var(--sp-5) var(--gutter) var(--sp-9); }
.content-with-toc { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-7); }
@media (min-width: 1280px) { .content-with-toc { grid-template-columns: minmax(0, 1fr) 200px; } }
.toc { position: sticky; top: calc(var(--topbar-h) + var(--sp-5)); align-self: start; display: none; font-size: var(--fs-sm); }
@media (min-width: 1280px) { .toc { display: block; } }
.toc .label { color: var(--text-faint); padding-bottom: var(--sp-2); border-bottom: 1px solid var(--border); margin-bottom: var(--sp-2); display: block; }
.toc a { display: block; padding: 6px 0 6px 12px; color: var(--text-muted); text-decoration: none; border-left: 2px solid var(--border); line-height: var(--lh-ui); }
.toc a:hover { color: var(--text); border-left-color: var(--border-strong); }
.toc a[aria-current="true"] { color: var(--text); border-left-color: var(--accent); font-weight: var(--wght-strong); }

/* ---------- sidebar ---------- */
.sidebar {
  position: sticky; top: var(--topbar-h); height: calc(100dvh - var(--topbar-h));
  overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin;
  background: var(--sidebar-bg); padding: var(--sp-4) var(--sp-3) var(--sp-7);
}
.plan-card {
  display: block; margin: 0 0 var(--sp-3); padding: 12px;
  background: var(--surface); color: var(--text); text-decoration: none;
  border: 1px solid var(--border); border-top: var(--rule-heavy) solid var(--accent);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}
.plan-card:hover { color: var(--text); border-color: var(--border-strong); border-top-color: var(--accent); }
.plan-card .pc-top { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.plan-card .pc-top .i { width: 16px; height: 16px; }
.plan-card .pc-next { margin-top: 6px; font-size: var(--fs-xs); line-height: 1.45; color: var(--text-muted); }
.plan-card .pc-next b { color: var(--text); }
.plan-card.is-empty { border-top-color: var(--border-strong); }
.sidebar-group { margin-top: var(--sp-3); }
.sidebar-title { display: flex; align-items: center; gap: 8px; padding: 10px 10px 6px; color: var(--text-faint); }
.sec-num {                                /* section numerals: numbers mean sections, letters mean programs */
  display: inline-grid; place-items: center; width: 20px; height: 20px; flex: none;
  background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-xs);
  font: var(--wght-strong) var(--fs-label)/1 var(--font-body); font-variant-numeric: tabular-nums; letter-spacing: 0;
}
.sidebar a.nav-link, .sidebar summary {
  display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 6px 10px;
  border-radius: var(--radius-sm); color: var(--text-muted); font-size: var(--fs-sm); line-height: var(--lh-ui); text-decoration: none;
}
.sidebar a.nav-link .i { width: 16px; height: 16px; color: var(--text-faint); }
.sidebar a.nav-link:hover, .sidebar summary:hover { background: var(--surface-alt); color: var(--text); }
.sidebar a.nav-link[aria-current="page"] {
  background: var(--accent-tint); color: var(--accent-strong); font-weight: var(--wght-strong);
  box-shadow: inset 3px 0 0 var(--accent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.sidebar a.nav-link[aria-current="page"] .i { color: var(--accent-strong); }
.nav-meta, .count-pill {
  margin-left: auto; font-size: var(--fs-label); font-weight: var(--wght-strong); color: var(--text-faint);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* program items are two lines: the name, then days · dates · hours */
.sidebar a.nav-link.prog { align-items: flex-start; padding-top: 8px; padding-bottom: 8px; }
.sidebar a.nav-link.prog .bullet { margin-top: 1px; }
.nav-2 { display: flex; flex-direction: column; min-width: 0; }
.nav-2 .nav-sub { font-size: var(--fs-label); color: var(--text-faint); font-variant-numeric: tabular-nums; line-height: 1.35; margin-top: 2px; }
.nav-2 .nav-sub > span { white-space: nowrap; }   /* QA: wrap between " · " segments, never inside one */
.sidebar details > summary { list-style: none; cursor: pointer; }
.sidebar summary::-webkit-details-marker { display: none; }
.sidebar summary .chev { width: 16px; height: 16px; margin-left: auto; color: var(--text-faint); transition: transform var(--speed) var(--ease); }
.sidebar details[open] > summary .chev { transform: rotate(90deg); }
.sidebar details > .sub { margin: 2px 0 4px 21px; padding-left: 10px; border-left: 2px solid var(--ink-fill); }
.sidebar-src { margin-top: var(--sp-5); padding: var(--sp-3) 10px 0; border-top: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-faint); line-height: 1.45; }

/* ---------- drawer (<1024px) and desktop rail collapse ---------- */
.scrim {
  position: fixed; inset: 0; z-index: var(--z-scrim); background: var(--scrim);
  opacity: 0; pointer-events: none; transition: opacity var(--speed-slow) var(--ease);
}
@media (max-width: 1023px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed; left: 0; top: var(--topbar-h); z-index: var(--z-drawer);
    width: min(320px, 86vw); height: calc(100dvh - var(--topbar-h));
    transform: translateX(-102%); visibility: hidden;
    transition: transform var(--speed-slow) var(--ease), visibility 0s var(--speed-slow);
    border-right: 1px solid var(--border); box-shadow: var(--shadow-3);
  }
  body.nav-open .sidebar { transform: none; visibility: visible; transition: transform var(--speed-slow) var(--ease), visibility 0s; }
  body.nav-open .scrim { opacity: 1; pointer-events: auto; }
  body.nav-open { overflow: hidden; }
  body.nav-open .topbar { z-index: calc(var(--z-drawer) + 1); }
  .sidebar a.nav-link, .sidebar summary { min-height: var(--tap); }
  .content { padding-bottom: calc(var(--dock-h) + var(--sp-8)); }
}
@media (min-width: 1024px) {
  .sidebar { width: var(--sidebar-w); transition: transform 240ms var(--ease), visibility 0s; }
  :root.rail-collapsed .sidebar { transform: translateX(-102%); visibility: hidden; transition: transform 240ms var(--ease), visibility 0s 240ms; }
}

/* ---------- phone dock: Week · Map · Plan · Search, within thumb reach ---------- */
.dock { display: none; }
@media (max-width: 1023px) {
  .dock {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-dock);
    display: grid; grid-template-columns: repeat(4, 1fr);
    height: calc(var(--dock-h) + env(safe-area-inset-bottom)); padding-bottom: env(safe-area-inset-bottom);
    background: var(--dock-bg); border-top: 1px solid var(--border-strong);
  }
  @supports ((backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px))) {
    .dock { backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
  }
  body.nav-open .dock, body.modal-open .dock, body.kb-open .dock { display: none; }
}
.dock a, .dock button {
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  min-height: var(--tap); color: var(--text-muted); text-decoration: none;
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: 0.02em;
}
.dock .i { width: 22px; height: 22px; }
.dock [aria-current="page"] { color: var(--text); }
.dock [aria-current="page"]::before { content: ""; position: absolute; top: -1px; left: 28%; right: 28%; height: 3px; background: var(--accent); }
.dock .count { position: absolute; top: 5px; left: calc(50% + 7px); min-width: 20px; height: 20px; }

/* ---------- back to top, toast ---------- */
.to-top {
  position: fixed; right: var(--sp-4); bottom: var(--sp-4); z-index: var(--z-sticky);
  width: var(--tap); height: var(--tap); display: grid; place-items: center;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  box-shadow: var(--shadow-2); opacity: 0; pointer-events: none; transition: opacity var(--speed) var(--ease);
}
.to-top.show { opacity: 1; pointer-events: auto; }
@media (max-width: 1023px) { .to-top { bottom: calc(var(--dock-h) + var(--sp-3)); } }
.toast {
  position: fixed; left: 50%; bottom: var(--sp-5); z-index: var(--z-toast); transform: translate(-50%, 12px);
  display: flex; align-items: center; gap: var(--sp-3); max-width: min(92vw, 460px); min-height: var(--tap); padding: 8px 8px 8px 16px;
  background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-md); box-shadow: var(--shadow-3);
  font-size: var(--fs-sm); opacity: 0; pointer-events: none; transition: opacity var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.toast a, .toast button { color: var(--primary-contrast); font-weight: var(--wght-strong); min-height: var(--tap); display: inline-flex; align-items: center; padding: 0 10px; }
@media (max-width: 1023px) { .toast { bottom: calc(var(--dock-h) + var(--sp-3)); } }

/* ---------- engine additions (Agent A): scroll lock, no-JS fallbacks ---------- */
@media (max-width: 1023px) {
  body.nav-open { position: fixed; left: 0; right: 0; }        /* top: -scrollY is set by drawer.js: no jump */
}
/* Without JavaScript: no drawer, no dialogs. On phones the sidebar follows the page instead. */
.no-js .nav-toggle, .no-js [data-search-open], .no-js .theme-toggle, .no-js .planbtn, .no-js .plan-card, .no-js .star, .no-js .js-only, .no-js .to-top { display: none !important; }
@media (max-width: 1023px) {
  .no-js .layout { display: flex; flex-direction: column; }
  .no-js .layout > .content { order: 1; }
  /* z-index: auto — a flex item keeps its z-index even when static, and the drawer's would paint it over the dock */
  .no-js .sidebar { order: 2; position: static; z-index: auto; transform: none; visibility: visible; width: auto; height: auto; box-shadow: none; border-right: 0; border-top: var(--rule-heavy) solid var(--rule-ink); }
  .no-js .layout > .content { padding-bottom: var(--sp-5); }
  .no-js .dock { grid-template-columns: repeat(3, 1fr); }
}
/* ---- 20-content.css ---- */
/* ======================================================================
   site/css/20-content.css · OWNER: Agent A (core engine)
   Page anatomy and the shared class vocabulary: crumbs, .oxford, page head, sections, prose, facts,
   source line, buttons, star, badges, chips, callouts, cards/grid, toolbar, fields, view toggle,
   result count, empty state, A–Z, tables, avatars.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 20 · content: page anatomy ---------- */
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; margin-bottom: var(--sp-4); font-size: var(--fs-xs); color: var(--text-faint); }
.crumbs a { color: var(--text-muted); display: inline-flex; align-items: center; min-height: var(--tap); }
.crumbs .sep { color: var(--border-strong); }
.crumbs [aria-current="page"] { color: var(--text); }
@media (min-width: 1024px) { .crumbs a { min-height: 28px; } }

/* the Oxford rule: a heavy bar over a hairline, over every section head and the folio */
.oxford {
  padding-top: 15px;
  background:
    linear-gradient(var(--rule-ink), var(--rule-ink)) 0 0 / 100% var(--rule-heavy) no-repeat,
    linear-gradient(var(--rule-ink), var(--rule-ink)) 0 7px / 100% 1px no-repeat;
}
.page-head { margin-bottom: var(--sp-6); }
.kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: var(--sp-3); color: var(--accent-strong); }
.kicker .sec-num { background: var(--accent-strong); color: var(--accent-contrast); }
.page-head h1 { max-width: 22ch; }
.lede { margin-top: var(--sp-3); max-width: 62ch; font-size: 1.0625rem; color: var(--text-muted); }
.dek {                                    /* deks are always Newsreader italic */
  margin-top: var(--sp-3); max-width: 44ch;
  font-family: var(--font-display); font-style: italic; font-weight: 420; font-size: var(--fs-lg); line-height: var(--lh-snug); color: var(--text-muted);
}
@media (max-width: 559px) { .dek { font-size: var(--fs-md); } }
.byline { margin-top: var(--sp-3); font-size: var(--fs-xs); color: var(--text-faint); }
.head-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: var(--sp-4); }

.section { margin-top: var(--sp-8); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.sec-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px var(--sp-4); margin-bottom: var(--sp-5); }
.sec-head .sec-kicker { display: flex; align-items: center; gap: 8px; width: 100%; color: var(--text-muted); }
.sec-head h2 { flex: 1 1 auto; }
.sec-head h2 .sec-icon { width: 0.8em; height: 0.8em; margin-right: 10px; vertical-align: -0.06em; color: var(--text-muted); }
.sec-head .more { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.sub-h:has(+ .tonight), .sub-h:has(+ .themes) { border-bottom: 0; margin-bottom: var(--sp-2); }
.sub-h {
  margin: var(--sp-6) 0 var(--sp-3); padding-bottom: 6px; border-bottom: 1px solid var(--border);
  font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted);
}
.prose { max-width: var(--measure); }
.prose > * + * { margin-top: var(--sp-3); }
.prose h2 { margin-top: var(--sp-7); } .prose h3 { margin-top: var(--sp-5); }
.prose ul, .prose ol { padding-left: 1.3em; }
.prose li + li { margin-top: 6px; }

/* facts panel ("at a glance"): SIG .facts/.fact, set as a newspaper box */
.facts {
  display: flex; flex-wrap: wrap; gap: 1px;
  background: var(--border); border-top: var(--rule-heavy) solid var(--rule-ink); border-bottom: 1px solid var(--border);
  margin: var(--sp-5) 0;
}
.fact { flex: 1 1 170px; background: var(--surface); padding: 12px 14px 14px; min-width: 0; }
.fact dt { font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-faint); }
.fact dd { margin-top: 4px; font-size: var(--fs-sm); line-height: 1.45; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.fact.fact-wide { flex: 2 1 340px; }   /* QA: long values (organizer lists) take two tiles' width */
.fact dd a { font-weight: var(--wght-strong); }

.source-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin-top: var(--sp-5); padding-top: var(--sp-3);
  border-top: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-faint);
}
.source-line .i { width: 14px; height: 14px; align-self: center; }
.source-line a { color: var(--text-muted); }

.keylinks { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.pagenav { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); margin-top: var(--sp-8); padding-top: var(--sp-4); border-top: var(--rule-mid) solid var(--rule-ink); }
.pagenav a { display: flex; flex-direction: column; gap: 2px; min-height: var(--tap); padding: 10px 12px; border: 1px solid var(--border); background: var(--surface); text-decoration: none; color: var(--text); }
.pagenav a:hover { border-color: var(--border-strong); color: var(--text); }
.pagenav .label { color: var(--text-faint); }
.pagenav strong { font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); line-height: var(--lh-snug); }
.pagenav a.next { text-align: right; align-items: flex-end; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 18px; border: 2px solid transparent; border-radius: var(--radius-md);
  font-size: var(--fs-sm); font-weight: var(--wght-strong); line-height: 1.1; text-decoration: none; white-space: nowrap;
  transition: background var(--speed) var(--ease), border-color var(--speed) var(--ease), color var(--speed) var(--ease), transform var(--speed) var(--ease);
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn .i { width: 17px; height: 17px; }
.btn-primary { background: var(--primary); color: var(--primary-contrast); }
.btn-primary:hover { background: var(--accent-strong); color: var(--accent-contrast); }
.btn-river { background: var(--accent); color: var(--accent-contrast); }       /* the one "Add to My Plan" action */
.btn-river:hover { background: var(--accent-strong); color: var(--accent-contrast); }
.btn-secondary { background: var(--surface); color: var(--text); border-color: var(--border-strong); }
.btn-secondary:hover { color: var(--text); border-color: var(--text); }
.btn-ghost { color: var(--link); padding: 0 8px; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
.btn-ghost:hover { color: var(--link-hover); text-decoration-thickness: 2px; }
.btn-sm { min-height: 36px; padding: 0 12px; font-size: var(--fs-xs); }
@media (pointer: coarse), (max-width: 1023px) { .btn-sm { min-height: var(--tap); } }
.btn[disabled], .btn[aria-disabled="true"] { background: var(--surface-sunken); color: var(--text-faint); border-color: var(--border); cursor: not-allowed; transform: none; }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
@media (max-width: 559px) { .btn-row.stack-sm .btn { flex: 1 1 100%; } }

/* the star (engine contract): 44px, label names the event; on = solid ink */
.star {
  position: relative; z-index: 1; display: inline-grid; place-items: center; flex: none;
  width: var(--tap); height: var(--tap); border-radius: var(--radius-md); color: var(--text-muted);
}
.star:hover { background: var(--surface-alt); color: var(--text); }
.star .i { width: 22px; height: 22px; }
.star[aria-pressed="true"] { color: var(--text); }
.star[aria-pressed="true"] .i { fill: currentColor; }
.star.floating { position: absolute; top: 8px; right: 8px; background: var(--surface); box-shadow: var(--shadow-2); }

/* ---------- badges: 24px, 12px caps; states are always words ---------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px; min-height: 24px; padding: 3px 8px; max-width: 100%;
  border-radius: var(--radius-xs); border: 1px solid transparent;
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; line-height: 1;
  font-variant-numeric: tabular-nums; background: var(--surface-sunken); color: var(--text-muted);
}
.badge .i { width: 13px; height: 13px; }
.badge-live { background: var(--live-tint); color: var(--live-ink); }
.badge-live::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--live); flex: none; }
.badge-out, .badge-soon, .badge-started { background: transparent; border-color: var(--soon); color: var(--soon); }
.badge-past { background: var(--surface-sunken); color: var(--text-muted); }
.badge-free { background: transparent; border-color: var(--accent); color: var(--accent-strong); }
.badge-plan { background: var(--success-tint); color: var(--success); }
.badge-warn { background: var(--warning-tint); color: var(--warning); }
.badge-unconfirmed { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-muted); }

/* ---------- chips (filters): 44px, pressed = program tint + 2px edge + check + bold ---------- */
.chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.chip {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 0 14px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface);
  color: var(--text); font-size: var(--fs-sm); font-weight: var(--wght-ui); white-space: nowrap; text-decoration: none;
}
.chip:hover { border-color: var(--text); color: var(--text); }
.chip .n { color: var(--text-faint); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.chip .ck { display: none; width: 16px; height: 16px; }
.chip[aria-pressed="true"], .chip[aria-checked="true"] {
  background: var(--ink-tint); border: 2px solid var(--ink-edge); padding: 0 13px; color: var(--ink-text); font-weight: var(--wght-strong);
}
.chip:not([data-prog])[aria-pressed="true"] { background: var(--accent-tint); border-color: var(--accent); color: var(--accent-strong); }
.chip[aria-pressed="true"] .ck { display: block; }
.chip[aria-pressed="true"] .n { color: inherit; }
.chip-sep { width: 1px; align-self: stretch; margin: 6px 4px; background: var(--border-strong); }
.chip .x { width: 16px; height: 16px; }                  /* removable active-filter chip */
.chip-more { font-weight: var(--wght-strong); }
.chip-more .count { min-width: 20px; height: 20px; }

/* ---------- callouts: a boxed sidebar with a flag straddling the top rule ---------- */
.callout { position: relative; margin: var(--sp-6) 0 var(--sp-5); padding: 22px 18px 16px; border: 1px solid var(--border-strong); background: var(--surface); max-width: 72ch; }
.callout > .flag {
  position: absolute; top: 0; left: 14px; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
  background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-xs);
}
.callout > .flag .i { width: 14px; height: 14px; }
.callout p + p { margin-top: var(--sp-2); }
.callout.tone-tip { background: var(--accent-tint); border-color: var(--accent); }
.callout.tone-tip > .flag { background: var(--accent-strong); color: var(--accent-contrast); }
.callout.tone-warn { background: var(--warning-tint); border-color: var(--warning-edge); }
.callout.tone-warn > .flag { background: var(--warning); color: var(--warning-tint); }
/* "From the organizers": the program's own words, tinted in its ink, always with a named source */
.callout.tone-org { background: var(--ink-tint); border-color: var(--ink-edge); border-left: var(--rule-heavy) solid var(--ink-fill); }
.callout.tone-org > .flag { background: var(--surface); color: var(--ink-text); border: 1px solid var(--ink-edge); }
.callout.tone-org blockquote { font-family: var(--font-display); font-size: var(--fs-md); line-height: var(--lh-snug); }
.callout.tone-org cite { display: block; margin-top: var(--sp-2); font-style: normal; font-size: var(--fs-xs); color: var(--text-muted); }

/* ---------- cards grid (SIG .grid) ---------- */
.grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); }
.card { position: relative; display: block; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border); color: var(--text); text-decoration: none; }
a.card:hover, .card:has(.stretched:hover) { border-color: var(--border-strong); color: var(--text); }
.stretched::after { content: ""; position: absolute; inset: 0; z-index: 0; }
.stretched { text-decoration: none; color: inherit; }
.stretched:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; color: inherit; }

/* ---------- toolbar, fields, view toggle, result count, empty state ---------- */
.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3); margin-bottom: var(--sp-4); }
.field {
  position: relative; display: flex; align-items: center; flex: 1 1 260px; max-width: 460px; min-height: var(--tap);
  background: var(--surface); border: 1px solid var(--border-strong); border-bottom: var(--rule-mid) solid var(--rule-ink); border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.field .i { position: absolute; left: 12px; color: var(--text-faint); pointer-events: none; }
.field input { width: 100%; min-height: var(--tap); padding: 0 12px 0 40px; border: 0; background: transparent; outline: none; font-size: var(--fs-base); }
.field input::placeholder { color: var(--text-faint); opacity: 1; }
.field:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }
.select {
  min-height: var(--tap); padding: 0 34px 0 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface); font-size: var(--fs-sm); appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-muted) 50%), linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%; background-size: 5px 5px; background-repeat: no-repeat;
}
.view-toggle { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--radius-md); overflow: hidden; }
.view-toggle button { display: inline-flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 0 14px; font-size: var(--fs-sm); color: var(--text-muted); }
.view-toggle button + button { border-left: 1px solid var(--border-strong); }
.view-toggle button[aria-pressed="true"] { background: var(--primary); color: var(--primary-contrast); font-weight: var(--wght-strong); }
.result-count { font-size: var(--fs-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.result-count b { color: var(--text); }
.empty-state {
  display: grid; justify-items: start; gap: var(--sp-2); padding: var(--sp-5); max-width: 560px;
  border: 1px dashed var(--border-strong); background: var(--surface);
}
.empty-state .halftone { width: 44px; height: 44px; display: grid; place-items: center; color: var(--ink-text); }
.empty-state h2, .empty-state h3 { font-size: var(--fs-md); }
.empty-state p { color: var(--text-muted); font-size: var(--fs-sm); }
.az { display: flex; flex-wrap: wrap; gap: 2px; }
.az a { display: grid; place-items: center; min-width: 32px; min-height: var(--tap); font-weight: var(--wght-strong); font-size: var(--fs-sm); text-decoration: none; color: var(--text-muted); border-radius: var(--radius-sm); }
.az a:hover { background: var(--surface-alt); color: var(--text); }
.az a[aria-current="true"] { background: var(--primary); color: var(--primary-contrast); }
.az a[aria-disabled="true"] { color: var(--border-strong); pointer-events: none; }

/* ---------- tables: ink top rule, caps heads; below 700px every row becomes a card ---------- */
.table-wrap { overflow-x: auto; margin: var(--sp-4) 0; }
table.data { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); border-top: var(--rule-heavy) solid var(--rule-ink); }
table.data caption { caption-side: top; text-align: left; padding-bottom: var(--sp-2); font-size: var(--fs-xs); color: var(--text-faint); }
table.data th { text-align: left; vertical-align: bottom; padding: 10px 12px 8px; border-bottom: 1px solid var(--rule-ink); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); }
table.data td { padding: 12px; border-bottom: 1px solid var(--border); vertical-align: top; }
table.data td.num, table.data th.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data tbody th { vertical-align: top; padding: 12px; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); font-weight: var(--wght-strong); letter-spacing: 0; text-transform: none; color: var(--text); }
table.data td.when { font-variant-numeric: tabular-nums; white-space: nowrap; font-weight: var(--wght-strong); }
table.data td .prog-badge { white-space: nowrap; }
table.data tbody tr:hover td { background: var(--surface-alt); }
@media (max-width: 699px) {
  table.data, table.data tbody, table.data tr, table.data td, table.data tbody th { display: block; }
  table.data tbody th { padding: 0 0 4px; border: 0; font-family: var(--font-display); font-size: var(--fs-md); font-weight: var(--wght-head); letter-spacing: 0; text-transform: none; color: var(--text); }
  table.data caption { display: block; }
  table.data thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  table.data tr { padding: 10px 0; border-bottom: var(--rule-mid) solid var(--rule-ink); }
  table.data td { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; padding: 5px 0; border: 0; }
  table.data td::before { content: attr(data-label); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-faint); padding-top: 2px; }
  table.data td.num { text-align: left; }
  table.data td:empty { display: none; }   /* a stacked row never shows a label with nothing after it */
}

/* ---------- avatars ("mugs"): 4:5 rectangles; the 256px square pipeline stays sharp at these sizes ---------- */
.avatar {
  --av: 64px; position: relative; display: block; flex: none; width: var(--av); height: calc(var(--av) * 1.25);
  overflow: hidden; background: var(--ink-tint); border-radius: var(--radius-xs);
}
.avatar img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 30%; filter: var(--photo-filter); }
.avatar.s { --av: 28px; }
.avatar.m { --av: 44px; }
.avatar.l { --av: 96px; }
.avatar.mono { display: grid; place-items: center; }
.avatar.mono > span { font-family: var(--font-display); font-style: italic; font-weight: 500; color: var(--ink-text); font-size: calc(var(--av) * 0.42); line-height: 1; letter-spacing: -0.02em; }
.avatar.s.mono > span { font-size: var(--fs-label); font-style: normal; font-family: var(--font-body); font-weight: var(--wght-strong); }
.avatar-stack { display: flex; flex: none; }
.avatar-stack { gap: 3px; }

/* ---------- engine additions (Agent A) ---------- */
.spaced { margin-top: var(--sp-5); }
.h-card { font-size: var(--fs-lg); line-height: var(--lh-snug); }
/* heading anchors (QS): shown on hover and focus */
.h-anchor { margin-left: 6px; color: var(--text-faint); text-decoration: none; font-family: var(--font-body); font-weight: var(--wght-ui); opacity: 0; transition: opacity var(--speed) var(--ease); }
:is(h2, h3):hover > .h-anchor, .h-anchor:focus-visible { opacity: 1; }
@media (max-width: 699px), (hover: none) { .h-anchor { display: none; } }
/* disclosure rows in content are full touch targets */
.prose details > summary, .card details > summary, details.faq > summary { display: flex; align-items: center; min-height: var(--tap); cursor: pointer; }
/* "On this page" for narrow screens on long pages; the rail takes over at ≥ 1280px */
.toc-mobile { margin: 0 0 var(--sp-5); border: 1px solid var(--border); background: var(--surface); }
.toc-mobile > summary { display: flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 0 12px; cursor: pointer; list-style: none; font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.toc-mobile > summary::-webkit-details-marker { display: none; }
.toc-mobile > summary .chev { margin-left: auto; transition: transform var(--speed) var(--ease); }
.toc-mobile[open] > summary .chev { transform: rotate(180deg); }
.toc-mobile ul { list-style: none; padding: 0 12px 8px; }
.toc-mobile a { display: flex; align-items: center; min-height: var(--tap); color: var(--text-muted); text-decoration: none; border-top: 1px solid var(--border); font-size: var(--fs-sm); }
@media (min-width: 1280px) { .toc-mobile { display: none; } }

/* ---------- "Tonight": the time-first timetable (74px tabular time column), shared vocabulary ----------
   Used by eventRow() (build/components/event-card.mjs) on the home page, venue pages (.byday), person pages
   and program pages. Moved here from 30-home.css so no domain partial owns a shared component. */
.tonight { list-style: none; padding: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.tonight li { border-bottom: 1px solid var(--border); }
.tonight a { display: grid; grid-template-columns: 74px auto minmax(0, 1fr); align-items: start; gap: 4px 10px; min-height: var(--tap); padding: 10px 0; color: var(--text); text-decoration: none; }
.tonight a:hover .t { text-decoration: underline; text-underline-offset: 0.16em; }
.tonight time { font-weight: 700; font-variant-numeric: tabular-nums; font-size: var(--fs-base); line-height: 1.35; text-align: right; }
.tonight time small { display: block; font-size: var(--fs-label); font-weight: var(--wght-strong); color: var(--text-faint); letter-spacing: var(--track-label); }
.tonight .t { font-weight: var(--wght-strong); line-height: 1.35; }
.tonight .w { display: block; font-size: var(--fs-xs); color: var(--text-muted); font-weight: var(--wght-body); }
/* ---- 30-home.css ---- */
/* ======================================================================
   site/css/30-home.css · OWNER: Agent G (home, programs & info)
   Ticker, masthead (folio, nameplate, river rule), lead + "At this hour" ear, phase switch, Tonight,
   the week line, program cards, stats, doors.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 30 · home: ticker ---------- */
/* static, never a marquee: desktop shows what fits behind a fade; phones get a scroll-snap strip */
.ticker { display: flex; align-items: stretch; min-height: var(--tap); margin-bottom: var(--sp-5); border-top: var(--rule-mid) solid var(--rule-ink); border-bottom: 1px solid var(--border); }
.ticker-tag { display: flex; align-items: center; gap: 8px; padding-right: 12px; color: var(--text); white-space: nowrap; }
.ticker-tag::after { content: ""; width: 1px; align-self: stretch; margin: 10px 0 10px 4px; background: var(--border-strong); }
.ticker-viewport {
  flex: 1 1 auto; min-width: 0; display: flex; gap: var(--sp-5); align-items: center; padding-left: 12px;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain;
  -webkit-mask-image: linear-gradient(to right, var(--mask-ink) 90%, transparent); mask-image: linear-gradient(to right, var(--mask-ink) 90%, transparent);
}
.ticker-viewport::-webkit-scrollbar { display: none; }
.ticker-item { display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); flex: none; scroll-snap-align: start; color: var(--text); text-decoration: none; font-size: var(--fs-sm); white-space: nowrap; }
.ticker-item:hover { text-decoration: underline; color: var(--text); }
.ticker-item .ti-src { color: var(--text-faint); font-size: var(--fs-xs); }
.ticker-more { display: inline-flex; align-items: center; gap: 4px; flex: none; min-height: var(--tap); padding-left: 12px; font-size: var(--fs-sm); font-weight: var(--wght-strong); white-space: nowrap; }
@media (max-width: 699px) {
  .ticker { flex-direction: column; }
  .ticker-tag { min-height: 32px; padding: 6px 0 0; }
  .ticker-tag::after { display: none; }
  .ticker-viewport { padding-left: 0; gap: var(--sp-4); -webkit-mask-image: none; mask-image: none; }
  .ticker-item {
    width: 84%; min-height: 52px; padding: 6px 0; white-space: normal; font-size: var(--fs-xs); line-height: 1.35;
    display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 8px; align-items: center;
  }
  .ticker-item > .bullet { grid-row: span 2; }
  .ticker-item .ti-src { display: none; }
  .ticker-more { display: none; }
}

/* ---------- masthead: folio, nameplate, the river rule ---------- */
.folio {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 16px;
  padding-bottom: 7px; border-bottom: 1px solid var(--rule-ink); color: var(--text-muted);
}
.folio .today { color: var(--text); }
@media (max-width: 699px) { .folio .region, .folio .vol { display: none; } }
.nameplate { display: flex; justify-content: center; padding-top: var(--sp-5); }
.nameplate .wm { width: min(100%, 720px); height: auto; color: var(--text); }
.river { position: relative; margin-top: var(--sp-2); }
.river .rr { display: block; width: 100%; height: 44px; overflow: visible; }
.rr-line, .rr-tick { fill: none; stroke: var(--accent); stroke-width: 4; }
.river-bank { position: absolute; left: 0; top: -4px; color: var(--text-faint); line-height: 1; }
.river-caption { position: relative; height: 18px; margin-top: 4px; color: var(--text-faint); }
.river-caption > span { position: absolute; top: 0; white-space: nowrap; }
.river-caption .rc-bank { left: 0; }
.river-caption .rc-tick { left: var(--tick, 58.7%); transform: translateX(-50%); color: var(--accent-strong); }
.river-caption .rc-name { right: 0; top: -2px; font-family: var(--font-display); font-style: italic; font-size: var(--fs-sm); font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--text-muted); }
@media (max-width: 699px) {
  .river .rr { height: 30px; }
  .river-caption .rc-name { display: none; }
  .river-caption .rc-tick { left: auto; right: 0; transform: none; }
}

/* ---------- lead story + "At this hour" ear ---------- */
.lead { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-6); margin-top: var(--sp-6); }
@media (min-width: 960px) {
  .lead { grid-template-columns: minmax(0, 1.35fr) minmax(300px, 1fr); grid-template-areas: "story ear" "body ear"; grid-template-rows: auto 1fr; column-gap: var(--col-gap); row-gap: 0; }
  .lead-story { grid-area: story; } .lead-body { grid-area: body; }
  .lead > .ear { grid-area: ear; border-left: 1px solid var(--border); padding-left: var(--col-gap); }
}
.lead h1 { max-width: 17ch; }
.hero-search {
  display: flex; align-items: center; gap: 10px; width: 100%; max-width: 520px; min-height: 52px; margin-top: var(--sp-4); padding: 0 12px 0 14px;
  background: var(--surface); color: var(--text-muted); text-align: left;
  border: 1px solid var(--border-strong); border-bottom: var(--rule-mid) solid var(--rule-ink); border-radius: var(--radius-md) var(--radius-md) 0 0;
}
.hero-search:hover { color: var(--text); border-color: var(--text); }
.hero-search kbd { margin-left: auto; }
@media (max-width: 559px) { .hero-search kbd { display: none; } }
.ear-head { display: flex; align-items: center; gap: 10px; }
.ear h2 { font-size: var(--fs-lg); }
.ear .sub-h { border-bottom: 0; margin-bottom: var(--sp-2); }
.clock { display: flex; justify-content: space-between; gap: 8px; margin: 6px 0 var(--sp-3); padding-bottom: 8px; border-bottom: 1px solid var(--border); color: var(--text-muted); }
.clock .sim { color: var(--text-faint); }
.nn-group + .nn-group { margin-top: var(--sp-4); }
.nn-label { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; color: var(--text-muted); }
.nn-label.now { color: var(--live-ink); }
.nn-item { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 10px; padding: 10px 0; min-height: var(--tap); border-top: 1px solid var(--border); color: var(--text); text-decoration: none; }
.nn-group .nn-item:first-of-type { border-top: 0; }
.nn-item .bullet { grid-row: span 3; margin-top: 1px; }
.nn-item .t { font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); line-height: var(--lh-snug); }
.nn-item:hover .t { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
.nn-item .m { font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; line-height: 1.45; }
.nn-item .m .p { color: var(--ink-text); font-weight: var(--wght-strong); }
.progress { position: relative; height: 4px; margin-top: 6px; overflow: hidden; background: var(--surface-sunken); border-radius: var(--radius-xs); }
.progress > i { position: absolute; inset: 0 auto 0 0; width: var(--p, 0%); background: var(--live); }
.countdown { display: flex; align-items: baseline; gap: var(--sp-3); }
.countdown .n { font-family: var(--font-display); font-size: 3.5rem; line-height: 1; font-weight: var(--wght-head); font-variant-numeric: lining-nums tabular-nums; }

/* phase-aware first screen: html[data-phase=before|during|after]. During the week, phones read
   "At this hour" before the headline; before and after, the week line follows the H1 (title, line, body). */
[data-show] { display: none; }
[data-phase="before"] [data-show~="before"], [data-phase="during"] [data-show~="during"], [data-phase="after"] [data-show~="after"] { display: revert; }
.ear > [data-show] { display: none; }
[data-phase="before"] .ear > [data-show~="before"], [data-phase="during"] .ear > [data-show~="during"], [data-phase="after"] .ear > [data-show~="after"] { display: block; }
@media (max-width: 959px) {
  .home-top { display: flex; flex-direction: column; }
  .home-top > .mast { order: 1; } .home-top > .lead { display: contents; }
  .home-top .lead-story { order: 2; } .home-top > .wk { order: 3; } .home-top .lead-body { order: 4; } .home-top .ear { order: 5; }
  [data-phase="during"] .home-top .ear {
    order: 0; margin-bottom: var(--sp-5); padding: var(--sp-4);
    background: var(--surface); border: 1px solid var(--border); border-top: var(--rule-heavy) solid var(--live);
  }
  [data-phase="during"] .home-top .nameplate { padding-top: var(--sp-3); }
  [data-phase="during"] .home-top .nameplate .wm { width: min(100%, 420px); }
  .home-top .lead-story, .home-top .lead-body, .home-top .ear { margin-top: var(--sp-5); }
  .home-top > .wk { margin-top: var(--sp-6); }
}
@media (min-width: 960px) {
  .home-top .lead-body { margin-top: 0; }
}

/* "Tonight" (.tonight, the 74px time-first timetable) moved to 20-content.css (A): it is shared by the
   home page, venue pages, person pages and eventRow(). */

/* ---------- the week line: programs are lines, days are stations, Thu Oct 8 is the interchange ----------
   One DOM rendering: <ol class="wk-days"> of 9 day links. Each day carries four lanes in a fixed order
   (A, S, B, F) marked data-run=start|mid|end|only. Desktop draws the lanes as rows under 9 columns;
   below 700px the same list becomes nine 56px rows with the lanes running down the page. */
.wk { margin-top: var(--sp-7); }
.wk-top { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-2) var(--sp-4); margin-bottom: var(--sp-6); }
.wk-date { display: flex; flex-direction: column; align-items: center; }
.wk-top h2 { font-size: var(--fs-xl); }
.wk-note { font-size: var(--fs-xs); color: var(--text-faint); }
.wk-grid { display: grid; grid-template-columns: var(--wk-key-w) minmax(0, 1fr); border-top: var(--rule-mid) solid var(--rule-ink); border-bottom: 1px solid var(--rule-ink); }
.wk-key { list-style: none; padding: var(--wk-head) 12px 0 0; margin: 0; }
.wk-key li { display: flex; align-items: center; gap: 10px; height: var(--wk-lane); font-size: var(--fs-sm); font-weight: var(--wght-strong); line-height: 1.15; }
.wk-key li:first-child { margin-top: 8px; }
.wk-key small { display: block; font-size: var(--fs-label); font-weight: var(--wght-body); color: var(--text-muted); font-variant-numeric: tabular-nums; letter-spacing: 0; }
.wk-days { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); }
.wk-day { position: relative; display: flex; flex-direction: column; border-left: 1px solid var(--border); }
.wk-link { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; height: var(--wk-head); padding: 8px 2px; color: var(--text); text-decoration: none; }
.wk-link:hover { background: var(--surface-alt); color: var(--text); }
.wk-dow { color: var(--text-muted); }
.wk-num { font-family: var(--font-display); font-weight: 600; font-size: 1.75rem; line-height: 1; margin-top: 4px; font-variant-numeric: lining-nums tabular-nums; }
.wk-sum, .wk-chev, .wk-today { display: none; }
.wk-lanes { position: relative; display: flex; flex-direction: column; padding-top: 8px; padding-bottom: 12px; }
.wk-lanes > i { position: relative; display: block; height: var(--wk-lane); }
.wk-lanes > i[data-run]::before {                /* the line segment */
  content: ""; position: absolute; top: 50%; left: 0; right: 0; height: var(--line-w); margin-top: calc(var(--line-w) / -2); background: var(--ink-fill);
}
.wk-lanes > i[data-run="start"]::before { left: 50%; }
.wk-lanes > i[data-run="end"]::before { right: 50%; }
.wk-lanes > i[data-run="only"]::before { display: none; }
.wk-lanes > i[data-run]::after {                 /* the station */
  content: ""; position: absolute; top: 50%; left: 50%; width: 16px; height: 16px; transform: translate(-50%, -50%);
  background: var(--surface); border: 3px solid var(--ink-fill); border-radius: 50%;
}
.wk-lanes > i[data-run="start"]::after, .wk-lanes > i[data-run="end"]::after, .wk-lanes > i[data-run="only"]::after {   /* termini are bars */
  width: 6px; height: 24px; border-radius: 1px; background: var(--ink-fill); border: 0;
}
/* the silver line is cased: FotoFocus is a different kind of service */
.wk-lanes > i[data-prog="fotofocus"][data-run]::before, .wk-lanes > i[data-prog="also"][data-run]::before { border-block: 2px solid var(--ink-edge); }
.wk-lanes > i[data-prog="fotofocus"][data-run]::after, .wk-lanes > i[data-prog="also"][data-run]::after { border-color: var(--ink-edge); }
.wk-lanes > i[data-run="thru"]::after { width: 12px; height: 12px; border-width: 2px; }
.wk-off { position: absolute; top: calc(50% + 9px); z-index: 1; color: var(--text-muted); font-size: var(--fs-label); font-weight: var(--wght-strong); white-space: nowrap; }
.wk-off.l { left: 4px; } .wk-off.r { right: 4px; }
/* the interchange: one capsule over the three festival lanes on the day all three run */
.wk-day.is-interchange .wk-lanes::before {
  content: ""; position: absolute; z-index: 1; left: 50%; transform: translateX(-50%);
  top: calc(8px + var(--wk-lane) / 2 - 15px); height: calc(2 * var(--wk-lane) + 30px); width: 30px;
  background: var(--surface); border: 3px solid var(--rule-ink); border-radius: 15px;
}
.wk-x { position: absolute; left: 50%; bottom: -1px; transform: translate(-50%, 100%); padding-top: 6px; white-space: nowrap; color: var(--text); }
/* today moves; the interchange doesn't */
.wk-day[aria-current="date"] .wk-link { background: var(--primary); color: var(--primary-contrast); }
.wk-day[aria-current="date"] .wk-dow { color: var(--primary-contrast); }
.wk-day[aria-current="date"] .wk-link::before {
  content: "Today"; position: absolute; top: -2px; left: 50%; transform: translate(-50%, -100%);
  padding: 3px 7px 2px; background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase;
}
.wk-foot { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--sp-2) var(--sp-4); padding-top: var(--sp-5); font-size: var(--fs-xs); color: var(--text-muted); }
@media (min-width: 700px) and (max-width: 1099px) { .wk { --wk-key-w: 150px; } .wk-key small { display: none; } }
@media (max-width: 699px) {
  .wk-grid { grid-template-columns: minmax(0, 1fr); }
  .wk-key { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 12px; padding: 10px 0; border-bottom: 1px solid var(--border); }
  .wk-key li { height: auto; min-height: 28px; font-size: var(--fs-xs); }
  .wk-key li:first-child { margin-top: 0; }
  .wk-key small { display: none; }
  .wk-days { grid-template-columns: minmax(0, 1fr); }
  .wk-day { border-left: 0; border-top: 1px solid var(--border); }
  .wk-day:first-child { border-top: 0; }
  .wk-link {
    display: grid; grid-template-columns: 58px 72px minmax(0, 1fr) 20px; align-items: center; gap: 0 10px;
    height: auto; min-height: var(--wk-row); padding: 6px 4px 6px 8px; text-align: left;
  }
  .wk-date { flex-direction: row; align-items: baseline; gap: 6px; grid-column: 1; }
  .wk-num { margin-top: 0; font-size: 1.5rem; }
  .wk-sum { display: block; grid-column: 3; font-size: var(--fs-sm); line-height: 1.3; color: var(--text); }
  .wk-sum b { font-weight: var(--wght-strong); }
  .wk-chev { display: block; grid-column: 4; width: 18px; height: 18px; color: var(--text-faint); }
  .wk-lanes { position: absolute; top: 0; bottom: 0; left: 70px; width: 72px; flex-direction: row; padding: 0; pointer-events: none; }
  .wk-lanes > i { flex: 1 1 0; height: auto; }
  .wk-lanes > i[data-run]::before { top: 0; bottom: 0; left: 50%; right: auto; width: 5px; height: auto; margin: 0 0 0 -2.5px; }
  .wk-lanes > i[data-run="start"]::before { top: 50%; left: 50%; }
  .wk-lanes > i[data-run="end"]::before { bottom: 50%; right: auto; }
  .wk-lanes > i[data-prog="fotofocus"][data-run]::before, .wk-lanes > i[data-prog="also"][data-run]::before { border-block: 0; border-inline: 1.5px solid var(--ink-edge); }
  .wk-lanes > i[data-run]::after { width: 12px; height: 12px; border-width: 2.5px; }
  .wk-lanes > i[data-run="start"]::after, .wk-lanes > i[data-run="end"]::after, .wk-lanes > i[data-run="only"]::after { width: 16px; height: 5px; }
  .wk-off { display: none; }
  .wk-day.is-interchange .wk-lanes::before { top: 50%; left: 6px; transform: translateY(-50%); width: 50px; height: 24px; }
  .wk-x { display: none; }
  .wk-day[aria-current="date"] .wk-link { background: var(--surface); color: var(--text); box-shadow: inset 4px 0 0 var(--rule-ink); }
  .wk-day[aria-current="date"] .wk-dow { color: var(--text-muted); }
  .wk-day[aria-current="date"] .wk-link::before { display: none; }
  .wk-today { display: inline; font-weight: var(--wght-strong); }
  .wk-foot { padding-top: var(--sp-3); }
}

/* ---------- program cards ("section fronts") ---------- */
.prog-cards { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }   /* five programs: 3 + 2 on a desktop */
.prog-card { position: relative; display: flex; flex-direction: column; padding: var(--sp-4) var(--sp-4) var(--sp-3); background: var(--surface); border: 1px solid var(--border); border-top: var(--rule-heavy) solid var(--ink-fill); }
.prog-card:has(.stretched:hover) { border-color: var(--border-strong); border-top-color: var(--ink-fill); }
[data-prog="fotofocus"].prog-card { border-top-color: var(--ink-edge); }
.prog-card .pk { display: flex; align-items: flex-start; gap: 10px; color: var(--ink-text); }
.prog-card .pk .nw { white-space: nowrap; }
.lead .byline .nw { white-space: nowrap; }
.prog-card h3 { margin-top: var(--sp-2); font-size: var(--fs-lg); }
.prog-card p { margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.5; }
.prog-card dl { margin-top: var(--sp-3); font-size: var(--fs-xs); border-top: 1px solid var(--border); }
.prog-card dl div { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.prog-card dt { font-weight: var(--wght-strong); }
.prog-card dd { color: var(--text-muted); }
.prog-card .links { position: relative; z-index: 1; margin-top: auto; padding-top: var(--sp-3); display: flex; flex-wrap: wrap; gap: 0 var(--sp-3); }
.prog-card .links a { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); font-size: var(--fs-sm); font-weight: var(--wght-strong); }

/* ---------- stats and quick doors ---------- */
/* QA: fixed columns (2 on phones, 4 above) so the first tile of every row is flush with the rule; auto-fit
   wrapped rows left their first tile indented behind a stray column rule */
.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); border-top: var(--rule-heavy) solid var(--rule-ink); margin-top: var(--sp-6); }
.stat { position: relative; padding: var(--sp-3) var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--border); border-left: 1px solid var(--border); color: var(--text); text-decoration: none; min-width: 0; }
.stat:nth-child(4n+1) { padding-left: 0; border-left: 0; }
.stat .n { display: block; font-family: var(--font-display); font-weight: var(--wght-head); font-size: 2.25rem; line-height: 1.05; font-variant-numeric: lining-nums tabular-nums; }
.stat .l { font-size: var(--fs-xs); color: var(--text-muted); }
a.stat:hover .l { text-decoration: underline; }
@media (max-width: 559px) { .stats { grid-template-columns: 1fr 1fr; } .stat:nth-child(4n+1) { padding-left: var(--sp-3); border-left: 1px solid var(--border); } .stat:nth-child(odd) { padding-left: 0; border-left: 0; } }
.doors { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); }
.door { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; min-height: 64px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--border); color: var(--text); text-decoration: none; }
.door:hover { border-color: var(--text); color: var(--text); }
.door .i { width: 22px; height: 22px; }
.door strong { font-family: var(--font-display); font-size: var(--fs-md); font-weight: var(--wght-head); line-height: 1.2; }
.door span { display: block; font-size: var(--fs-xs); color: var(--text-muted); }

/* ---------- G additions: ear details, program card lines, fact tiles, highlights ---------- */
.ear .nn-st:empty { display: none; }
.ear .nn-st { font-weight: var(--wght-strong); color: var(--text); }
.ear .nn-st::before { content: "· "; font-weight: var(--wght-body); color: var(--text-muted); }   /* QA: the state word never runs into the place */
.ear [data-status="live"] .nn-st { color: var(--live-ink); }
.ear [data-status="past"] .nn-st { color: var(--text-faint); }
.ear [data-status="past"] .t { color: var(--text-muted); }
.nn-item .progress { grid-column: 2; }
.nn-more, .ear-more a { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.ear-more { margin-top: var(--sp-2); }
.nn-none, .ear-note { font-size: var(--fs-sm); color: var(--text-muted); }
.nn-onview { margin-top: var(--sp-3); font-size: var(--fs-sm); }
.nn-onview a { font-weight: var(--wght-strong); }
.nn-item > .i.bullet { width: 24px; height: 24px; color: var(--text-muted); }
.ear-recap { list-style: none; padding: 0; margin: var(--sp-3) 0 var(--sp-4); display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--border); }
.ear-recap li { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); color: var(--text-muted); }
.ear-recap b { display: block; font-family: var(--font-display); font-size: var(--fs-lg); font-weight: var(--wght-head); color: var(--text); line-height: 1.1; }
.countdown { margin: var(--sp-2) 0 var(--sp-4); }
.countdown .label { color: var(--text-muted); max-width: 16ch; }
.ticker-item .ti-t { overflow: hidden; text-overflow: ellipsis; }
.hero-search > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-card .pc-ed { margin-top: 4px; font-size: var(--fs-xs); font-weight: var(--wght-strong); color: var(--text); }
.prog-card .pc-q { font-family: var(--font-display); font-style: italic; font-size: var(--fs-sm); line-height: 1.45; }
.stats-facts { margin-top: 0; border-top: 0; }
.stats-facts .stat { display: flex; flex-direction: column; gap: 4px; }
.stats-facts .n { font-size: 1.75rem; }
.stats-facts .lp { display: flex; align-items: center; gap: 6px; font-size: var(--fs-xs); font-weight: var(--wght-strong); color: var(--ink-text); }
.stats-facts .lp .bullet { width: 18px; height: 18px; }
.stats-facts .src { margin-top: auto; font-size: var(--fs-label); color: var(--text-faint); }
.stats-facts .src a { color: var(--text-muted); }
.home-highlights { margin-top: var(--sp-2); }
/* the new-tab note (.sr-only, absolutely positioned) must stay inside the scroller, or it widens the page */
.ticker-viewport, .ticker-item { position: relative; }
/* under the "Now" and "Open now" labels the word "Now" would repeat itself; "Started" (end time not listed) stays */
.nn-group.is-now [data-status="live"] .nn-st, .nn-group.is-open [data-status="live"] .nn-st { display: none; }
/* ---- 31-program.css ---- */
/* ======================================================================
   site/css/31-program.css · OWNER: Agent G (home, programs & info)
   Program page head (plate underline) and the day-by-day themes list.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */
/* program page head: the name in display type, plate-underlined in its ink */
.prog-head { padding-top: var(--sp-4); }
.prog-head h1 { font-size: var(--fs-2xl); max-width: 18ch; }
.prog-head .kicker { color: var(--ink-text); }
.themes { list-style: none; padding: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.themes li { display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 4px 16px; padding: 12px 0; border-bottom: 1px solid var(--border); }
.themes time { font-weight: 700; font-variant-numeric: tabular-nums; }
.themes time small { display: block; font-size: var(--fs-label); font-weight: var(--wght-strong); color: var(--text-faint); letter-spacing: var(--track-label); text-transform: uppercase; }
.themes b { font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); }
.themes p { font-size: var(--fs-sm); color: var(--text-muted); }

/* ---------- G: program page sections ---------- */
.prog-head .dek { max-width: 60ch; }
/* compact time-first rows (the shared .tonight list) with a star and a state word */
.prog-rows li { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 4px; }
.prog-rows li > a { min-width: 0; }
.prog-rows .star { align-self: start; margin-top: 2px; }
.prog-rows.is-runs time small { letter-spacing: 0; font-size: var(--fs-xs); color: var(--text-muted); }
.prog-rows .pr-st:empty { display: none; }
.prog-rows .pr-st { font-weight: var(--wght-strong); color: var(--text); white-space: nowrap; }
.prog-rows .pr-st::before { content: "· "; font-weight: var(--wght-body); color: var(--text-muted); }   /* QA: the state word never runs into the place */
.prog-rows li[data-status="live"] .pr-st { color: var(--live-ink); }
.prog-rows li[data-status="live"] { box-shadow: inset 3px 0 0 var(--live); }
.prog-rows li[data-status="live"] > a { padding-left: 6px; }
.prog-rows li[data-status="past"] { background: var(--past-bg); }
.prog-rows li[data-status="past"] .t { color: var(--text-muted); font-weight: var(--wght-body); }
.prog-rows li[data-status="past"] .pr-st { color: var(--text-faint); }
.prog-sub { display: flex; align-items: center; gap: 10px; margin-top: var(--sp-6); font-size: var(--fs-lg); }
.prog-sub:first-child { margin-top: 0; }
.prog-more { margin-top: var(--sp-3); }
.prog-more a { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.prog-stats { margin-top: var(--sp-5); border-top: var(--rule-heavy) solid var(--rule-ink); }
.prog-history { margin-top: var(--sp-5); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.prog-history > summary { display: flex; align-items: center; gap: 10px; min-height: var(--tap); cursor: pointer; font-weight: var(--wght-strong); list-style: none; }
.prog-history > summary::-webkit-details-marker { display: none; }
.prog-history > summary .chev { margin-left: auto; transition: transform var(--speed) var(--ease); }
.prog-history[open] > summary .chev { transform: rotate(180deg); }
.prog-history ol { list-style: none; padding: 0 0 var(--sp-3); }
.prog-history li { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 12px; padding: 10px 0; border-top: 1px solid var(--border); font-size: var(--fs-sm); line-height: 1.5; }
.prog-tickets td:nth-child(3) { font-size: var(--fs-xs); color: var(--text-muted); max-width: 52ch; }
/* venues: a static map of stall numbers beside the venue rows */
.prog-venues { display: grid; gap: var(--sp-5); }
@media (min-width: 1100px) { .prog-venues { grid-template-columns: minmax(300px, 400px) minmax(0, 1fr); align-items: start; } .prog-map-col { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); } }
.prog-map .pin { width: 30px; height: 30px; }
.prog-map .pin-venue > span { width: 24px; height: 24px; border-width: 2px; }
.prog-map-note { margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--text-muted); }
.prog-sources { list-style: none; padding: 0; display: grid; gap: 0 var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); border-top: 1px solid var(--border); }
.prog-sources li { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.prog-src-note { margin: var(--sp-3) 0; font-size: var(--fs-sm); color: var(--text-muted); }
.faq-list { border-top: var(--rule-mid) solid var(--rule-ink); }
@media (max-width: 699px) { .prog-tickets th a { display: inline-flex; align-items: center; min-height: var(--tap); } }

/* QA: a long program's days fold (details.prog-day): the summary is the day heading, a 44px row with a chevron */
.prog-day > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-2); min-height: var(--tap); cursor: pointer; list-style: none; border-bottom: 1px solid var(--border); }
.prog-day > summary::-webkit-details-marker { display: none; }
.prog-day > summary .sub-h { margin: 0; padding: 0; border: 0; }
.prog-day > summary .i { width: 18px; height: 18px; color: var(--text-muted); transition: transform var(--speed) var(--ease); }
.prog-day[open] > summary .i { transform: rotate(180deg); }
.prog-day > summary:hover .sub-h { color: var(--text); }
.prog-day[open] > summary { border-bottom: 0; }
.prog-day[open] > .tonight { margin-bottom: var(--sp-4); }
.prog-day + .sub-h { margin-top: var(--sp-6); }

/* ---------- the program's official map (BLINK's folding map, 2026-09-24): numbers by zone, facilities, source ---------- */
.prog-map-lede { max-width: var(--measure, 68ch); }
.prog-mapzones { list-style: none; padding: 0; margin: var(--sp-3) 0 var(--sp-4); display: grid; gap: 0 var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); border-top: 1px solid var(--border); }
.prog-mapzones a { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 2px 12px; min-height: var(--tap); padding: 8px 0; border-bottom: 1px solid var(--border); color: var(--text); text-decoration: none; }
.prog-mapzones a:hover b { text-decoration: underline; text-underline-offset: 0.16em; }
.prog-mapzones .tnum { font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.prog-mapzones .faint { grid-column: 1 / -1; font-size: var(--fs-xs); }
.prog-fac { display: grid; gap: var(--sp-3) var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); margin: var(--sp-2) 0 var(--sp-3); }
.prog-fac-g .sub-h { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; }
.prog-fac-g .sub-h .i { width: 18px; height: 18px; flex: none; }
.prog-fac-g .sub-h .label { margin-left: auto; }
.prog-fac-s { font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 4px; }
.prog-fac-l { list-style: none; padding: 0; margin: 0; font-size: var(--fs-sm); }
.prog-fac-l li { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; min-height: var(--tap); border-bottom: 1px solid var(--border); }
.prog-fac-l a { display: inline-flex; align-items: center; min-height: var(--tap); }

/* participants (programs[].participants: Brand Fusion's confirmed brands): names in newspaper columns */
.prog-names { columns: 3 12em; column-gap: var(--col-gap); list-style: none; padding: 0; margin: var(--sp-3) 0 0; }
.prog-names li { break-inside: avoid; padding: 7px 0; border-top: 1px solid var(--border); font-size: var(--fs-sm); line-height: 1.3; }
/* ---- 40-schedule.css ---- */
/* ======================================================================
   site/css/40-schedule.css · OWNER: Agent D (schedule & plan)
   The Week: the sticky day strip, filters, the ongoing band, day sections, slots, the NOW line,
   the session card (.ev) and its states. From the final "Interchange" design (DESIGN.md §9.4).
   Partials are concatenated in lexical order into docs/assets/site.css. Read only tokens (var(--…));
   no color literal may appear here (the build fails on one). Domain prefixes: .ev- .evd- .dt- .slot- .sched- .plan-
   ====================================================================== */

/* ---------- 40 · schedule: the sticky day strip (the only sticky part, ≤ 76px) ---------- */
.sched-bar {
  position: sticky; top: var(--topbar-h); z-index: var(--z-sticky);
  margin: 0 calc(-1 * var(--gutter)); padding: 6px var(--gutter);
  background: var(--bg); border-bottom: 1px solid var(--border);
}
.daytabs {
  display: flex; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; scroll-padding: 0 var(--sp-6);
  background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md);
}
.daytabs::-webkit-scrollbar { display: none; }
.daytab {
  position: relative; flex: 1 0 58px; min-width: 58px; height: 62px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  color: var(--text); text-align: center; text-decoration: none;
}
.daytab:hover { background: var(--surface-alt); color: var(--text); text-decoration: none; }
.daytab + .daytab { border-left: 1px solid var(--border); }
.daytab.is-out .dt-dow { color: var(--text-faint); }
.daytab.is-out + .daytab:not(.is-out), .daytab:not(.is-out) + .daytab.is-out, .dt-all { border-left: 2px solid var(--border-strong); }
.dt-dow { font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); line-height: 1; }
.dt-num { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-daynum); line-height: 1; font-variant-numeric: lining-nums tabular-nums; }
.dt-all .dt-num { font-size: var(--fs-base); line-height: 22px; white-space: nowrap; }
.dt-ticks { display: flex; gap: 2px; height: 5px; align-items: center; margin-top: 2px; }
.dt-ticks > i { display: block; width: 9px; height: 1px; background: var(--border-strong); }                 /* empty slot keeps the order */
.dt-ticks > i[data-prog] { height: 5px; background: var(--ink-fill); border-radius: 1px; }
.dt-ticks > i[data-prog="fotofocus"], .dt-ticks > i[data-prog="also"] { box-shadow: inset 0 0 0 1px var(--ink-edge); }
.dt-n { font-size: var(--fs-label); font-weight: var(--wght-strong); line-height: 1; color: var(--text-faint); font-variant-numeric: tabular-nums; margin-top: 1px; }
.daytab.is-zero .dt-num, .daytab.is-zero .dt-n { color: var(--text-faint); }
.daytab[aria-selected="true"] { background: var(--primary); color: var(--primary-contrast); }
.daytab[aria-selected="true"] :is(.dt-dow, .dt-num, .dt-n) { color: var(--primary-contrast); }
.daytab[aria-selected="true"] .dt-ticks > i { background: var(--primary-contrast); }
.daytab[aria-selected="true"] .dt-ticks > i[data-prog] { background: var(--ink-fill); box-shadow: 0 0 0 1px var(--primary-contrast); }
.daytab.is-today::after { content: ""; position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%; background: var(--live); box-shadow: 0 0 0 2px var(--surface); }
.daytab.is-today[aria-selected="true"]::after { box-shadow: 0 0 0 2px var(--primary); }
.daytab:focus-visible { outline-offset: -3px; }
.tick-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-top: var(--sp-2); font-size: var(--fs-label); color: var(--text-muted); }
.tick-legend span { display: inline-flex; align-items: center; gap: 5px; }
.tick-legend i { display: inline-block; width: 12px; height: 5px; border-radius: 1px; background: var(--ink-fill); }
.tick-legend [data-prog="fotofocus"] > i { box-shadow: inset 0 0 0 1px var(--ink-edge); }

/* ---------- filters: program chips in one scrolling row + "Filters (n)"; the rest lives in a sheet ---------- */
.filter-row { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.filter-scroll { flex: 1 1 auto; min-width: 0; display: flex; gap: var(--sp-2); overflow-x: auto; scrollbar-width: none; padding: 3px 1px; }
.filter-scroll::-webkit-scrollbar { display: none; }
.filter-scroll > * { flex: none; }
@media (max-width: 699px) {
  .filter-scroll { -webkit-mask-image: linear-gradient(to right, var(--mask-ink) 86%, transparent); mask-image: linear-gradient(to right, var(--mask-ink) 86%, transparent); padding-right: 24px; }
}
@media (min-width: 700px) { .filter-scroll { flex-wrap: wrap; overflow: visible; } }
.chip.is-zero:not([aria-pressed="true"]) { color: var(--text-faint); }
.sched-status { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px var(--sp-3); margin-top: var(--sp-3); }
.sched-status .result-count { flex: 1 1 280px; }
.sched-tools { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.active-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }
.active-chips .chip { min-height: 36px; padding: 0 8px 0 12px; font-size: var(--fs-xs); }
@media (pointer: coarse) { .active-chips .chip { min-height: var(--tap); } }
.sched-map { margin-top: var(--sp-4); }
.sched-map .unk { padding: var(--sp-4); border: 1px dashed var(--border-strong); background: var(--surface); width: 100%; }
/* the filter sheet's own pieces (the frame is .modal.sheet in 80-dialogs.css) */
.sheet-h { font-size: var(--fs-lg); }
.sheet-h:focus { outline: none; }
.sheet .sf-q { max-width: none; margin-top: var(--sp-3); }
.sheet .sf-venue { width: 100%; }
.sheet .sf-note { margin-top: var(--sp-4); font-size: var(--fs-xs); }
.sheet .chip-row { gap: var(--sp-2); }

/* ---------- until the schedule script has picked the day, keep the list still (never forever) ---------- */
.js:not(.cw-ready) .sched-days { visibility: hidden; animation: sched-reveal 0s linear 2.5s forwards; }
@keyframes sched-reveal { to { visibility: visible; } }

/* ---------- "All day and all night": exhibitions, BLINK nights, the Biennial ---------- */
.ongoing { margin-top: var(--sp-5); padding: 12px var(--sp-4) var(--sp-2); background: var(--surface-alt); border: 1px solid var(--border); }
.ongoing-head { display: flex; align-items: center; gap: 8px; color: var(--text-muted); padding-bottom: 8px; font-family: var(--font-body); }
.ongoing-head .n { color: var(--text-faint); }
.ongoing-list { display: grid; gap: 0 var(--col-gap); grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }
.ongoing .ev {
  grid-template-columns: minmax(0, 1fr) var(--tap);
  grid-template-areas: "meta star" "title star" "when when" "where where" "more more";
  padding: 10px 0 12px 14px; background: transparent; border: 0; border-top: 1px solid var(--border);
}
.ongoing .ev::before { top: 12px; bottom: 12px; left: 0; width: 4px; }
.ongoing .ev-title { font-size: var(--fs-base); margin-top: 4px; }
.ongoing .ev-when { margin-top: 4px; font-size: var(--fs-xs); line-height: 1.5; }
.ongoing .ev-where { font-size: var(--fs-xs); }
.ongoing .ev .star { margin-top: -4px; }
.ongoing .ev[data-status="live"] { outline: 0; background: transparent; padding-bottom: 12px; }
.ongoing .ev-progress { display: none; }
.sched:not(.is-today) .ongoing .ev-status { display: none; }         /* live words only when the day shown is today, */
.sched:not(.is-today) .ongoing .ev[data-status] { background: transparent; }  /* and no state tint without its word */
.sched:not(.is-today) .ongoing .ev[data-status="past"] .ev-title a { color: var(--text); }
.ongoing-more { border-top: 1px solid var(--border); }
.ongoing-more > summary {
  display: flex; align-items: center; gap: 8px; min-height: var(--tap); cursor: pointer; list-style: none;
  font-size: var(--fs-sm); color: var(--text-muted); font-variant-numeric: tabular-nums;
}
.ongoing-more > summary::-webkit-details-marker { display: none; }
.ongoing-more > summary b { color: var(--text); }
.ongoing-more > summary .chev { width: 16px; height: 16px; transition: transform var(--speed) var(--ease); }
.ongoing-more[open] > summary .chev { transform: rotate(90deg); }
.ongoing-more .ongoing-list { padding-bottom: var(--sp-2); }

/* ---------- day sections ---------- */
.sched-day { margin-top: var(--sp-6); }
.sched-day-h {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--sp-3); margin-bottom: var(--sp-4); padding-top: 15px;
  background: linear-gradient(var(--rule-ink), var(--rule-ink)) 0 0 / 100% var(--rule-heavy) no-repeat, linear-gradient(var(--rule-ink), var(--rule-ink)) 0 7px / 100% 1px no-repeat;
  font-size: var(--fs-xl);
}
.sched-day-n { color: var(--text-muted); }
.sched-none { margin: var(--sp-2) 0 var(--sp-4); }
[data-sched-empty] { margin-top: var(--sp-6); }

/* ---------- time slots: a rail on desktop, sticky slot headings on phones ---------- */
.slots { position: relative; }
.slot { position: relative; }
.js:not(.cw-ready) .slot { content-visibility: auto; contain-intrinsic-size: auto 360px; }  /* first paint: skip the ~500 cards the script is about to hide */
.slot-head { font-family: var(--font-body); letter-spacing: 0; line-height: 1.2; color: var(--text); font-weight: 400; }
.slot-time { font-size: 1.125rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.slot-time .ampm { font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); color: var(--text-muted); margin-left: 3px; }
.slot-rel { display: block; font-size: var(--fs-label); font-weight: var(--wght-strong); color: var(--text-faint); font-variant-numeric: tabular-nums; }
.slot-rel:empty { display: none; }
.slot[data-status="live"] .slot-rel { color: var(--live-ink); }
.slot-cards { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
@media (min-width: 700px) {
  .slots::before { content: ""; position: absolute; top: 6px; bottom: 0; left: calc(var(--rail-time-w) + 10px); width: var(--rule-mid); background: var(--rule-ink); }
  .slot { display: grid; grid-template-columns: var(--rail-time-w) minmax(0, 1fr); column-gap: 30px; padding-bottom: var(--sp-6); }
  .slot-head { position: sticky; top: calc(var(--topbar-h) + var(--sched-bar-h) + var(--sp-2)); align-self: start; text-align: right; padding-top: 4px; }
  .slot-head::after {                     /* the station on the rail: open = upcoming, filled = ended, river = on now */
    content: ""; position: absolute; top: 8px; right: -21px; width: 14px; height: 14px; border-radius: 50%;
    background: var(--bg); border: 3px solid var(--rule-ink);
  }
  .slot[data-status="past"] .slot-head::after { background: var(--rule-ink); }
  .slot[data-status="live"] .slot-head::after { border-color: var(--live); background: var(--live); box-shadow: 0 0 0 3px var(--bg); }
  .slot-time { display: block; }
  .slot-time .ampm { display: block; margin: 2px 0 0; }
  .slot-rel { margin-top: 4px; }
}
@media (max-width: 699px) {
  .slot { padding-bottom: var(--sp-4); }
  .slot-head {
    position: sticky; top: calc(var(--topbar-h) + var(--sched-bar-h)); z-index: 2;
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; min-height: 44px; padding: 10px 0 8px; margin-bottom: var(--sp-3);
    background: var(--bg); border-bottom: 1px solid var(--border-strong);
  }
  .slot-time { font-size: var(--fs-base); }
  .slot-rel { font-size: var(--fs-label); }
}

/* the NOW line: a river-green rule across the list at the current minute */
.now-line { position: relative; display: flex; align-items: center; gap: 10px; margin: 0 0 var(--sp-5); }
.now-line::after { content: ""; flex: 1; height: 3px; background: var(--live); }
.now-line span { padding: 3px 8px; background: var(--accent); color: var(--accent-contrast); border-radius: var(--radius-xs); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; font-variant-numeric: tabular-nums; white-space: nowrap; }
@media (min-width: 700px) { .now-line span { min-width: calc(var(--rail-time-w) + 20px); text-align: center; } }

/* ended slots fold into a <details> (it works without JS once drawn) */
details.earlier { margin-bottom: var(--sp-5); border: 1px dashed var(--border-strong); background: var(--surface); }
details.earlier > summary {
  display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 8px 12px; cursor: pointer; list-style: none;
  font-size: var(--fs-sm); color: var(--text-muted); font-variant-numeric: tabular-nums;
}
details.earlier > summary::-webkit-details-marker { display: none; }
details.earlier > summary b { color: var(--text); }
details.earlier > summary .chev { width: 16px; height: 16px; transition: transform var(--speed) var(--ease); }
details.earlier[open] > summary .chev { transform: rotate(90deg); }
details.earlier[open] > summary { border-bottom: 1px dashed var(--border-strong); }
details.earlier > .slots { margin: var(--sp-4) var(--sp-3) 0; }
details.earlier .slot-head { background: var(--surface); }
details.earlier .slot-head::after { background: var(--surface); }
details.earlier .slot[data-status="past"] .slot-head::after { background: var(--rule-ink); }

/* ---------- the session card (engine contract: article.ev > .ev-when + .ev-body + .star) ---------- */
.ev {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) var(--tap);
  grid-template-areas: "meta star" "title star" "when when" "where where" "people people" "tags tags" "note note" "more more";
  column-gap: 4px; padding: 12px 4px 14px calc(var(--stripe-w) + 12px);
  background: var(--surface); border: 1px solid var(--border);
}
.ev::before {                              /* the program stripe; the silver line is cased in graphite */
  content: ""; position: absolute; top: -1px; bottom: -1px; left: -1px; width: var(--stripe-w);
  background: var(--ink-fill); box-shadow: inset 0 0 0 1.5px var(--ink-edge);
}
.ev-body { display: contents; }
.ev-meta { grid-area: meta; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-height: 24px; }
.ev-kind { font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-faint); }
.ev-title { grid-area: title; margin-top: 6px; font-size: var(--fs-md); line-height: var(--lh-snug); font-weight: var(--wght-head); }
.ev-title a { color: var(--text); text-decoration: none; }
.ev-title a::after { content: ""; position: absolute; inset: 0; }        /* the whole card opens the event */
.ev-title a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
.ev-when { grid-area: when; display: block; margin-top: 8px; line-height: 1.7; font-size: var(--fs-sm); font-weight: var(--wght-strong); font-variant-numeric: tabular-nums; padding-right: 8px; }
.ev-when .unk, .ev-dates { font-weight: var(--wght-body); }
.ev-dates { color: var(--text-muted); }
.ev-where { grid-area: where; display: flex; align-items: baseline; gap: 6px; margin-top: 2px; padding-right: 8px; font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.4; }
.ev-where .i { width: 14px; height: 14px; align-self: center; flex: none; }
.ev-where a { position: relative; z-index: 1; color: inherit; }
.ev-where .unk { margin-left: 4px; }
.ev-room { color: var(--text-faint); }
.ev-stall {                                /* the venue's stall number, as on its map pin (DESIGN.md §4.6) */
  display: inline-grid; place-items: center; min-width: 20px; height: 18px; padding: 0 3px; margin-right: 6px; vertical-align: 1px;
  border: 1px solid var(--border-strong); border-bottom: 3px solid var(--ink-fill); border-radius: var(--radius-xs);
  font-size: var(--fs-label); font-weight: 750; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums;
}
.ev-people { grid-area: people; display: flex; align-items: center; gap: 10px; margin-top: 10px; padding-right: 8px; font-size: var(--fs-xs); line-height: 1.35; color: var(--text-muted); }
.ev-people b { color: var(--text); }
.ev-people a { position: relative; z-index: 1; color: inherit; text-decoration: none; }
.ev-people a:hover b { text-decoration: underline; }
.ev-tags { grid-area: tags; margin-top: 10px; padding-right: 8px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; color: var(--text-faint); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; }
.ev-tags .free { color: var(--accent-strong); }
.ev .star { grid-area: star; align-self: start; margin-top: -8px; }
.ev-more { grid-area: more; margin-top: 8px; font-size: var(--fs-sm); }
.ev-more > summary { min-height: var(--tap); display: flex; align-items: center; cursor: pointer; color: var(--link); position: relative; z-index: 1; }
.ev-more > :not(summary) { position: relative; z-index: 1; max-width: var(--measure); }
.ev-more > p + p { margin-top: var(--sp-2); }
.js .ev-more { display: none; }                                          /* JS opens the dialog instead */
.ev-status:empty { display: none; }
.ev-when > * + .ev-status, .ev-when > .unk, .ev-when > .badge { margin-left: 8px; }
.ev-status {
  vertical-align: 1px; display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 8px; border: 1px solid var(--soon); color: var(--soon); border-radius: var(--radius-xs);
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; white-space: nowrap;
}
:is(.ev, .evd, .plan-item)[data-status="live"] .ev-status { background: var(--live-tint); color: var(--live-ink); border-color: transparent; }
:is(.ev, .evd, .plan-item)[data-status="live"] .ev-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--live); }
:is(.ev, .evd, .plan-item)[data-status="past"] .ev-status { background: var(--surface-sunken); color: var(--text-muted); border-color: transparent; }
/* states: live = river outline + progress; past = a surface tint (never opacity) */
.ev[data-status="live"] { background: color-mix(in srgb, var(--live-tint) 40%, var(--surface)); outline: 2px solid var(--live); outline-offset: -1px; }
.ev[data-status="past"] { background: var(--past-bg); }
.ev[data-status="past"] .ev-title a { color: var(--text-muted); }
.ev[data-cancelled] .ev-title a { text-decoration: line-through; color: var(--text-muted); }
.ev-progress { position: absolute; left: calc(var(--stripe-w) + 12px); right: 12px; bottom: 6px; height: 4px; background: var(--surface-sunken); border-radius: var(--radius-xs); overflow: hidden; }
.ev-progress > i { position: absolute; inset: 0 auto 0 0; width: var(--p, 0%); background: var(--live); }
.ev[data-status="live"] { padding-bottom: 20px; }
/* plan overlap, printed with its length */
.ev-conflict {
  grid-area: note; position: relative; z-index: 1; display: flex; align-items: flex-start; gap: 8px; margin: 12px 8px 0 0; padding: 8px 10px;
  background: var(--warning-tint); color: var(--warning); border-left: 3px solid var(--warning-edge); font-size: var(--fs-xs); font-weight: var(--wght-strong); line-height: 1.4;
}
.ev-conflict .i { width: 16px; height: 16px; margin-top: 1px; flex: none; }
.ev.is-hit { box-shadow: 0 0 0 3px var(--focus); }                     /* deep-link target */
.ev:target { scroll-margin-top: calc(var(--topbar-h) + var(--sched-bar-h) + 56px); }
@media (max-width: 699px) {
  .ev { padding-top: 10px; padding-bottom: 12px; }
  .ev-title { margin-top: 4px; }
}
/* ---- 41-plan.css ---- */
/* ======================================================================
   site/css/41-plan.css · OWNER: Agent D (schedule & plan)
   My Plan (DESIGN.md §9.10): actions, the shared-plan prompt, days, items with a 74px tabular time
   column, overlaps (.ev-conflict from 40-schedule.css) and walking gap hints.
   Tokens only; no color literal (the build fails on one).
   ====================================================================== */
.plan-bar { margin-bottom: var(--sp-2); }
.plan-bar .result-count { margin-top: var(--sp-3); }
.plan-confirm { margin-top: var(--sp-3); padding: var(--sp-3) var(--sp-4); border: 1px solid var(--warning-edge); background: var(--warning-tint); max-width: 560px; }
.plan-confirm p { margin-bottom: var(--sp-3); font-weight: var(--wght-strong); color: var(--text); }
.plan-shared { margin-top: var(--sp-3); }
.plan-shared .btn-row { margin-top: var(--sp-3); }
.plan-loading { margin-top: var(--sp-5); }
[data-plan-empty] .empty-state { margin-top: var(--sp-2); }
/* ---------- by day, overlaps with their length, walking gaps ---------- */
.plan-day { margin-top: var(--sp-6); }
.plan-day > h2 { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding-bottom: 6px; border-bottom: var(--rule-mid) solid var(--rule-ink); font-size: var(--fs-lg); }
.plan-list { list-style: none; padding: 0; }
.plan-item { position: relative; display: grid; grid-template-columns: 74px minmax(0, 1fr) var(--tap); gap: 2px 12px; align-items: start; padding: 12px 0; border-bottom: 1px solid var(--border); }
.plan-item time { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; line-height: 1.35; padding-top: 2px; }
.plan-item time small { display: block; font-size: var(--fs-label); color: var(--text-faint); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; line-height: 1.3; }
.plan-item time small.rng { white-space: nowrap; letter-spacing: 0.04em; }   /* QA: a date range ("Oct 8–11") no longer breaks at its dash */
.plan-item .t { font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); line-height: var(--lh-snug); }
.plan-item .t a { color: var(--text); text-decoration: none; }
.plan-item .t a:hover { text-decoration: underline; text-underline-offset: 0.16em; }
.plan-item .m { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-top: 6px; font-size: var(--fs-xs); color: var(--text-muted); }
.plan-item .m a { color: inherit; }
.plan-item .m .unk { font-size: var(--fs-xs); }
.plan-item .star { margin-top: -6px; }
.plan-item[data-status="past"] { background: var(--past-bg); }
.plan-item[data-status="past"] .t a { color: var(--text-muted); }
.plan-item[data-status="live"] { box-shadow: inset 3px 0 0 var(--live); }
.plan-item .ev-conflict { grid-column: 2 / -1; margin: 8px 0 0; }
.plan-glyph { display: flex; justify-content: flex-end; padding-top: 2px; }
.gap-hint { display: flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 6px 0 6px 86px; font-size: var(--fs-xs); color: var(--text-muted); border-bottom: 1px solid var(--border); }
.gap-hint .i { width: 16px; height: 16px; flex: none; }
.gap-hint.long { color: var(--warning); }
@media (max-width: 559px) {
  .plan-item { grid-template-columns: 58px minmax(0, 1fr) var(--tap); gap: 2px 10px; }
  .gap-hint { padding-left: 68px; }
}
/* ---- 50-map.css ---- */
/* ======================================================================
   site/css/50-map.css · OWNER: Agent E (map, venues & visit)
   Map box, basemap, labels, pins, clusters, edge chip, selection card, panel and sheet, the map page's
   list, and the mini-map. From the final "Interchange" design (DESIGN.md §9.7). Partials are concatenated
   in lexical order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 50 · map: a token-themed OSM basemap with an HTML pin overlay ---------- */
.map-box { border: 1px solid var(--border-strong); background: var(--surface); min-width: 0; }
.map-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2); padding: 4px 4px 4px 12px; border-bottom: 1px solid var(--border); }
.map-bar .label { color: var(--text-muted); margin: 0; }
.map-bar-acts { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.map-view {
  position: relative; overflow: hidden; width: 100%; aspect-ratio: var(--map-ratio, 4 / 3); max-height: 72vh; background: var(--map-bg);
  touch-action: none; user-select: none; -webkit-user-select: none; cursor: grab; outline-offset: -3px;
}
.map-view.is-dragging { cursor: grabbing; }
.map-view.is-dragging .pin { pointer-events: none; }
.map-view.is-loading::after { content: "Loading the map…"; position: absolute; left: 12px; bottom: 10px; font-size: var(--fs-xs); color: var(--text-muted); }
.map-base { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.map-labels, .map-pins { position: absolute; inset: 0; }
.map-labels { pointer-events: none; }
/* level of detail: minor streets appear as you zoom in (data-lod is set by features/map.js) */
.map-view[data-lod="0"] .m-minor { display: none; }
.map-view[data-lod="0"] .m-tertiary { opacity: 0.7; }
.map-fail { position: absolute; left: 12px; right: 12px; bottom: 12px; padding: 8px 12px; background: var(--surface); border: 1px solid var(--border-strong); }

/* labels: 12px caps with a halo; the river in italic serif; streets and bridges follow their angle (--a) */
.map-label {
  position: absolute; transform: translate(-50%, -50%) rotate(var(--a, 0deg)); white-space: nowrap; line-height: 1;
  font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--map-label);
  text-shadow: 0 0 2px var(--map-label-halo), 0 0 3px var(--map-label-halo), 0 0 4px var(--map-label-halo);
}
.map-label.water { font-family: var(--font-display); font-style: italic; font-size: var(--fs-sm); font-weight: 500; letter-spacing: 0.02em; text-transform: none; }
.map-label.state { color: var(--text-faint); }
.map-label.park, .map-label.bridge { font-family: var(--font-display); font-style: italic; font-weight: 500; letter-spacing: 0.01em; text-transform: none; color: var(--text-muted); }
.map-label.street { font-weight: var(--wght-ui); letter-spacing: 0.01em; text-transform: none; color: var(--text-muted); }

/* pins: HTML buttons; the visible mark is small, the hit area is always 44px */
.pin {
  position: absolute; z-index: 1; display: grid; place-items: center; transform: translate(-50%, -50%);
  width: var(--tap); height: var(--tap); padding: 0; border-radius: 50%; color: var(--map-pin-ink); background: none; border: 0;
}
button.pin { cursor: pointer; }
.pin:hover, .pin:focus-visible, .pin[aria-pressed="true"] { z-index: 3; }
.pin:focus-visible { outline: 3px solid var(--focus); outline-offset: -3px; }
.pin-venue > span {                                  /* the station: a disc ringed in the program ink, numbered like its list row */
  display: grid; place-items: center; min-width: var(--map-pin); height: var(--map-pin); padding: 0 3px; border-radius: 999px;
  background: var(--map-pin-bg); border: 3px solid var(--ink-edge); box-shadow: var(--shadow-1);
  font-size: var(--fs-label); font-weight: 750; font-variant-numeric: tabular-nums; line-height: 1;
}
.pin-venue[data-prog2] > span { border-color: transparent; background: linear-gradient(var(--map-pin-bg), var(--map-pin-bg)) padding-box, conic-gradient(var(--ink-edge) 0 50%, var(--ink-fill-2) 0 100%) border-box; }
button.pin-venue:hover > span { background: var(--primary); color: var(--primary-contrast); border-color: var(--primary); }
/* selected: inverted to ink, larger, with a river ring, so it never reads as a cluster count */
.pin-venue[aria-pressed="true"] > span { min-width: 36px; height: 36px; background: var(--primary); color: var(--primary-contrast); border-color: var(--map-pin-bg); box-shadow: 0 0 0 3px var(--accent); font-size: var(--fs-sm); }
/* an artwork: the program's own shape (BLINK diamond, Art Week square, …), on a paper halo */
.pin-work { --pshape: var(--shape-diamond); }
.pin-work[data-prog="caw"] { --pshape: var(--shape-square); }
.pin-work[data-prog="scw"] { --pshape: var(--shape-circle); }
.pin-work[data-prog="brandfusion"] { --pshape: var(--shape-octagon); }
.pin-work[data-prog="fotofocus"], .pin-work[data-prog="also"] { --pshape: var(--shape-hexagon); }
.pin-work > span { position: relative; width: 20px; height: 20px; background: var(--map-pin-bg); clip-path: var(--pshape); }
.pin-work > span::after { content: ""; position: absolute; inset: 3px; background: var(--ink-fill); clip-path: var(--pshape); }
.pin-work[data-prog="fotofocus"] > span::after, .pin-work[data-prog="also"] > span::after { background: var(--ink-edge); }
button.pin-work:hover > span, .pin-work[aria-pressed="true"] > span { background: var(--primary); }
.pin-work[aria-pressed="true"] > span { width: 26px; height: 26px; }
/* a place to stay: the bed glyph on a square tag; a program room block gets the program edge */
.pin-stay > span { display: grid; place-items: center; width: 24px; height: 24px; border-radius: var(--radius-xs); background: var(--map-pin-bg); border: 2px solid var(--ink-edge); box-shadow: var(--shadow-1); }
.pin-stay .i { width: 14px; height: 14px; }
button.pin-stay:hover > span, .pin-stay[aria-pressed="true"] > span { background: var(--primary); color: var(--primary-contrast); border-color: var(--primary); }
/* transit: a small station ring; food and drink: a dot */
.pin-stop > span { width: 14px; height: 14px; border-radius: 50%; background: var(--map-pin-bg); border: 3px solid var(--map-rail); }
.pin-food > span { width: 12px; height: 12px; border-radius: 50%; background: var(--text-muted); border: 2px solid var(--map-pin-bg); box-shadow: 0 0 0 1px var(--text-muted); }
button.pin-stop:hover > span, .pin-stop[aria-pressed="true"] > span, button.pin-food:hover > span, .pin-food[aria-pressed="true"] > span { background: var(--primary); border-color: var(--primary); width: 18px; height: 18px; }
/* a BLINK facility (restrooms, Oasis Station, merch, hospitality zone, hike departure, drone viewing): a dark square tag with
   its glyph, like the printed map's black symbols; the glyph and the list row's words say which one it is */
.pin-facility > span { display: grid; place-items: center; width: 24px; height: 24px; border-radius: var(--radius-sm); background: var(--primary); color: var(--primary-contrast); border: 2px solid var(--map-pin-bg); box-shadow: var(--shadow-1); }
.pin-facility .i { width: 15px; height: 15px; }
button.pin-facility:hover > span, .pin-facility[aria-pressed="true"] > span { background: var(--accent-strong); color: var(--accent-contrast); }
.pin-facility[aria-pressed="true"] > span { width: 30px; height: 30px; }
/* hovering a list row lights its pin */
.pin.is-hi > span { outline: 3px solid var(--focus); outline-offset: 2px; }
.pin.is-live::after {                                /* live: a river ring that pulses outward (static under reduced motion) */
  content: ""; position: absolute; inset: 4px; border-radius: 50%; border: 3px solid var(--live);
  animation: cw-pulse var(--pulse) var(--ease-out) infinite; pointer-events: none;
}
.pin-cluster > span {                                /* count on a ring split by program share (--a --s --b --x --f, --o = no program; x = Brand Fusion) */
  --tot: calc(var(--a, 0) + var(--s, 0) + var(--b, 0) + var(--x, 0) + var(--f, 0) + var(--o, 0));
  --pa: calc(var(--a, 0) / var(--tot) * 100%); --ps: calc(var(--pa) + var(--s, 0) / var(--tot) * 100%); --pb: calc(var(--ps) + var(--b, 0) / var(--tot) * 100%); --px: calc(var(--pb) + var(--x, 0) / var(--tot) * 100%); --pf: calc(var(--px) + var(--f, 0) / var(--tot) * 100%);
  display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; border: 5px solid transparent; color: var(--primary-contrast);
  --ring: conic-gradient(var(--prog-caw) 0 var(--pa), var(--prog-scw) 0 var(--ps), var(--prog-blink) 0 var(--pb), var(--prog-brandfusion) 0 var(--px), var(--prog-fotofocus-edge) 0 var(--pf), var(--border-strong) 0 100%);
  background: linear-gradient(var(--primary), var(--primary)) padding-box, var(--ring) border-box;
  font-size: var(--fs-label); font-weight: 750; font-variant-numeric: tabular-nums; box-shadow: var(--shadow-1);
}
.pin-cluster:hover > span, .pin-cluster.is-hi > span { background: linear-gradient(var(--accent-strong), var(--accent-strong)) padding-box, var(--ring) border-box; color: var(--accent-contrast); }
.pin-cluster.is-hi > span { outline: 3px solid var(--focus); outline-offset: 2px; }
.pin-you { z-index: 4; pointer-events: none; }
.pin-you > span { width: 16px; height: 16px; border-radius: 50%; background: var(--focus); box-shadow: 0 0 0 4px var(--map-pin-bg), 0 0 0 5px var(--focus); }

/* controls: zoom, the edge chip, the wheel hint, the selection card */
.map-zoom { position: absolute; z-index: 5; top: 10px; right: 10px; display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-1); }
.map-zoom button { display: grid; place-items: center; width: var(--tap); height: var(--tap); color: var(--text); background: none; border: 0; }
.map-zoom button + button { border-top: 1px solid var(--border); }
.map-zoom button:hover { background: var(--surface-alt); }
.map-edge {
  position: absolute; z-index: 5; left: 50%; bottom: 10px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); max-width: calc(100% - 20px); padding: 0 12px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); border-radius: var(--radius-md); box-shadow: var(--shadow-2);
  font-size: var(--fs-xs); font-weight: var(--wght-strong); text-align: left; line-height: 1.25;
}
.map-edge > span { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.map-edge:hover { border-color: var(--text); }
.map-edge.at-top { top: 10px; bottom: auto; max-width: calc(100% - 84px); }
.map-edge .i { flex: none; }
.map-edge .dir-south { transform: rotate(90deg); } .map-edge .dir-north { transform: rotate(-90deg); } .map-edge .dir-west { transform: rotate(180deg); }
.map-view:has(.map-card:not([hidden])) .map-edge { display: none; }
.map-hint { position: absolute; z-index: 6; left: 50%; top: 50%; transform: translate(-50%, -50%); margin: 0; padding: 8px 14px; background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-md); font-size: var(--fs-sm); font-weight: var(--wght-strong); pointer-events: none; }
.map-card {
  position: absolute; z-index: 6; left: 10px; right: 64px; bottom: 10px; max-width: 360px; padding: 10px 12px; cursor: auto;
  background: var(--surface); border: 1px solid var(--border-strong); border-top: var(--rule-heavy) solid var(--rule-ink); box-shadow: var(--shadow-2);
}
.map-card h3 { font-size: var(--fs-md); padding-right: 36px; margin: 2px 0 2px; }
.map-card .muted { font-size: var(--fs-xs); }
.map-card .btn-row { margin-top: var(--sp-2); }
.map-card-x { position: absolute; top: 2px; right: 2px; display: grid; place-items: center; width: var(--tap); height: var(--tap); color: var(--text-muted); background: none; border: 0; }
.map-card-list { list-style: none; padding: 0; margin: 4px 0 0; }
.map-card-list button { display: block; width: 100%; min-height: var(--tap); padding: 6px 4px; text-align: left; background: none; border: 0; border-top: 1px solid var(--border); color: var(--text); font-size: var(--fs-sm); }

/* legend + attribution */
.map-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 2px var(--sp-4); padding: 6px 12px; border-top: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-muted); }
.map-legend > span { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; }
.map-legend > span[hidden] { display: none; }
.lg-station { width: 14px; height: 14px; border-radius: 50%; border: 3px solid var(--rule-ink); background: var(--map-pin-bg); }
.lg-work { width: 10px; height: 10px; transform: rotate(45deg); background: var(--prog-blink); }
.lg-stay { width: 12px; height: 12px; border-radius: var(--radius-xs); border: 2px solid var(--rule-ink); background: var(--map-pin-bg); }
.lg-stop { width: 12px; height: 12px; border-radius: 50%; border: 3px solid var(--map-rail); background: var(--map-pin-bg); }
.lg-food { width: 10px; height: 10px; border-radius: 50%; background: var(--text-muted); }
.lg-facility { display: grid; place-items: center; width: 18px; height: 18px; border-radius: var(--radius-xs); background: var(--primary); color: var(--primary-contrast); }
.lg-facility .i { width: 13px; height: 13px; }
.lg-live { width: 14px; height: 14px; border-radius: 50%; border: 3px solid var(--live); }
.lg-cluster { width: 16px; height: 16px; border-radius: 50%; background: var(--primary); box-shadow: 0 0 0 3px var(--prog-blink); }
.lg-tram { width: 22px; height: 0; border-top: 2px dashed var(--map-rail); }
.map-attrib { margin-left: auto; display: inline-flex; align-items: center; min-height: var(--tap); color: var(--text-muted); font-size: var(--fs-label); }

/* the no-JS map: the home frame, static pins, not interactive */
.map-static { position: absolute; inset: 0; cursor: auto; }
.map-static .pin { pointer-events: none; }
.no-js .map-view { touch-action: auto; cursor: auto; }
@media (max-width: 699px) { .map-view { aspect-ratio: var(--map-ratio, 1 / 1); } }

/* ---------- the map page (map.html): filters, the map, the side panel / bottom sheet, the list ---------- */
.map-ctrl { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.map-ctrl .chip .i:not(.ck) { width: 16px; height: 16px; }
.vn-sel { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); min-width: 0; }
.vn-sel .select { max-width: 100%; }
.map-day-note { font-size: var(--fs-xs); }
@media (max-width: 699px) { .map-page .map-bar > .label { display: none; } .map-page .map-bar { justify-content: flex-end; } }
.map-main { display: grid; gap: var(--sp-4); grid-template-columns: minmax(0, 1fr); align-items: start; }
/* phones: filters, then the map, then the list (the side column dissolves into the grid) */
@media (max-width: 1099px) {
  .map-side { display: contents; }
  .map-ctrl { order: 0; margin-bottom: 0; }
  .map-main > .map-box { order: 1; }
  .map-side > .result-count, .map-list { order: 2; }
  .map-side > .map-panel { order: 3; }
}
.map-page .map-view { aspect-ratio: auto; height: min(68vh, 620px); min-height: 340px; max-height: none; }
.no-js .map-page .map-view { height: auto; aspect-ratio: var(--map-ratio, 1 / 1); min-height: 0; max-height: 80vh; }
.map-page.is-list .map-view, .map-page.is-list .map-legend { display: none; }
.map-side { min-width: 0; }
.map-side .result-count { margin: 0 0 var(--sp-2); }
@media (min-width: 1100px) {
  .map-main { grid-template-columns: minmax(0, 1fr) minmax(340px, 400px); }
  .map-main > .map-box { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }
  .map-page .map-view { height: calc(100vh - var(--topbar-h) - 136px); min-height: 460px; }
  .map-side { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); max-height: calc(100vh - var(--topbar-h) - 2 * var(--sp-4)); overflow: auto; overscroll-behavior: contain; padding: 0 4px 0 2px; }
  .map-side .map-ctrl { padding-bottom: var(--sp-3); margin-bottom: var(--sp-3); border-bottom: 1px solid var(--border); }
  .map-side .dir-group { grid-template-columns: minmax(0, 1fr); gap: 4px; }
  .map-page.is-list .map-main { grid-template-columns: minmax(0, 1fr); }
  .map-page.is-list .map-side { position: static; max-height: none; overflow: visible; }
}
/* the selection panel: on top of the side column on wide screens, a bottom sheet on phones */
.map-panel { position: relative; padding: var(--sp-2) var(--sp-4) var(--sp-4); background: var(--surface); border: 1px solid var(--border-strong); border-top: var(--rule-heavy) solid var(--rule-ink); margin-bottom: var(--sp-4); }
.map-panel:focus { outline: none; }
.map-panel h2 { display: flex; align-items: center; gap: 10px; font-size: var(--fs-lg); line-height: var(--lh-head); margin: 2px 0 4px; padding-right: 48px; }
.map-panel h2:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.map-panel-top { position: absolute; top: 2px; right: 2px; display: flex; }
.map-panel-top button { display: grid; place-items: center; width: var(--tap); height: var(--tap); color: var(--text-muted); background: none; border: 0; }
.map-panel-top button:hover { color: var(--text); }
.map-panel-grip { display: none !important; }
.map-panel-meta { font-size: var(--fs-sm); }
.map-panel-h { font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); margin: var(--sp-3) 0 0; }
.map-panel-events { margin-top: 4px; }
.map-panel-events .w [data-status]:not(:empty)::before { content: "· "; }
.map-panel-more { margin-top: var(--sp-2); font-size: var(--fs-sm); }
.map-panel-acts { margin-top: var(--sp-3); align-items: center; }
.acts-l { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-xs); font-weight: var(--wght-strong); color: var(--text-muted); }
.acts-l .i { width: 16px; height: 16px; }
.map-panel-list { list-style: none; padding: 0; margin: var(--sp-2) 0 0; }
.map-panel-list button { display: grid; gap: 2px; width: 100%; min-height: var(--tap); padding: 8px 4px; text-align: left; background: none; border: 0; border-top: 1px solid var(--border); color: var(--text); font-size: var(--fs-sm); }
.map-panel-list .faint { font-size: var(--fs-xs); }
@media (max-width: 1099px) {
  .map-panel {
    position: fixed; z-index: var(--z-sticky); left: 0; right: 0; bottom: 0; margin: 0; max-height: 46vh; overflow: auto; overscroll-behavior: contain;
    border-left: 0; border-right: 0; border-bottom: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: var(--shadow-3);
    padding-bottom: calc(var(--sp-4) + env(safe-area-inset-bottom)); transform: translateY(100%); transition: transform var(--speed-slow) var(--ease), max-height var(--speed-slow) var(--ease);
  }
  .map-panel.is-open { transform: none; }
  .map-panel.is-full { max-height: 82vh; }
  .map-panel-grip { display: grid !important; }
  .map-panel-grip[aria-expanded="true"] .i { transform: rotate(180deg); }
  .map-page.has-sel { padding-bottom: 46vh; }
  body.modal-open .map-panel, body.nav-open .map-panel { display: none; }
}
@media (max-width: 1023px) { .map-panel { bottom: calc(var(--dock-h) + env(safe-area-inset-bottom)); padding-bottom: var(--sp-4); } }

/* the list: every place on the map, by layer, readable without JS */
.map-sec { margin-bottom: var(--sp-4); }
.map-sec[hidden] { display: none; }
.map-sec-h { display: flex; align-items: center; gap: 8px; font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); padding: var(--sp-2) 0; border-bottom: var(--rule-mid) solid var(--rule-ink); margin: 0; }
.map-sec-h .i { width: 16px; height: 16px; }
.map-sec-h .label { margin-left: auto; }
.map-items { list-style: none; padding: 0; margin: 0; }
.map-li { position: relative; display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; align-items: center; gap: 4px 10px; min-height: 52px; padding: 4px 0; border-bottom: 1px solid var(--border); }
.map-li[hidden] { display: none; }
.map-li.is-hi, .map-li.is-sel { background: var(--surface-alt); box-shadow: inset 3px 0 0 var(--accent); }
.map-li-b { display: grid; gap: 1px; min-width: 0; padding: 4px 0; }
.map-li .t { font-weight: var(--wght-strong); color: var(--text); text-decoration: none; overflow-wrap: anywhere; line-height: var(--lh-ui); }
.map-li .t:hover { text-decoration: underline; text-underline-offset: 0.16em; }
.map-li .m { font-size: var(--fs-xs); color: var(--text-muted); overflow-wrap: anywhere; }
.map-li .badge { justify-self: start; margin-top: 4px; }
.map-li .t.stretched:focus-visible { outline: none; }
.map-li .t.stretched:focus-visible::after { outline: 3px solid var(--focus); outline-offset: -3px; }
.map-show { position: relative; z-index: 1; display: grid; place-items: center; width: var(--tap); height: var(--tap); color: var(--text-muted); background: none; border: 1px solid transparent; border-radius: var(--radius-md); }
.map-show:hover { color: var(--text); border-color: var(--border-strong); }
.map-off-note { font-size: var(--fs-xs); margin: var(--sp-2) 0; }
.map-li.is-off { grid-template-columns: 34px minmax(0, 1fr); }
/* list markers: the same marks as the pins */
.map-mk { display: grid; place-items: center; justify-self: center; }
.mk-venue { min-width: 28px; height: 28px; padding: 0 3px; border-radius: 999px; background: var(--map-pin-bg); border: 3px solid var(--ink-edge); font-size: var(--fs-label); font-weight: 750; font-variant-numeric: tabular-nums; color: var(--text); }
.mk-venue[data-prog2] { border-color: transparent; background: linear-gradient(var(--map-pin-bg), var(--map-pin-bg)) padding-box, conic-gradient(var(--ink-edge) 0 50%, var(--ink-fill-2) 0 100%) border-box; }
.mk-venue.is-off { background: transparent; border: 2px dashed var(--border-strong); color: var(--text-muted); }
.mk-work { --pshape: var(--shape-diamond); width: 18px; height: 18px; }
.mk-work[data-prog="caw"] { --pshape: var(--shape-square); }
.mk-work i { width: 16px; height: 16px; background: var(--ink-fill); clip-path: var(--pshape); }
.mk-work.is-off i { background: none; outline: 2px dashed var(--border-strong); clip-path: none; transform: rotate(45deg) scale(0.75); }
.mk-stay { width: 26px; height: 26px; border-radius: var(--radius-xs); border: 2px solid var(--ink-edge); background: var(--map-pin-bg); }
.mk-stay .i { width: 14px; height: 14px; }
.mk-stop i { width: 14px; height: 14px; border-radius: 50%; border: 3px solid var(--map-rail); background: var(--map-pin-bg); }
.mk-food i { width: 12px; height: 12px; border-radius: 50%; background: var(--text-muted); }
.mk-facility { width: 26px; height: 26px; border-radius: var(--radius-sm); background: var(--primary); color: var(--primary-contrast); }
.mk-facility .i { width: 16px; height: 16px; }

/* ---------- mini-map on venue pages and in dialogs: a crop of the same basemap (<use href="…#bm">) + pins ---------- */
.mini-map { position: relative; aspect-ratio: 4 / 3; overflow: hidden; border: 1px solid var(--border-strong); background: var(--map-bg); }
.mini-map svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.mini-map .pin { pointer-events: none; }
.mini-labels { position: absolute; inset: 0; pointer-events: none; }
.mini-map .map-label { font-size: var(--fs-label); }
.mini-map .map-label.water { font-size: var(--fs-label); }
.area-map { aspect-ratio: var(--map-ratio, 4 / 3); }
.area-map .pin-venue > span { min-width: 26px; height: 26px; border-width: 3px; }
.area-map .pin-stop > span { display: grid; place-items: center; width: 22px; height: 22px; border-width: 2px; font-size: var(--fs-label); font-weight: 750; font-variant-numeric: tabular-nums; }
.mini-map-none { padding: var(--sp-3); border: 1px dashed var(--border-strong); }
/* ---- 51-venues.css ---- */
/* ======================================================================
   site/css/51-venues.css · OWNER: Agent E (map, venues & visit)
   Venue rows with stall numbers, the venues page (filters, List/Map), and the venue page (facts + mini-map,
   on view, what's on by day, nearby). From the final "Interchange" design (DESIGN.md §9.7, §9.13).
   Partials are concatenated in lexical order into docs/assets/site.css. Read only tokens (var(--…)); no
   color literal may appear here (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */
/* ---------- venues: numbered like market stalls, and the same number is on the map pin ---------- */
.venues { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.venue { position: relative; display: grid; grid-template-columns: var(--tap) minmax(0, 1fr); gap: 4px 14px; padding: var(--sp-4) 0; border-bottom: 1px solid var(--border); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.venue[hidden] { display: none; }
.stall {
  grid-row: span 6; display: grid; place-items: center; width: var(--tap); height: var(--tap);
  background: var(--primary); color: var(--primary-contrast); border-radius: var(--radius-xs); box-shadow: inset 0 calc(-1 * var(--rule-heavy)) 0 var(--ink-fill);
  font-size: var(--fs-base); font-weight: 750; font-variant-numeric: tabular-nums; line-height: 1;
}
.stall.is-off { background: transparent; color: var(--text-muted); border: 2px dashed var(--border-strong); box-shadow: none; }
.stall.s { grid-row: auto; flex: none; width: 30px; height: 30px; font-size: var(--fs-sm); box-shadow: inset 0 -3px 0 var(--ink-fill); }
.stall.s.is-off { box-shadow: none; }
.venue h3 { font-size: var(--fs-lg); line-height: var(--lh-head); margin: 0; overflow-wrap: anywhere; }
.venue h3 a { color: var(--text); text-decoration: none; }
.venue h3 a::after { content: ""; position: absolute; inset: 0; }                   /* the whole row opens the venue page */
.venue h3 a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
.venue h3 a:focus-visible { outline: none; }
.venue h3 a:focus-visible::after { outline: 3px solid var(--focus); outline-offset: 2px; }
.venue .addr { font-size: var(--fs-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; margin: 0; }
.venue .roles { list-style: none; padding: 0; display: grid; gap: 4px; margin: 6px 0 0; font-size: var(--fs-sm); }
.venue .roles li { display: flex; align-items: center; gap: 8px; color: var(--text); }
.venue .today { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 6px 0 0; font-size: var(--fs-sm); color: var(--text-muted); }
.venue .acts { position: relative; z-index: 1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
/* QA: the label gets its own line, so the buttons sit together on the next one instead of wrapping one by one */
.venue .acts .acts-l, .vp-dir .acts-l { flex-basis: 100%; }
.venue:hover .stall:not(.is-off), .venue.is-hi .stall:not(.is-off) { background: var(--accent-strong); color: var(--accent-contrast); }
.venue.is-hi { background: var(--surface-alt); box-shadow: inset 3px 0 0 var(--accent); }

/* ---------- venues.html: the filter bar, List/Map; at ≥ 1100px the map sits beside the list ---------- */
.vn-sel > label { flex: 1 1 180px; min-width: 0; max-width: 320px; }
.vn-sel .select { width: 100%; min-width: 0; }
.vn-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); }
.vn-bar .dir-status { margin: var(--sp-2) 0 var(--sp-3); flex: 1 1 280px; }
.vn-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; border-bottom: 0; margin-bottom: 0; }
.vn-head .label { font-family: var(--font-body); }
.vn-hood-link { margin-left: auto; display: inline-flex; align-items: center; min-height: var(--tap); font-family: var(--font-body); font-size: var(--fs-sm); font-weight: var(--wght-ui); }
.vn-group { margin-bottom: var(--sp-6); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.vn-group[hidden] { display: none; }
.vn-map { display: none; min-width: 0; }
.vn-map .map-view { aspect-ratio: auto; height: min(70vh, 620px); min-height: 320px; max-height: none; }
.js .vn-layout.is-map .vn-map { display: block; }
.js .vn-layout.is-map .vn-list { display: none; }
@media (min-width: 1100px) {
  .js .vn-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, 440px); gap: var(--sp-6); align-items: start; }
  .js .vn-layout .vn-map { display: block; position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); order: 2; }
  .js .vn-layout .vn-list { display: block; }
  .vn-map .map-view { height: calc(100vh - var(--topbar-h) - 160px); min-height: 420px; }
  .vn-bar .view-toggle { display: none; }
}

/* ---------- the venue page: facts + mini-map side by side; on view; what's on here, by day; nearby ---------- */
.vp-head .kicker { display: flex; align-items: center; gap: 10px; }
.vp-top { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1fr); align-items: start; scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
@media (min-width: 860px) { .vp-top { grid-template-columns: minmax(0, 1fr) 340px; } }
.vp-top .facts { margin-top: 0; }
.vp-status { margin-top: var(--sp-3); }
.vp-map .mini-map { margin: 0; }
.vp-dir { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); }
.vp-sec { margin-top: var(--sp-6); }
.vp-sec > .sub-h { scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.vp-note { font-size: var(--fs-xs); margin: calc(-1 * var(--sp-2)) 0 var(--sp-3); }
.byday { margin-top: var(--sp-6); }
.vp-day, .byday h3.vp-day { font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); padding: var(--sp-2) 0; margin: var(--sp-4) 0 var(--sp-3); border-bottom: var(--rule-mid) solid var(--rule-ink); }
.vp-nearby { display: grid; gap: var(--sp-4) var(--sp-6); grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.vp-nearby .sub-h { margin-top: 0; }
.vp-near { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.vp-near li { border-bottom: 1px solid var(--border); }
.vp-near a { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 6px 0; color: var(--text); text-decoration: none; }
.vp-near a:hover b { text-decoration: underline; text-underline-offset: 0.16em; }
.vp-near a > span:last-child { display: grid; gap: 1px; min-width: 0; }
.vp-near b { font-weight: var(--wght-strong); overflow-wrap: anywhere; }
.vp-near .faint { font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.vp-approx { margin-top: 6px; font-size: var(--fs-xs); }
/* ---- 60-directory.css ---- */
/* ======================================================================
   site/css/60-directory.css · OWNER: Agent F (directory: people, art, partners)
   The directory filter bar (.dir-*: search, chip groups, A–Z, status, active chips), people rows
   and featured mugs, artwork cards, partner logo walls.
   From the final "Interchange" design (DESIGN.md §9.5, §9.6, §9.8). Partials are concatenated in
   lexical order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear
   here (the build fails on one).
   ====================================================================== */

/* ---------- the filter bar: search, chip groups (one scrolling row each on phones), A–Z, status ---------- */
.dir-tools { display: grid; gap: var(--sp-2); margin-bottom: var(--sp-3); }
.dir-tools > .view-toggle { justify-self: start; }   /* QA: a grid item stretched the Grid/Map toggle across the page */
.dir-search { max-width: 520px; }
.dir-group { display: grid; grid-template-columns: 76px minmax(0, 1fr); align-items: center; gap: var(--sp-2); min-width: 0; }
.dir-glabel { color: var(--text-muted); }
.dir-chips { position: relative; display: flex; gap: var(--sp-2); min-width: 0; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; padding: 3px 1px; }
.dir-chips::-webkit-scrollbar { display: none; }
.dir-chips > * { flex: none; }
.dir-chips .chip.is-zero { color: var(--text-faint); border-style: dashed; }
@media (max-width: 699px) {
  .dir-chips { -webkit-mask-image: linear-gradient(to right, var(--mask-ink) 88%, transparent); mask-image: linear-gradient(to right, var(--mask-ink) 88%, transparent); padding-right: 24px; }
}
@media (min-width: 700px) { .dir-chips { flex-wrap: wrap; overflow: visible; } }

/* A–Z: a scrolling row on phones, a wrapped strip on desktop; jumps without JS, filters with it */
.dir-az { position: relative; margin: var(--sp-2) 0 var(--sp-1); flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.dir-az::-webkit-scrollbar { display: none; }
.dir-az a { flex: none; }
.dir-az a[aria-disabled="true"] { color: var(--border-strong); pointer-events: none; }
@media (pointer: coarse) { .dir-az a { min-width: var(--tap); } }
@media (max-width: 699px) { .dir-az { -webkit-mask-image: linear-gradient(to right, var(--mask-ink) 90%, transparent); mask-image: linear-gradient(to right, var(--mask-ink) 90%, transparent); padding-right: 24px; } }
@media (min-width: 700px) { .dir-az { flex-wrap: wrap; overflow: visible; } }

.dir-status { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4); margin: var(--sp-3) 0 var(--sp-4); min-height: var(--tap); }
.dir-active { gap: var(--sp-2); }
.dir-active > .label { margin-right: 2px; }
.chip-x { background: var(--surface-alt); }
.chip-x .x { width: 16px; height: 16px; color: var(--text-muted); }
.chip-x:hover .x { color: var(--text); }
[data-dir-empty] { margin: var(--sp-4) 0; }

/* ---------- people: directory rows (500+): a 64×80 mug beside the name; the whole card is the link ---------- */
.people { display: grid; gap: var(--sp-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.person {
  position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); grid-template-rows: auto auto 1fr; gap: 4px 14px; align-items: start;
  padding: 10px 12px 10px 10px; background: var(--surface); border: 1px solid var(--border); color: var(--text); text-decoration: none;
  scroll-margin-top: calc(var(--topbar-h) + var(--sp-4));
}
.person:hover { border-color: var(--border-strong); color: var(--text); }
.person:hover .per-name { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
.person .avatar { grid-row: span 3; }
.person .avatar::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: var(--rule-heavy); background: var(--ink-fill); }
[data-prog="fotofocus"].person .avatar::after, [data-prog="also"].person .avatar::after { background: var(--ink-edge); }
.per-name { font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); line-height: var(--lh-snug); overflow-wrap: anywhere; }
.per-role { font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.4; overflow-wrap: anywhere; }
.per-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin-top: 4px; color: var(--ink-text); align-self: end; }
.per-foot .bullet + .bullet { margin-left: -4px; }
@media (min-width: 1100px) { .person .avatar { --av: 80px; } }

/* featured person ("mug"): the 4:5 portrait, program rule and bullet on the photo (home, program pages) */
.people-feature { display: grid; gap: var(--sp-5) var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(46%, 168px), 1fr)); }
.person-feature { position: relative; display: block; color: var(--text); text-decoration: none; }
.person-feature .photo { display: block; position: relative; aspect-ratio: 4 / 5; overflow: hidden; border-bottom: var(--rule-heavy) solid var(--ink-fill); }
[data-prog="fotofocus"].person-feature .photo, [data-prog="also"].person-feature .photo { border-bottom-color: var(--ink-edge); }
.person-feature .photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 28%; filter: var(--photo-filter); }
.person-feature .photo .bullet { position: absolute; left: 8px; bottom: 8px; }
.person-feature .photo .mono { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: 3rem; color: var(--ink-text); }
.person-feature .per-name, .person-feature .per-role, .person-feature .per-foot { display: block; }
.person-feature .per-name { margin-top: 10px; }
.person-feature .per-role { margin-top: 2px; }
.person-feature:hover .per-name { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
.person-feature .per-foot { margin-top: 4px; font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; }

/* ---------- art: artwork card (never filtered; the credit sits under the photo) ---------- */
.works { display: grid; gap: var(--sp-5) var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(46%, 250px), 1fr)); }
@media (max-width: 559px) { .works { gap: var(--sp-5) var(--sp-3); } .work h3 { font-size: var(--fs-base); } }
.work { position: relative; display: flex; flex-direction: column; min-width: 0; scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.work .photo { position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.work .photo:not(.halftone), .person-feature .photo:not(.halftone) { background: var(--ink-tint); }        /* .halftone paints its own screen */
.work .photo img { width: 100%; height: 100%; object-fit: cover; }
.work .credit { min-height: 1.25em; margin-top: 5px; color: var(--text-faint); overflow-wrap: anywhere; }
.work .wk-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 8px; color: var(--ink-text); overflow-wrap: anywhere; }
.work .wk-kicker .i { width: 16px; height: 16px; }
.work h3 { margin-top: 6px; font-size: var(--fs-md); overflow-wrap: anywhere; }
.work h3 a { color: var(--text); text-decoration: none; }
.work h3 a::after { content: ""; position: absolute; inset: 0; }
.work h3 a:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
.work h3 a:focus-visible { outline: none; }
.work:has(h3 a:focus-visible) { outline: 3px solid var(--focus); outline-offset: 4px; }
.work .by { font-size: var(--fs-sm); color: var(--text-muted); margin-top: 2px; overflow-wrap: anywhere; }
.work .zone { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: var(--fs-xs); color: var(--text-muted); }
.work .zone .i { width: 14px; height: 14px; flex: none; }
.work .star.floating { z-index: 2; }
.photo-missing { position: absolute; inset: 0; display: grid; place-content: center; justify-items: center; gap: 8px; color: var(--ink-text); text-align: center; }
.photo-missing .i { width: 32px; height: 32px; }

/* ---------- partners: logo walls grouped by program, then tier; logos unaltered on their plates ---------- */
.wall-group { scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.wall-group + .wall-group { margin-top: var(--sp-7); }
.wall-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding-bottom: var(--sp-2); border-bottom: var(--rule-mid) solid var(--rule-ink); }
.wall-head h2, .wall-head h3 { font-size: var(--fs-lg); }
.wall-head .cap { margin-left: auto; color: var(--text-faint); }
@media (max-width: 559px) { .wall-head .cap { display: none; } }
.tier { margin: var(--sp-4) 0 var(--sp-2); color: var(--text-muted); }
/* QA: a program's tiers flow as a row; a tier of one or two logos (.n1, .n2) takes only their width, so a wall of
   many one-sponsor tiers fills the row instead of running down the left edge. Plates keep one size. */
.wall-group { display: flex; flex-wrap: wrap; align-items: flex-end; column-gap: var(--sp-4); }
.wall-group > * { flex: 1 1 100%; min-width: 0; }
.wall-group > .wall-tier.n1 { flex: 0 1 164px; }
.wall-group > .wall-tier.n2 { flex: 0 1 336px; }
.wall-tier.n1 .plates, .wall-tier.n2 .plates { grid-template-columns: repeat(auto-fill, minmax(min(100%, 150px), 1fr)); }
@media (max-width: 559px) { .wall-group > .wall-tier.n1 { flex-basis: calc(50% - var(--sp-2)); } .wall-group > .wall-tier.n2 { flex-basis: 100%; } .wall-tier.n2 .plates { grid-template-columns: 1fr 1fr; } }
.wall-marks .plates { margin-top: var(--sp-3); }
.plates { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fill, minmax(min(46%, 150px), 1fr)); }
.plates.lg { grid-template-columns: repeat(auto-fill, minmax(min(46%, 220px), 1fr)); }
.plate {
  position: relative; display: grid; place-items: center; aspect-ratio: 3 / 2; padding: 14px; min-width: 0;
  background: var(--plate); border: 1px solid var(--plate-border); color: var(--plate-ink); text-decoration: none;
  scroll-margin-top: calc(var(--topbar-h) + var(--sp-6));
}
.plate[data-tone="dark"] { background: var(--plate-dark); color: var(--plate-dark-ink); }
.plate img { max-width: 100%; max-height: 56px; width: auto; height: auto; object-fit: contain; }
.plates.lg .plate img { max-height: 76px; }
a.plate:hover { border-color: var(--text); color: var(--plate-ink); }
a.plate[data-tone="dark"]:hover { color: var(--plate-dark-ink); }
.plate:target { outline: 3px solid var(--focus); outline-offset: 3px; }
.plate .ext { position: absolute; top: 6px; right: 6px; width: 14px; height: 14px; color: var(--plate-ink); opacity: 0; transition: opacity var(--speed) var(--ease); }
.plate[data-tone="dark"] .ext { color: var(--plate-dark-ink); }
.plate:hover .ext, .plate:focus-visible .ext { opacity: 1; }
.plate-text { font-family: var(--font-body); font-weight: 720; font-size: var(--fs-sm); line-height: 1.2; text-align: center; text-wrap: balance; overflow-wrap: anywhere; }
/* ---- 61-person.css ---- */
/* ======================================================================
   site/css/61-person.css · OWNER: Agent F (directory: people, art, partners)
   The person page (.dp, DESIGN.md §9.13): a 240px portrait column beside the main column on
   desktop; on phones a 120px portrait beside the name. Then the bio, links, events (Agent D's
   cards), the works in full (.wk-full), the venues (.per-venues) and the sources.
   Tokens only; no color literal.
   ====================================================================== */
.dp {
  display: grid; gap: var(--sp-4) var(--sp-4); align-items: end;
  grid-template-columns: 120px minmax(0, 1fr); grid-template-areas: "portrait head" "main main";
}
.dp-portrait { grid-area: portrait; min-width: 0; }
.dp-head { grid-area: head; min-width: 0; }
.dp-main { grid-area: main; min-width: 0; align-self: start; }
@media (min-width: 860px) {
  .dp { column-gap: var(--sp-6); align-items: start; grid-template-columns: 240px minmax(0, 1fr); grid-template-areas: "portrait head" "portrait main"; grid-template-rows: auto 1fr; }
  .dp-portrait { position: sticky; top: calc(var(--topbar-h) + var(--sp-4)); }
}
.dp-portrait .photo { position: relative; aspect-ratio: 4 / 5; overflow: hidden; border-bottom: var(--rule-heavy) solid var(--ink-fill); }
.dp-portrait .photo:not(.halftone), .wk-media .photo:not(.halftone) { background: var(--ink-tint); }
[data-prog="fotofocus"] .dp-portrait .photo, [data-prog="also"] .dp-portrait .photo { border-bottom-color: var(--ink-edge); }
.dp-portrait .photo img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 28%; filter: var(--photo-filter); }
.dp-portrait .photo .mono { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-display); font-style: italic; font-weight: 500; font-size: clamp(2.5rem, 9vw, 4.5rem); line-height: 1; color: var(--ink-text); }
.dp-portrait .credit { margin-top: 6px; color: var(--text-faint); overflow-wrap: anywhere; }
/* QA: on phones the 120px portrait column broke a long credit inside its host name ("CINCINNATIMAG / AZINE.COM");
   the credit now runs the full width under the portrait and the name */
@media (max-width: 859px) {
  .dp { grid-template-areas: "portrait head" "credit credit" "main main"; row-gap: 0; }
  .dp-portrait { display: contents; }
  .dp-portrait .photo { grid-area: portrait; align-self: end; }
  .dp-portrait .credit { grid-area: credit; margin-top: 6px; overflow-wrap: normal; }
  .dp-main { margin-top: var(--sp-4); }
}
.dp-head h1 { max-width: 20ch; overflow-wrap: anywhere; }
@media (max-width: 559px) { .dp-head h1 { font-size: clamp(1.5rem, 7vw, 1.875rem); } }
.dp-head .lede { margin-top: var(--sp-2); }
.dp-head .lede, .dp-head .byline, .dp-roles { overflow-wrap: anywhere; }
.dp-roles { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin-bottom: var(--sp-2); }
.dp-bio { margin-top: var(--sp-2); }
.dp-links { margin-top: var(--sp-4); }
.dp-list { margin-top: var(--sp-3); align-items: start; }
.per-ev { display: grid; gap: 6px; min-width: 0; }
.per-evrole { color: var(--ink-text); }
.dp-back { margin-top: var(--sp-5); }
.dp-main .sub-h:has(+ .per-venues), .dp-main .sub-h:has(+ .dp-works) { border-bottom: 0; margin-bottom: 0; }

/* the full work on its artist's page (works have no pages of their own) */
.dp-works { display: grid; gap: var(--sp-5); border-top: var(--rule-mid) solid var(--rule-ink); }
.wk-full { display: grid; gap: var(--sp-3) var(--sp-5); padding-top: var(--sp-4); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.wk-full + .wk-full { border-top: 1px solid var(--border); padding-top: var(--sp-5); }
@media (min-width: 700px) { .wk-full { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); } }
.wk-media .photo { position: relative; aspect-ratio: 4 / 3; overflow: hidden; }
.wk-media .photo img { width: 100%; height: 100%; object-fit: cover; }
.wk-media .credit { margin-top: 5px; color: var(--text-faint); }
.wk-full .wk-kicker { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: var(--ink-text); }
.wk-full .wk-kicker .i { width: 16px; height: 16px; }
.wk-title { margin-top: 6px; font-size: var(--fs-lg); }
.wk-title a { color: var(--text); }
@media (max-width: 699px) { .wk-title a { display: inline-flex; align-items: center; min-height: var(--tap); } }
.wk-bio-note { margin-top: var(--sp-2); font-size: var(--fs-sm); font-style: italic; color: var(--text-muted); }
.wk-full .facts { margin: var(--sp-3) 0; }
.wk-full .fact { flex-basis: 140px; }
.wk-note { margin-top: var(--sp-3); }
.wk-full .btn-row { align-items: center; margin-top: var(--sp-3); gap: var(--sp-2); }
.wk-full .btn-row .star { border: 1px solid var(--border-strong); }

/* the venues they appear at: stall number (as on the map pin), name, address */
.per-venues { list-style: none; padding: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.per-venues li { border-bottom: 1px solid var(--border); }
.per-venues a { display: grid; grid-template-columns: 32px minmax(0, 1fr); align-items: center; gap: 12px; min-height: var(--tap); padding: 8px 0; color: var(--text); text-decoration: none; }
.per-venues a:hover b { text-decoration: underline; text-underline-offset: 0.16em; }
.per-venues b { font-weight: var(--wght-strong); }
.per-venues span span { display: block; font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.per-stall {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--radius-xs);
  background: var(--primary); color: var(--primary-contrast); box-shadow: inset 0 -3px 0 var(--ink-fill);
  font-size: var(--fs-sm); font-weight: 750; font-variant-numeric: tabular-nums; line-height: 1;
}
.per-stall.is-off { background: transparent; color: var(--text-muted); border: 2px dashed var(--border-strong); box-shadow: none; }
/* ---- 62-art.css ---- */
/* ======================================================================
   site/css/62-art.css · OWNER: Agent F (directory: people, art, partners)
   The art page's program sections and map box, and the work dialog's own parts (.wd-*). The
   dialog body reuses D's .evd layout (81-event-dialog.css: .evd-grid, .evd-where, .evd-people,
   .evd-facts, .evd-actions), as CONTRACTS §7 records. Tokens only; no color literal.
   ====================================================================== */
.art-group { margin-top: var(--sp-6); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.art-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: var(--sp-4); padding-bottom: var(--sp-2); border-bottom: var(--rule-mid) solid var(--rule-ink); font-size: var(--fs-lg); }
.art-head .label { margin-left: auto; font-family: var(--font-body); }
.art-note { margin: calc(-1 * var(--sp-2)) 0 var(--sp-4); font-size: var(--fs-sm); color: var(--text-muted); }
.art-map { margin: var(--sp-3) 0 var(--sp-5); min-height: 320px; }

/* work dialog */
.wd-media { position: relative; margin: calc(-1 * var(--sp-4)) calc(-1 * var(--sp-5)) var(--sp-4); }
.wd-media:not(.halftone) { background: var(--surface-sunken); }
.wd-media img { display: block; width: 100%; height: auto; max-height: min(44vh, 440px); object-fit: contain; }
.wd-media .credit { padding: 6px var(--sp-5) 8px; color: var(--text-faint); background: var(--surface); }
.wd-media.photo { aspect-ratio: 16 / 7; }
@media (max-width: 699px) { .wd-media { margin: calc(-1 * var(--sp-4)) calc(-1 * var(--sp-4)) var(--sp-4); } .wd-media .credit { padding-inline: var(--sp-4); } }
.evd .evd-kind .i { width: 16px; height: 16px; color: var(--ink-text); }
.wd-by { margin-top: var(--sp-2); font-family: var(--font-display); font-style: italic; font-size: var(--fs-md); color: var(--text-muted); }
.wd-stall {
  display: inline-grid; place-items: center; min-width: 20px; height: 18px; padding: 0 3px; margin-right: 6px; vertical-align: 1px;
  border: 1px solid var(--border-strong); border-bottom: 3px solid var(--ink-fill); border-radius: var(--radius-xs);
  font-size: var(--fs-label); font-weight: 750; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums;
}
/* verbatim texts can hold long bare URLs: let them wrap instead of widening the dialog or the page */
#work-dialog .prose, .dp .prose, .wk-full .prose { overflow-wrap: anywhere; }
.wd-zone-note { margin-top: 6px; font-size: var(--fs-xs); }   /* QA: a work shown at its zone says so */

/* BLINK's official map number ("BLINK map No. 29", 2026-09-24): a small tag in the look of the dialog's stall numbers,
   underlined in the program ink (identity only); the words carry the meaning, never the color */
.mapno {
  display: inline-flex; align-items: center; gap: 4px; padding: 1px 6px 0; min-height: 22px;
  border: 1px solid var(--border-strong); border-bottom: 3px solid var(--ink-fill); border-radius: var(--radius-xs);
  font-size: var(--fs-label); font-weight: var(--wght-strong); line-height: 1.2; color: var(--text); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.work .wk-no { margin-top: 6px; }
.wd-mapno { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--text-muted); }
.wd-mapno a { color: inherit; }
.wd-approx { margin-top: 6px; font-size: var(--fs-xs); }
/* ---- 70-visit.css ---- */
/* ======================================================================
   site/css/70-visit.css · OWNER: Agent E (map, venues & visit)
   Stays with room blocks, getting around (the Connector, place cards, the walking matrix), neighborhoods,
   eat & drink. From the final "Interchange" design (DESIGN.md §9.9). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here (the build
   fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- shared: small source lines, "Details" fold-outs; long addresses and web addresses in quoted text wrap ---------- */
.gp, .eat, .stay, .hood, .ga-intro, .gp-mini { overflow-wrap: anywhere; }
.src { font-size: var(--fs-xs); margin: var(--sp-2) 0 0; }
.more-d { margin-top: var(--sp-2); }
.more-d > summary { display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); cursor: pointer; font-size: var(--fs-sm); font-weight: var(--wght-strong); color: var(--link); text-decoration: underline; text-underline-offset: 0.18em; list-style: none; }
.more-d > summary::-webkit-details-marker { display: none; }
.more-d > summary .i { width: 16px; height: 16px; transition: transform var(--speed) var(--ease); }
.more-d[open] > summary .i { transform: rotate(180deg); }
.prose.small { font-size: var(--fs-sm); color: var(--text-muted); }
.prose + .prose.small { margin-top: var(--sp-2); }   /* QA: the short details paragraph no longer runs straight on from the summary */

/* ---------- stays: where to stay ---------- */
.stays { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }
.stay { position: relative; display: flex; flex-direction: column; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); min-width: 0; }
.stay:target { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.stay h3 { font-size: var(--fs-lg); line-height: var(--lh-head); margin: 0; overflow-wrap: anywhere; }
.stay .addr { margin: 2px 0 0; font-size: var(--fs-sm); color: var(--text-muted); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.dist { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: var(--sp-3) 0 0; }
.dist > .i { width: 16px; height: 16px; color: var(--text-muted); }
.dist span { display: inline-flex; align-items: center; gap: 5px; min-height: 28px; padding: 0 8px; border: 1px solid var(--border); border-radius: var(--radius-xs); font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.dist span b { color: var(--text); font-weight: var(--wght-strong); }
.block { margin-top: var(--sp-4); padding: 12px 14px; background: var(--ink-tint); border-left: var(--rule-heavy) solid var(--ink-fill); }
.block .bh { display: flex; align-items: center; gap: 8px; color: var(--ink-text); margin: 0; }
.block dl { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; margin: 8px 0 0; font-size: var(--fs-sm); }
.block dt { color: var(--text-muted); }
.block dd { margin: 0; font-weight: var(--wght-strong); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.block .st-status { font-weight: var(--wght-body); }
.block .bk { margin: var(--sp-3) 0 0; }
.portal { display: flex; align-items: flex-start; gap: 8px; margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--text-muted); }
.portal .bullet { flex: none; }
.stay .acts { margin-top: auto; padding-top: var(--sp-4); display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.st-note { font-size: var(--fs-xs); margin-top: var(--sp-3); }
.st-map .map-view { aspect-ratio: 16 / 9; }
.st-map:empty { aspect-ratio: 16 / 9; background: var(--map-bg); border: 1px solid var(--border); }   /* QA: holds the lazy map's space (no jump when it mounts) */
@media (max-width: 699px) { .st-map:empty { aspect-ratio: 4 / 5; } }
@media (max-width: 699px) { .st-map .map-view { aspect-ratio: 4 / 5; } }

/* ---------- getting around: place cards, the Connector, the walking matrix ---------- */
.gps { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); margin-top: var(--sp-4); }
.gp { padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); min-width: 0; }
.gp:target, .ga-intro:target, .ga-stops li:target, .gp-mini li:target, .eat:target { box-shadow: inset 0 0 0 2px var(--accent); }
.gp h3 { font-size: var(--fs-md); line-height: var(--lh-snug); margin: 0 0 var(--sp-2); overflow-wrap: anywhere; }
.gp .prose { font-size: var(--fs-sm); }
.gp .addr { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.gp .acts, .eat .acts { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-2) 0 0; }
.gp-mini { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); columns: 2 280px; column-gap: var(--sp-6); }
.gp-mini p { margin: 0; }
.gp-mini li { break-inside: avoid; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.gp-mini .faint { font-size: var(--fs-xs); }
.ga-car { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 900px) { .ga-car { grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); } }
.ga-intro { scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.ga-stops { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); columns: 2 220px; column-gap: var(--sp-5); }
.ga-stops li { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 4px 0; border-bottom: 1px solid var(--border); break-inside: avoid; font-size: var(--fs-sm); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.ga-stops .faint { font-size: var(--fs-xs); }
.ga-n { flex: none; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--map-rail); background: var(--map-pin-bg); color: var(--map-pin-ink); font-size: var(--fs-label); font-weight: 750; font-variant-numeric: tabular-nums; }
.ga-route { max-width: 340px; }
/* walking matrix: minutes between hubs */
table.data.walk th .faint { font-weight: var(--wght-body); font-size: var(--fs-xs); }
table.data.walk td.num b { font-size: var(--fs-base); }
table.data.walk td.num .faint { display: block; font-size: var(--fs-label); }
table.data.walk td.far b { font-style: italic; }
.walk-note { font-size: var(--fs-xs); color: var(--text-faint); margin-top: var(--sp-2); }
/* the shared card layout hides the thead with overflow: hidden, which a table-header-group ignores: make it a block so
   the long hub names do not widen the page on phones */
@media (max-width: 699px) { table.data.walk thead { display: block; } }

/* ---------- neighborhoods: a hood, what's on there this week, and its doors ---------- */
.hood { scroll-margin-top: calc(var(--topbar-h) + var(--sp-2)); }
.hood-top { display: grid; gap: var(--sp-5); grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 900px) { .hood-top { grid-template-columns: minmax(0, 1fr) minmax(240px, 320px); } }
.hood-counts { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-3); }
.hood-cols { display: grid; gap: var(--sp-3) var(--sp-6); grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); margin-top: var(--sp-4); }
.hood-cols .sub-h { margin-top: var(--sp-3); }
.hood-list { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); }
.hood-list li { border-bottom: 1px solid var(--border); }
.hood-list a { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 6px 0; color: var(--text); text-decoration: none; }
.hood-list a > span:last-child { display: grid; gap: 1px; min-width: 0; }
.hood-list b { font-weight: var(--wght-strong); overflow-wrap: anywhere; }
.hood-list a:hover b { text-decoration: underline; text-underline-offset: 0.16em; }
.hood-list .faint { font-size: var(--fs-xs); }

/* ---------- eat & drink ---------- */
.ed-group { margin-bottom: var(--sp-6); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.ed-group[hidden] { display: none; }
.eats { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); border-top: var(--rule-mid) solid var(--rule-ink); padding-top: var(--sp-4); }
.eat { display: flex; flex-direction: column; padding: var(--sp-4); background: var(--surface); border: 1px solid var(--border); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); min-width: 0; }
.eat[hidden] { display: none; }
.eat-k { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); margin: 0 0 4px; }
.eat-k .i { width: 16px; height: 16px; }
.eat h3 { font-size: var(--fs-md); line-height: var(--lh-snug); margin: 0 0 var(--sp-2); overflow-wrap: anywhere; }
.eat .prose { font-size: var(--fs-sm); }
.eat .addr { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.near { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: var(--sp-3) 0 0; }
.near > .label { flex-basis: 100%; }   /* QA: the label on its own line, so every card lays its chips out the same way */
.near .chip { gap: 6px; padding-left: 4px; max-width: 100%; min-width: 0; }
.near .chip > span:not(.n):not(.stall) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.near .chip .stall.s { width: 26px; height: 26px; font-size: var(--fs-label); }
.eat .acts { margin-top: auto; padding-top: var(--sp-3); }

/* ---------- getting-around.html#blink-facilities: BLINK's restrooms, Oasis Stations and more (its maps, 2026-09-24) ---------- */
.ga-fac-lede { font-size: var(--fs-sm); color: var(--text-muted); max-width: 68ch; }
.fac-h { display: flex; align-items: center; gap: 10px; margin-top: var(--sp-5); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); }
.fac-h .label { margin-left: auto; }
.fac-gs { font-size: var(--fs-sm); color: var(--text-muted); margin: 0 0 var(--sp-2); }
/* the glyph: a dark tag like the printed map's black symbols, the same mark as the map pin */
.fac-mk { display: inline-grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: var(--radius-sm); background: var(--primary); color: var(--primary-contrast); }
.fac-mk .i { width: 18px; height: 18px; }
.fac-list { list-style: none; padding: 0; margin: 0; border-top: var(--rule-mid) solid var(--rule-ink); display: grid; gap: 0 var(--sp-6); grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); }
.fac { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); scroll-margin-top: calc(var(--topbar-h) + var(--sp-4)); overflow-wrap: anywhere; }
.fac:target { box-shadow: inset 0 0 0 2px var(--accent); }
.fac-b > p { margin: 0; }
.fac-t { font-size: var(--fs-sm); }
.fac-m { display: block; font-size: var(--fs-xs); color: var(--text-muted); }
.fac-s { font-size: var(--fs-xs); margin-top: 2px !important; }
.fac .acts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px var(--sp-2); margin-top: 6px !important; }
.fac-src { font-size: var(--fs-xs); }
/* ---- 80-dialogs.css ---- */
/* ======================================================================
   site/css/80-dialogs.css · OWNER: Agent A (core engine)
   The one modal component, search palette, sheet, switches.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 80 · dialogs: one modal component (focus trap, inert page, focus returns) ---------- */
body.modal-open { overflow: hidden; }
.modal { position: fixed; inset: 0; z-index: var(--z-modal); display: none; }
.modal.open { display: block; }
.modal-backdrop { position: absolute; inset: 0; background: var(--scrim); }
.modal-panel {
  position: absolute; left: 50%; top: 6vh; transform: translateX(-50%);
  width: min(720px, calc(100vw - 2 * var(--gutter))); max-height: 88vh; overflow: auto; overscroll-behavior: contain;
  background: var(--surface); border-top: var(--rule-heavy) solid var(--rule-ink); box-shadow: var(--shadow-3); border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.modal-head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: var(--sp-2); padding: 8px 8px 8px var(--sp-4); background: var(--surface); border-bottom: 1px solid var(--border); }
.modal-head .icon-btn { margin-left: auto; }
.modal-body { padding: var(--sp-4) var(--sp-5) var(--sp-5); }
@media (max-width: 699px) {
  .modal-panel { top: auto; bottom: 0; left: 0; right: 0; transform: none; width: 100%; max-height: 92dvh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  .modal-body { padding: var(--sp-4); }
}
/* ---------- search palette (⌘K, Ctrl+K, /) ---------- */
.search-modal .modal-panel { width: min(640px, calc(100vw - 2 * var(--gutter))); top: 10vh; max-height: min(76vh, 640px); display: flex; flex-direction: column; overflow: hidden; }
@media (max-width: 699px) { .search-modal .modal-panel { top: 0; bottom: auto; left: 0; right: 0; transform: none; width: 100%; max-height: 100dvh; height: 100dvh; border-radius: 0; } }
.search-field { display: flex; align-items: center; gap: 10px; padding: 0 8px 0 16px; border-bottom: var(--rule-mid) solid var(--rule-ink); }
.search-field input { flex: 1; min-height: 56px; border: 0; background: transparent; font-size: 1.125rem; outline: none; }
.search-field input::placeholder { color: var(--text-faint); opacity: 1; }
.search-results { flex: 1; overflow: auto; padding: 4px 0 var(--sp-2); }
.sr-group { padding: 12px 16px 4px; color: var(--text-faint); display: flex; justify-content: space-between; }
.sr-hit { display: grid; grid-template-columns: 30px minmax(0, 1fr) auto; align-items: center; gap: 2px 12px; min-height: 52px; padding: 6px 16px; color: var(--text); text-decoration: none; cursor: pointer; }
.sr-hit .avatar.s { --av: 26px; }
.sr-hit .t { font-weight: var(--wght-strong); line-height: 1.3; }
.sr-hit .m { display: block; font-size: var(--fs-xs); color: var(--text-faint); font-variant-numeric: tabular-nums; }
.sr-hit mark { background: var(--accent-tint); color: var(--text); padding: 0 1px; border-radius: 1px; }
.sr-hit[aria-selected="true"], .sr-hit:hover { background: var(--surface-alt); box-shadow: inset 3px 0 0 var(--accent); }
.sr-hit .i { color: var(--text-faint); }
.sr-all { display: flex; align-items: center; gap: 6px; min-height: var(--tap); padding: 0 16px 0 58px; font-size: var(--fs-sm); font-weight: var(--wght-strong); }
.search-foot { display: flex; flex-wrap: wrap; gap: 4px 16px; padding: 8px 16px; border-top: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-faint); }
@media (max-width: 699px) { .search-foot { display: none; } }

/* ---------- sheet: bottom sheet on phones (filters, map selection, share); a side panel ≥ 1024px ---------- */
.sheet .modal-panel {
  top: auto; bottom: 0; left: 0; right: 0; transform: none; width: 100%; max-height: 86dvh;
  border-top: var(--rule-heavy) solid var(--rule-ink); border-radius: var(--radius-lg) var(--radius-lg) 0 0; display: flex; flex-direction: column;
}
.sheet .grip { width: 44px; height: 4px; margin: 8px auto 0; border-radius: 2px; background: var(--border-strong); }
@media (min-width: 1024px) {
  .sheet .modal-panel { top: 0; left: auto; right: 0; bottom: 0; width: 420px; max-height: none; border-radius: 0; border-top: 0; border-left: var(--rule-heavy) solid var(--rule-ink); }
  .sheet .grip { display: none; }
}
.sheet-body { flex: 1; overflow: auto; padding: var(--sp-2) var(--sp-4) var(--sp-4); }
.sheet fieldset { border: 0; padding: 0; margin: var(--sp-4) 0 0; }
.sheet legend { padding: 0; margin-bottom: var(--sp-2); color: var(--text-muted); }
.sheet-foot { display: flex; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom)); border-top: 1px solid var(--border); background: var(--surface); }
.sheet-foot .btn-primary { flex: 1; }
.switch { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); min-height: var(--tap); font-size: var(--fs-sm); }
.switch [role="switch"] { position: relative; width: 48px; height: 28px; flex: none; border-radius: var(--radius-pill); background: var(--surface-sunken); border: 2px solid var(--border-strong); }
.switch [role="switch"]::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--text-muted); transition: transform var(--speed) var(--ease); }
.switch [role="switch"][aria-checked="true"] { background: var(--accent); border-color: var(--accent); }
.switch [role="switch"][aria-checked="true"]::after { transform: translateX(20px); background: var(--accent-contrast); }

/* ---------- engine additions (Agent A): org logos as search thumbnails, on the white logo plate ---------- */
.sr-hit .sr-logo { display: grid; place-items: center; width: 30px; height: 26px; background: var(--plate); border: 1px solid var(--plate-border); border-radius: var(--radius-xs); }
.sr-hit .sr-logo img { max-width: 26px; max-height: 20px; width: auto; height: auto; object-fit: contain; }
/* ---- 81-event-dialog.css ---- */
/* ======================================================================
   site/css/81-event-dialog.css · OWNER: Agent D (schedule & plan)
   The event dialog body (.evd, ?e=): kind, title, when (ET) with its state word, place with the
   stall number, address, mini-map and directions, the description, people, facts, source, actions.
   The modal frame is .modal in 80-dialogs.css (A). The work dialog (F) reuses .evd, .evd-actions,
   .ev-where and .source-line, so those names stay. Tokens only; no color literal.
   ====================================================================== */
.evd h2 { font-size: var(--fs-xl); margin-top: var(--sp-1); text-wrap: balance; }
.evd h2:focus { outline: none; }
.evd h2:focus-visible { outline: none; }                          /* programmatic focus on the title: no ring (it is not a control) */
.evd-kind { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text-muted); }
.evd-when { margin-top: var(--sp-3); font-weight: var(--wght-strong); font-variant-numeric: tabular-nums; line-height: 1.8; }
.evd-when .faint { font-weight: var(--wght-body); }
.evd-when .ev-status, .evd-when .unk { margin-left: 8px; }
.evd-when .unk { font-weight: var(--wght-body); }
.evd-days { list-style: none; padding: 0; margin-top: var(--sp-2); font-size: var(--fs-sm); color: var(--text-muted); }
.evd-days li { padding: 4px 0; border-top: 1px solid var(--border); }
.evd-days .tnum { display: inline-block; min-width: 10ch; color: var(--text); font-weight: var(--wght-strong); }
.evd-grid { display: grid; gap: var(--sp-4); grid-template-columns: minmax(0, 1fr); margin-top: var(--sp-4); }
@media (min-width: 700px) { .evd-grid { grid-template-columns: minmax(0, 1fr) 240px; } }
.evd-where { padding-right: 0; font-size: var(--fs-sm); }
.evd-where > span { min-width: 0; }
.evd-where a { font-weight: var(--wght-strong); color: var(--text); }
.evd-addr { display: block; margin-top: 2px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.evd-desc { margin-top: var(--sp-4); }
.evd-people { list-style: none; padding: 0; display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.evd-people a { display: flex; align-items: center; gap: 12px; min-height: var(--tap); color: var(--text); text-decoration: none; }
.evd-people a:hover b { text-decoration: underline; }
.evd-people span span { display: block; font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.35; }
.evd-facts { margin: var(--sp-5) 0 0; }
.evd-facts .fact { flex-basis: 150px; }
.evd-side .mini-map { margin: 0; }
.evd-side > .unk { font-size: var(--fs-sm); }
.evd-dir { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }
.evd-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--border); }
.evd-actions .btn-river[aria-pressed="true"] { background: var(--accent-strong); }
@media (max-width: 559px) {
  .evd-actions .btn { flex: 1 1 auto; }
  .evd-actions .btn-river { flex-basis: 100%; }
}
.evd-credits { font-size: var(--fs-sm); line-height: 1.5; max-width: var(--measure); }
.evd-when .nw { white-space: nowrap; }   /* QA: "4:00 PM ET" stays on one line */
/* ---- 85-news.css ---- */
/* ======================================================================
   site/css/85-news.css · OWNER: Agent G (home, programs & info)
   News page (placeholder: add .news-* classes here).
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 85 · news: cards (home, program pages, news.html) and the news page's filters ---------- */
.news-grid { display: grid; gap: var(--sp-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.news-card {
  position: relative; display: flex; flex-direction: column; gap: 6px; padding: var(--sp-4);
  background: var(--surface); border: 1px solid var(--border); border-top: var(--rule-mid) solid var(--rule-ink);
}
.news-card:has(.stretched:hover) { border-color: var(--border-strong); border-top-color: var(--rule-ink); }
.news-card:target { outline: 3px solid var(--focus); outline-offset: 2px; }
.news-meta { display: flex; flex-wrap: wrap; gap: 2px 0; color: var(--text-muted); }
.news-meta > * + *::before { content: "·"; margin: 0 6px; color: var(--text-faint); }
.news-kind { color: var(--text); }
.news-kind.is-sponsored { color: var(--warning); }
.news-title { font-size: var(--fs-md); line-height: var(--lh-snug); }
.news-title a { color: var(--text); }
.news-sum { font-size: var(--fs-sm); color: var(--text-muted); line-height: 1.5; }
.news-progs { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: auto; padding-top: 4px; }
.news-host { font-size: var(--fs-xs); color: var(--text-faint); overflow-wrap: anywhere; }
.news-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); margin: var(--sp-5) 0 var(--sp-2); padding: var(--sp-3) 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.news-tools .chip-row { flex: 1 1 100%; }
.news-src-pick { display: inline-flex; align-items: center; gap: 10px; }
.news-src-pick .label { color: var(--text-muted); }
.news-src-pick .select { max-width: min(70vw, 320px); }
.news-note { margin-top: var(--sp-6); font-size: var(--fs-sm); }

/* ---------- about.html (G): officials, counts, sources by site, unknowns ---------- */
.about-officials, .about-counts, .about-hosts { list-style: none; padding: 0; }
.about-officials { display: grid; gap: 0 var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); margin-top: var(--sp-4); border-top: var(--rule-mid) solid var(--rule-ink); }
.about-officials li { display: flex; align-items: center; gap: 10px; min-height: var(--tap); padding: 6px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); }
.about-officials li > span { font-weight: var(--wght-strong); }
.about-officials a { margin-left: auto; display: inline-flex; align-items: center; gap: 4px; min-height: var(--tap); }
.about-counts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); margin-top: var(--sp-5); border-top: var(--rule-heavy) solid var(--rule-ink); }
.about-counts li { padding: var(--sp-3) var(--sp-3) var(--sp-3) 0; border-bottom: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-muted); }
.about-counts b { display: block; font-family: var(--font-display); font-size: 1.75rem; font-weight: var(--wght-head); line-height: 1.1; color: var(--text); }
.about-src + .about-src { margin-top: var(--sp-6); }
.about-src h3 { display: flex; align-items: center; gap: 10px; font-size: var(--fs-lg); margin-bottom: var(--sp-2); }
.about-src h3 a { color: var(--text); }
.about-official { font-size: var(--fs-sm); color: var(--text-muted); margin-bottom: var(--sp-2); }
.about-hosts { display: grid; gap: 0 var(--sp-5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); border-top: 1px solid var(--border); }
.about-hosts li { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--border); font-size: var(--fs-sm); overflow-wrap: anywhere; }
.about-more, .about-note { margin-top: var(--sp-2); font-size: var(--fs-sm); }
.about-unk td:nth-child(3) { color: var(--text-muted); font-size: var(--fs-sm); }
.about-built { margin-top: var(--sp-6); padding-top: var(--sp-3); border-top: 1px solid var(--border); color: var(--text-muted); }
.about-src h3 a { display: inline-flex; align-items: center; min-height: var(--tap); }
#corrections .btn-row { margin-top: var(--sp-4); }
/* ---- 86-faq.css ---- */
/* ======================================================================
   site/css/86-faq.css · OWNER: Agent G (home, programs & info)
   FAQ page (placeholder: add .faq-* classes here).
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */

/* ---------- 86 · FAQ: questions as <details> (faq.html and the program pages) ---------- */
details.faq { border-bottom: 1px solid var(--border); }
details.faq > summary {
  gap: 12px; padding: 10px 0; list-style: none;
  font-family: var(--font-display); font-weight: var(--wght-head); font-size: var(--fs-md); line-height: var(--lh-snug); color: var(--text);
}
details.faq > summary::-webkit-details-marker { display: none; }
details.faq > summary::after {
  content: "+"; flex: none; margin-left: auto; width: 28px; height: 28px; display: grid; place-items: center;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  font-family: var(--font-body); font-weight: var(--wght-strong); font-size: var(--fs-base); color: var(--text-muted);
}
details.faq[open] > summary::after { content: "–"; }
details.faq > summary:hover { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.16em; }
details.faq > .prose { padding: 0 0 var(--sp-3); max-width: var(--measure); }
details.faq > .source-line { margin: 0 0 var(--sp-4); }
details.faq:target { background: var(--accent-tint); box-shadow: 0 0 0 8px var(--accent-tint); }
details.faq:target > summary { color: var(--accent-strong); }
.faq-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-4); margin: var(--sp-5) 0 var(--sp-2); padding: var(--sp-3) 0; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.faq-tools .faq-search { flex: 1 1 100%; max-width: 560px; }
.faq-tools .chip-row { flex: 1 1 100%; }
.faq-topic { margin-top: var(--sp-5); }
.faq-group .faq-list + .faq-topic { margin-top: var(--sp-6); }
.faq-note { margin-top: var(--sp-6); font-size: var(--fs-sm); }
/* ---- 90-pages.css ---- */
/* ======================================================================
   site/css/90-pages.css · OWNER: Agent A (core engine)
   Footer (river rule, motto, author block) and the 404 page.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */
/* ---------- footer: the river rule on top, the city motto in the colophon ---------- */
.footer { background: var(--sidebar-bg); border-top: 1px solid var(--border); }
@media (min-width: 1024px) { .footer { padding-left: var(--sidebar-w); } :root.rail-collapsed .footer { padding-left: 0; } }
.footer-inner { max-width: var(--content-max); margin: 0 auto; padding: 0 var(--gutter) var(--sp-7); }
.footer .river .rr { height: 30px; }
.footer-grid { display: grid; gap: var(--sp-6); grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); padding-top: var(--sp-5); }
@media (max-width: 859px) { .footer-grid { grid-template-columns: minmax(0, 1fr); } }
.footer .wm { width: 180px; height: auto; color: var(--text); }
.motto { margin-top: var(--sp-3); font-family: var(--font-display); font-size: var(--fs-md); line-height: var(--lh-snug); }
.motto em { font-style: italic; }
.motto-note { margin-top: 4px; font-size: var(--fs-xs); color: var(--text-muted); }
.footer h2 { font-family: var(--font-body); font-size: var(--fs-label); font-weight: var(--wght-strong); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--sp-2); }
.footer ul { list-style: none; padding: 0; }
.footer li a { display: flex; align-items: center; gap: 8px; min-height: var(--tap); color: var(--text); font-size: var(--fs-sm); }
.footer-author { display: flex; align-items: center; gap: 12px; margin-top: var(--sp-5); font-size: var(--fs-sm); }
.footer-author .avatar { --av: 44px; }
.footer-author a { display: inline-flex; align-items: center; min-height: var(--tap); margin-right: 12px; }
.footer-base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--sp-2) var(--sp-5); margin-top: var(--sp-6); padding-top: var(--sp-3); border-top: 1px solid var(--border); font-size: var(--fs-xs); color: var(--text-muted); }
@media (max-width: 1023px) { .footer-inner { padding-bottom: calc(var(--dock-h) + var(--sp-6)); } }

/* ---------- 404: "This stop isn't on the line" ---------- */
.nf { max-width: 640px; }
.nf .nf-line { display: flex; align-items: center; margin: var(--sp-5) 0; height: 32px; }
.nf .nf-line i { height: var(--line-w); flex: 1; background: var(--rule-ink); }
.nf .nf-line i.gap { flex: 0 0 72px; height: 0; border-top: 3px dashed var(--border-strong); background: none; }
.nf .nf-line b { width: 22px; height: 22px; flex: none; border-radius: 50%; border: 4px solid var(--rule-ink); background: var(--bg); }
.nf .nf-line b.missing { border-style: dashed; border-color: var(--border-strong); }
.nf h1 { font-size: var(--fs-2xl); }
/* ---- 99-print.css ---- */
/* ======================================================================
   site/css/99-print.css · OWNER: Agent A (core engine)
   Print and reduced motion. Kept last so it wins the cascade.
   From the final "Interchange" design (design/final/css). Partials are concatenated in lexical
   order into docs/assets/site.css. Read only tokens (var(--…)); no color literal may appear here
   (the build fails on one). Prefix new classes with your domain (see CLAUDE.md).
   ====================================================================== */
/* ---------- print: the plan and the schedule print as a timetable ---------- */
@media print {
  .topbar, .sidebar, .dock, .scrim, .to-top, .toast, .sched-bar, .filter-row, .star, .map-zoom, .ticker, .modal { display: none !important; }
  .layout { display: block; background: none; }
  .content { max-width: none; padding: 0; }
  body { background: none; color: var(--text); font-size: 11pt; }
  .ev, .plan-item { break-inside: avoid; }
  details.earlier { display: none; }
  a { text-decoration: none; }
}

/* ---------- reduced motion: nothing moves by itself; the live ring shows as a static ring ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .dot-live::after, .pin.is-live::after { opacity: 1; transform: none; animation: none; }
}
