/* ============================================================
   LEVR Flywheel — Card Grid + Search Bar (Phase 1)
   Self-contained core styles. Signature gradient-fade, blur
   scrim, hover-video, 9-state matrix, width-driven grid.
   All values map to card-design-spec.md tokens.
   ============================================================ */

/* ---- Design tokens ---- */
:root {
  /* Brand blue (SGA #2D6FB7 — HSL 210/60/45, under 80% sat cap) */
  --blue-50: #eef4fb;
  --blue-100: #d9e7f5;
  --blue-200: #aecbea;
  --blue-300: #7faadd;
  --blue-400: #5189cb;
  --blue-500: #2d6fb7;
  --blue-600: #245c9b;
  --blue-700: #1c4a7e;
  /* Focus halo. Was rgba(45,111,183,.18) — a blue tint that composited to
     1.30:1 on white, i.e. a halo you cannot see (2.4.7 / 2.4.13). Monochrome
     and opaque enough to clear 3:1 against every surface it lands on. */
  --focus-ring: rgba(14, 23, 38, 0.55);
  /* Monochrome focus halo — LEVR platform UI is B&W (change-brief-6) */
  --focus-ink: rgba(14, 23, 38, 0.14);
  /* Search wrappers get the stronger halo: their inner control is borderless,
     so the wrapper ring IS the focus indicator and must carry 3:1 on its own. */
  --focus-ink-strong: rgba(14, 23, 38, 0.55);

  /* Neutrals — single cool/slate family */
  --ink-950: #0e1726;
  --ink-900: #152033;
  --ink-800: #1b2740;
  --ink-700: #334155;
  /* --ink-600 is the FLOOR for body/meta text. --ink-500 measures 4.76:1 on
     white but only 4.19:1 on --page-bg (#eef1f4), and --ink-500/--ink-400 both
     fail outright at the 10-12px sizes this UI uses them at. 400 and 500 stay
     in the ramp for DECORATION only — icons, chevrons, hairlines, dot tracks
     — where the 3:1 non-text threshold applies instead. */
  --ink-600: #475569;
  --ink-500: #64748b;
  --ink-400: #94a3b8;
  --ink-300: #cbd5e1;
  --ink-200: #e3e8ef;
  --ink-100: #eef1f5;
  --ink-50: #f6f8fa;
  --surface: #ffffff;
  --page-bg: #eef1f4;

  /* Semantic */
  --success: #2e9a6b;
  --error: #c2463c;
  --warn: #b7791f;

  /* Radii — varied by context (change-brief-3 §1: doubled card, proportional inner) */
  --radius-card: 48px;
  --radius-image: 30px;
  --radius-button: 12px;
  --radius-pill: 9999px;
  --radius-badge: 12px;
  --radius-search: 20px;

  /* One hover language for every card treatment (was 1.09 literal / 1.04
     floating / 1.03 metric / a no-op on node assets). */
  --hover-rise: -8px;
  --hover-zoom: 1.05;

  /* Shadows — soft, layered, blue-tinted (#102A48) */
  --shadow-card-rest:
    0 1px 2px rgba(16, 42, 72, 0.04), 0 6px 20px rgba(16, 42, 72, 0.06);
  --shadow-card-hover:
    0 2px 6px rgba(16, 42, 72, 0.06), 0 18px 44px rgba(16, 42, 72, 0.14);
  --shadow-pill:
    0 1px 2px rgba(16, 42, 72, 0.1), 0 2px 8px rgba(16, 42, 72, 0.08);
  --shadow-search:
    0 1px 2px rgba(16, 42, 72, 0.04), 0 4px 18px rgba(16, 42, 72, 0.07);
  --shadow-badge: 0 1px 3px rgba(16, 42, 72, 0.12);

  /* Alert accent — the one sanctioned non-monochrome chrome color, reserved
     strictly for the review-count notification badge (change-brief-9 rev).
     Darkened from #e5484d, which carried only 3.91:1 against its own white
     numeral at 11px (1.4.3 needs 4.5). Same red, one step deeper: 5.26:1
     both as a white-on-red chip AND as red-on-white status text. */
  --alert: #ce2a2f;
  --alert-ink: #ffffff;

  /* Motion tokens */
  --dur-fast: 120ms;
  --dur-base: 220ms;
  --dur-slow: 320ms;
  --dur-video: 450ms;
  --dur-rise: 470ms; /* gentle hover rise + slow zoom (change-brief-2 #3) */
  --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out-soft: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-press: cubic-bezier(0.2, 0, 0, 1);

  /* Type */
  --font-ui: "Geist", -apple-system, "Segoe UI", system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  /* the ONE non-Geist face, and only for quoted copy: a letter, an email or a
     script is an artefact, and it should not look like the UI reading it */
  --font-serif:
    "Iowan Old Style", "Palatino Linotype", Palatino, Georgia,
    "Times New Roman", serif;
}

/* ---- Reset / base ---- */
*,
*::before,
*::after {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
}
body {
  font-family: var(--font-ui);
  background: var(--page-bg);
  color: var(--ink-700);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img,
video {
  display: block;
  max-width: 100%;
}
button {
  font-family: inherit;
  cursor: pointer;
}
a {
  text-decoration: none;
  color: inherit;
}

/* ---- Assistive-tech-only utilities ----------------------------------------
   .sr-only carries the accessible page heading, the route announcer and the
   status messages this dashboard has no visual room for. The breadcrumb IS
   the visual page title by design (see index.html §BREADCRUMB) — these give
   the same information a programmatic form without painting anything. */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link — first tab stop, invisible until focused, then a real chip in
   the top-left gutter (2.4.1 Bypass Blocks). */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--radius-button);
  background: var(--ink-950);
  color: #ffffff;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--shadow-pill);
  transform: translateY(-160%);
  transition: transform var(--dur-base) var(--ease-out-soft);
}
.skip-link:focus {
  transform: translateY(0);
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
/* Route/skip targets. These are tabindex="-1" — not reachable by Tab, focused
   only so the keyboard user LANDS on the new surface. Painting a ring round a
   whole heading or the entire <main> just looks broken; the live-region
   announcement is what tells the user they moved. Real controls keep theirs. */
main.stage:focus,
#surface-heading:focus {
  outline: none;
}
/* Scroll containers ARE tabbable (they scroll from the keyboard), so they get
   the standard monochrome ring. */
.leaf-view__frame:focus-visible,
.cl-preview__wrap:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 5px var(--ink-950);
}

/* ============================================================
   PAGE HEADER
   ============================================================ */
.page-shell {
  max-width: 2100px;
  margin-inline: auto;
}
/* Keep the header aligned to the (now wider) grid edges */
@media (min-width: 1024px) {
  .site-header {
    padding-left: 40px;
    padding-right: 40px;
  }
  .search-hero {
    padding-left: 40px;
    padding-right: 40px;
  }
}
@media (min-width: 1600px) {
  .site-header {
    padding-left: 48px;
    padding-right: 48px;
  }
  .search-hero {
    padding-left: 48px;
    padding-right: 48px;
  }
}

/* LEVR wordmark removed — the quiet SGA context label sits alone, top-right */
.site-header {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  padding: 28px 24px 4px;
}
.site-header__context {
  font-size: 13px;
  color: var(--ink-500);
  font-weight: 450;
  white-space: nowrap;
}
.site-header__context b {
  color: var(--ink-700);
  font-weight: 550;
}

@media (max-width: 560px) {
  .site-header {
    flex-wrap: wrap;
    row-gap: 4px;
  }
}

/* ============================================================
   SEARCH BAR  (spec §9)
   ============================================================ */
/* Centered search hero: search bar is the focal point of an empty upper band,
   so the card grid begins ~40% down the page (change-brief-3 §3).
   The inline padding is SYMMETRIC — max(24px, --rail-lane) on both sides — so
   reserving the walk rail's lane on the left can never pull the row off the
   viewport's centre line. (A one-sided padding-left, which is what the card
   grid uses, would shift the hero ~34px right of centre at 1440.) */
.search-hero {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 42vh;
  padding: 24px max(24px, var(--rail-lane));
  /* Stands in for the benchmark's empty .site-header, which sits ABOVE its
     42vh band and is what pushes the first card row to ~40% down the page. It
     is margin, not padding, on purpose: padding would be swallowed by the
     min-height centring and move the row half as far. */
  margin-top: 48px;
}
@media (max-width: 700px) {
  .search-hero {
    margin-top: 20px;
  }
}
@media (max-width: 700px) {
  .search-hero {
    min-height: clamp(220px, 40vh, 380px);
  }
}
/* The row plus its quiet caption, stacked and centred as one block. */
.search-hero__stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 900px;
  min-width: 0;
}
.searchbar {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  max-width: 720px;
  min-width: 0;
  height: 60px;
  padding: 0 16px;
  border-radius: var(--radius-search);
  background: var(--surface);
  border: 1px solid var(--ink-200);
  box-shadow: var(--shadow-search);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
  cursor: text;
}
.searchbar:hover {
  border-color: var(--ink-300);
}
.searchbar:focus-within,
.searchbar.is-armed {
  border-color: var(--ink-950);
  box-shadow:
    var(--shadow-search),
    0 0 0 3px var(--focus-ink-strong);
}
.searchbar__icon {
  flex: none;
  color: var(--ink-400);
  display: grid;
  place-items: center;
}
/* Brand-anchored label: the client name IS the search prompt (change-brief-9 rev).
   Bold, slightly-larger "SGA Dental" + a lighter hint — mixed weights a plain
   input placeholder can't do, so the readonly decoy input became styled text. */
.searchbar__label {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: baseline;
  gap: 9px;
  overflow: hidden;
  white-space: nowrap;
}
.searchbar__brand {
  flex: none;
  font-size: 16.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-800);
}
.searchbar__hint {
  flex: 1 1 auto;
  min-width: 0;
  /* the bar is a real <button>, and the UA's text-align:center was pushing the
     hint into the middle of its stretched flex track instead of letting it sit
     right after the brand word */
  text-align: left;
  font-size: 15px;
  font-weight: 450;
  /* --ink-400 measured 2.56:1 on the white bar. This is the only prompt text
     telling anyone what the search does, so it has to be readable. */
  color: var(--ink-600);
  overflow: hidden;
  text-overflow: ellipsis;
}
.kbd {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 1px;
  padding: 2px 8px;
  border-radius: 6px;
  background: var(--ink-100);
  color: var(--ink-600);
  font-size: 12px;
  font-weight: 600;
  font-family: var(--font-mono);
  letter-spacing: 0.02em;
}

/* ============================================================
   RESPONSIVE GRID  (spec §8)
   ============================================================ */
/* Left SAFE LANE for the fixed Walk-and-Talk rail (change-brief-8 §2).
   Reserved whenever the rail is visible (>480px) so the leftmost cards
   always clear the rail lines at rest; dropped on mobile where the rail
   is display:none. ~92px = 40px rail inset + line + breathing room. */
:root {
  --rail-lane: 0px;
}
@media (min-width: 481px) {
  :root {
    --rail-lane: 92px;
  }
}

/* Horizontal lane the pinned dock reserves at the very top-left (change-brief-9).
   The breadcrumb starts to the RIGHT of the dock so the two never overlap;
   room stays open past the dock for future main-nav items. */
/* breadcrumb start-x — retuned for the vertical (1-button-wide) dock so the
   crumb clears the WT button with comfortable air (change-brief-9 rev) */
:root {
  --dock-lane: 104px;
}
@media (min-width: 481px) {
  :root {
    --dock-lane: 118px;
  }
}

/* Column count follows viewport width: ~3 cols on a laptop window, ~4 mid,
   ~5 on a large display (change-brief-2 #4). auto-fit + a BOUNDED track
   (no 1fr) + justify-content:center lets a partial or single row sit
   CENTERED in the free space instead of piling left (change-brief-8 §1).
   CARD SIZE is the priority (users liked the larger, generous card): the
   track band is 330–380px so cards read large like before. auto-fit sizes
   the column COUNT by the track's fixed MAX, so this lands ~3 cols on a
   ~1440 laptop and up to ~5 on a 2000px+ display given the 36px gap +
   reserved rail lane — exact counts are secondary to the larger size. Cards
   flex within the 330–380 band; a short set that fits one row centers via
   the collapsed trailing tracks. Left padding reserves the rail lane so
   centering happens in the space to the RIGHT of the rail; the leftmost
   card never sits under it. The taller card (4/5 of a wider column) also
   gives the panel-variant footer text room so it never overlaps the panel. */
.card-grid {
  display: grid;
  /* BOUNDED track, not 1fr. auto-fit counts repetitions off the DEFINITE max
     (380px), then each track stops growing at 380 — so a row deliberately does
     NOT fill its content box. The leftover is the design's white space, and
     justify-content:center splits it evenly either side of the row.
     A 1fr max flexes the tracks to consume every pixel: the row runs edge to
     edge, one more column squeezes in, cards shrink, and the whole grid reads
     cramped. That is the exact regression this line exists to prevent — do not
     reintroduce 1fr here. The 330 floor is the shrink allowance for the last
     step-down (narrow single-column widths), not the sizing driver.
     .hero mirrors this exactly — keep them in sync. */
  grid-template-columns: repeat(auto-fit, minmax(330px, 380px));
  justify-content: center;
  gap: 36px;
  max-width: 2100px;
  margin-inline: auto;
  padding: 24px;
  padding-left: max(24px, var(--rail-lane));
}
@media (min-width: 1024px) {
  .card-grid {
    padding: 40px;
    padding-left: max(40px, var(--rail-lane));
  }
}
@media (min-width: 1600px) {
  .card-grid {
    padding: 48px;
    padding-left: max(48px, var(--rail-lane));
  }
}
@media (max-width: 360px) {
  .card-grid {
    padding: 16px;
  }
}
/* Mobile: rail hidden (<480px) → single full-width column, no reserved lane. */
/* minmax(0,1fr) not 1fr: a bare 1fr track has an AUTO minimum, so the
   searchbar's 499px min-content blew the .card-grid 102px past a 375px
   viewport and scrolled the whole page sideways. */
@media (max-width: 480px) {
  .card-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ============================================================
   CARD — shared base (single component, variant + modifiers)
   ============================================================ */
.card {
  position: relative;
  display: block;
  width: 100%;
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
  overflow: hidden;
  isolation: isolate;
  text-align: left;
  color: inherit;
  border: 0;
  padding: 0;
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    box-shadow var(--dur-base) var(--ease-out-soft);
  /* caps the track so a 1fr grid can add columns without the card ballooning */
  max-width: 420px;
}
/* promote only while the pointer is on it — 15 pulse cards were each holding a
   permanent compositor layer for what is only a hover shadow */
@media (hover: hover) {
  .card:hover {
    will-change: transform;
  }
}
/* hairline border via inset ring so it sits above clipped media */
.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--ink-200);
  pointer-events: none;
  z-index: 5;
}

/* Hover (all cards): the weighted move lives on the ASSET (panel / full-bleed
   image) — the card itself only deepens its shadow. (change-brief-2 #3) */
@media (hover: hover) {
  .card:hover {
    box-shadow: var(--shadow-card-hover);
  }
}
/* Active / pressed */
.card:active {
  transform: scale(0.985);
  transition-duration: var(--dur-fast);
}
.card:active {
  transition-timing-function: var(--ease-press);
}

/* inner wrapper is layout-transparent so absolute media/footer resolve to .card */
.card__inner {
  display: contents;
}

/* Whole-card click target (Card A) + focus-visible ring */
.card__stretch {
  position: absolute;
  inset: 0;
  z-index: 4;
  border-radius: inherit;
  /* buttons carry a UA-default opaque background — clear it so a
     <button> stretch target never paints over the card content */
  background: transparent;
  border: 0;
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
}
/* Monochrome focus rings — the blue solid + blue tint predated the B&W chrome
   contract and left a 1.30:1 halo. Ink reads 17:1 on every card surface.

   .card__stretch fills its card and .card is overflow:hidden, so an OUTWARD
   ring on the button was clipped away to nothing: the primary affordance on
   every grid rendered no focus indicator at all (2.4.7). The inset ring below
   is the always-works version; the :has() rule after it rings the CARD, whose
   own shadow its own overflow cannot clip, so the indicator matches the rest
   of the system. */
.card__stretch:focus-visible {
  outline: none;
  box-shadow:
    inset 0 0 0 3px var(--surface),
    inset 0 0 0 6px var(--ink-950);
}
.card:has(.card__stretch:focus-visible) {
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 5px var(--ink-950),
    var(--shadow-card-hover);
}
.card:has(.card__stretch:focus-visible) .card__stretch:focus-visible {
  box-shadow: none; /* one ring, not two, where :has() is supported */
}
.card .pill:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
  border-radius: var(--radius-pill);
}

/* ---- Media layer ---- */
.card__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
.card__media img,
.card__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  filter: saturate(0.98) contrast(0.98);
  /* baseline over-scale gives cover-overflow room so the rise never
     reveals a gap at the clipped frame edge on hover */
  transform: scale(1.04);
  transform-origin: center;
  transition: transform var(--dur-rise) var(--ease-out-soft);
}
/* Full-bleed asset rises + slowly zooms within its clipped frame */
@media (hover: hover) {
  .card:hover .card__media img,
  .card:hover .card__media video {
    transform: translateY(var(--hover-rise))
      scale(calc(var(--hover-zoom) + 0.04));
  }
}

/* Poster + video stacking for has-video */
.card__video {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-smooth);
}
.card.is-playing .card__video {
  opacity: 1;
  transition-duration: var(--dur-video);
}

/* ---- Signature gradient fade (spec §3.1) — full-bleed hero (change-brief-5)
   Image covers the WHOLE card (see .card__media inset:0). The fade is laid
   OVER it as a STRETCHED OVAL of white emanating from the BOTTOM-LEFT corner
   (an ellipse wider than tall — horizontal radius > vertical radius), with a
   denser legible core behind the eyebrow/title/subtitle/Explore and a gentle
   bottom safety wash. The oval still DISSOLVES so the photo stays clearly
   visible in the upper-right half (no whiteout). ---- */
.card__fade {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    /* stretched oval of white from the bottom-left corner. First radius (172%)
       is horizontal, second (108%) vertical — wider-than-tall = a stretched
       ellipse. Anchored just past the corner (-9% 114%) so the corner is fully
       opaque. Dense core (0.99 @ 33%, 0.9 @ 49%) yields >=7:1 title contrast on
       Ad Studio's dark photo, yet dissolves to 0 by 90% so the top-right stays
       clearly visible. */
    radial-gradient(
      174% 115% at -9% 114%,
      #ffffff 0%,
      rgba(255, 255, 255, 0.99) 35%,
      rgba(255, 255, 255, 0.93) 52%,
      rgba(255, 255, 255, 0.6) 67%,
      rgba(255, 255, 255, 0.2) 80%,
      rgba(255, 255, 255, 0) 91%
    ),
    /* gentle bottom safety wash — keeps the full footer band readable without
       flooding the bottom-right, so the shape still reads as a bottom-left oval */
    linear-gradient(
        180deg,
        rgba(255, 255, 255, 0) 46%,
        rgba(255, 255, 255, 0.16) 66%,
        rgba(255, 255, 255, 0.5) 84%,
        rgba(255, 255, 255, 0.82) 100%
      );
}

/* ============================================================
   TREATMENT 1 — LITERAL (full-bleed screenshot, text over fade)
   ============================================================ */
.card--literal {
  aspect-ratio: 4 / 5;
}
/* Full-bleed crop (change-brief-4): the source art has content in its top
   region with baked-in white below, so object-fit:cover alone shows that
   white as a hard footer. We over-scale the image past the card and pan to
   the content slice via a negative top offset (per-card --art-h / --art-top),
   so the imagery covers the WHOLE card top-to-bottom with no divide. The fade
   (a sibling layer) then lays the organic bottom-left wash over it. The hover
   rise+zoom lives on `transform`, which composes cleanly over this offset. */
.card--literal .card__media img {
  position: absolute;
  left: 0;
  width: 100%;
  top: var(--art-top, 0%);
  height: var(--art-h, 100%);
  object-position: center;
}
.card--literal .card__footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: 26px 28px 30px;
}

/* ============================================================
   TREATMENT 2 — FLOATING PANEL on a per-asset wash
   (change-brief-2: level/straight panel — no tilt — floating on a
   muted, sophisticated "gallery mat" whose color derives from the
   asset's own dominant hue via the --wash custom property, set per
   card in app.js. Falls back to a refined neutral slate.)
   ============================================================ */
.card--floating {
  --wash: #aeb7c4; /* refined neutral-slate fallback */
  aspect-ratio: 4 / 5;
  background: #ffffff;
}
/* Per-asset wash: muted tinted mat at top, dissolving to the light footer.
   Consistent weight across cards so the grid still reads as one system. */
.card__wash {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(
      125% 85% at 76% -10%,
      color-mix(in srgb, var(--wash) 82%, #ffffff) 0%,
      color-mix(in srgb, var(--wash) 34%, #ffffff) 42%,
      rgba(255, 255, 255, 0) 68%
    ),
    linear-gradient(
      172deg,
      color-mix(in srgb, var(--wash) 90%, #ffffff) 0%,
      color-mix(in srgb, var(--wash) 66%, #ffffff) 22%,
      color-mix(in srgb, var(--wash) 34%, #ffffff) 46%,
      color-mix(in srgb, var(--wash) 12%, #ffffff) 62%,
      #ffffff 80%
    );
  pointer-events: none;
}
/* The screenshot rendered as a level (untilted) inset floating panel */
.card__panel {
  position: absolute;
  top: 8.5%;
  left: 10%;
  right: 10%;
  height: 50%;
  z-index: 1;
  border-radius: var(--radius-image);
  overflow: hidden;
  background: var(--surface);
  transform-origin: center;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.7) inset,
    0 2px 6px rgba(16, 42, 72, 0.1),
    0 18px 40px rgba(16, 42, 72, 0.22);
  transition:
    transform var(--dur-rise) var(--ease-out-soft),
    box-shadow var(--dur-rise) var(--ease-out-soft);
}
/* crisp hairline on the panel edge */
.card__panel::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(16, 42, 72, 0.08);
  pointer-events: none;
  z-index: 3;
}
.card__panel img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
/* Hover: the level panel gently rises and slowly zooms in — one weighted
   move, no rotation (change-brief-2 #3). */
@media (hover: hover) {
  .card:hover .card__panel {
    transform: translateY(-8px) scale(1.04);
    box-shadow:
      0 1px 0 rgba(255, 255, 255, 0.7) inset,
      0 4px 12px rgba(16, 42, 72, 0.14),
      0 30px 60px rgba(16, 42, 72, 0.3);
  }
}
/* Floating footer sits on the light lower wash */
.card--floating .card__footer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  padding: 22px 28px 30px;
}

/* ---- Brand System — full color-palette ARTBOARD as a floating document ----
   (change-brief-5) The source is a near-square color-palette artboard, not a
   photo. It is shown WHOLE inside a slightly taller/narrower panel via
   object-fit:contain so the Color Palette header, both hex-labelled swatch rows
   and the "View Color Palette" button all read intact — no crop, no over-scale.
   Panel white bg + rounded frame mats the artboard like a gallery document. */
.card--artboard .card__panel {
  top: 4%;
  left: 13%;
  right: 13%;
  height: 53%;
  background: #ffffff;
}
.card--artboard .card__panel img {
  object-fit: contain;
  object-position: center;
  background: #ffffff;
}

/* ============================================================
   TREATMENT 3 — METRIC (designed big-number hero, all SVG/CSS)
   A clean metric composition — progress ring + Geist-Mono number +
   play-family chips — on a gentle blue-50→surface tint. No screenshot.
   Same shell, footer and hover language (rise+zoom) as the other two.
   ============================================================ */
.card--metric {
  aspect-ratio: 4 / 5;
  /* the ring + chip row + footer need ~412px; 4/5 only clears that above a
     ~330px track, and .card has overflow:hidden, so a narrower column was
     slicing the "Explore →" line off the bottom */
  min-height: 440px;
}
.card--metric .card__inner {
  display: flex;
  flex-direction: column;
  position: absolute;
  inset: 0;
}
/* Hero region — top ~55%, calm brand-tint field */
.card__metric {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 13px;
  padding: 26px 20px 20px;
  background: linear-gradient(180deg, #eef4fb 0%, #ffffff 62%);
}
/* the composition that gently rises + zooms on hover */
.metric-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  transform-origin: center;
  transition: transform var(--dur-rise) var(--ease-out-soft);
  will-change: transform;
}
@media (hover: hover) {
  .card:hover .metric-figure {
    transform: translateY(-8px) scale(1.03);
  }
}

/* Progress ring — SVG ~104px, 10px stroke, round caps */
.metric-ring {
  position: relative;
  width: 104px;
  height: 104px;
}
.metric-ring svg {
  display: block;
  width: 104px;
  height: 104px;
  overflow: visible;
}
.metric-ring circle {
  fill: none;
  stroke-width: 10;
  stroke-linecap: round;
}
.ring-track {
  stroke: var(--ink-100);
}
.ring-arc {
  stroke: var(--client-accent, var(--blue-500));
}
.ring-tip {
  /* was a hardcoded #F36F21 that put a third orange/red on a card already
     carrying the arc accent and --alert. A tint of the one client accent. */
  stroke: color-mix(
    in srgb,
    var(--client-accent, var(--blue-500)) 55%,
    #ffffff
  );
} /* short orange accent tip (SGA ring style) */

/* Big number centered inside the ring — Geist Mono, tabular */
.metric-value {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 40px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.metric-unit {
  font-family: var(--font-ui);
  font-size: 11px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-500);
}
/* Play-family chips — one compact row, wraps to at most two lines */
.metric-families {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  max-width: 96%;
  /* 2 rows of 22px chips + a 6px gap = 54px; 50 sliced the second row */
  max-height: 56px;
  overflow: hidden;
  margin-top: 2px;
}
.metric-chip {
  font-size: 11px;
  line-height: 1;
  font-weight: 500;
  color: var(--ink-600);
  background: var(--ink-50);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-badge);
  padding: 5px 9px;
  white-space: nowrap;
}
/* Footer sits in flow below the field, on the white surface */
.card__footer--metric {
  position: relative;
  z-index: 3;
  padding: 4px 28px 30px;
}

/* ============================================================
   TYPE — the 6 hierarchy levels (spec §2.6)
   ============================================================ */
.eyebrow {
  margin: 0 0 11px;
  font-size: 11px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* chrome kicker — monochrome by contract. Was --blue-700, which applyTheme()
     was overwriting with the client accent, so every eyebrow painted red. */
  color: var(--ink-600);
}
.card__title--display {
  margin: 0;
  font-size: 22px;
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card__title--b {
  margin: 0;
  font-size: 20px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink-900);
}
.card__subtitle {
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.5;
  font-weight: 450;
  color: var(--ink-600);
  max-width: 40ch;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card--b .card__subtitle {
  margin-top: 6px;
}

/* Explore link (Card A) */
.card__link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 26px;
  font-size: 14px;
  line-height: 1;
  font-weight: 500;
  color: var(--ink-700);
  transition: color var(--dur-base) var(--ease-smooth);
}
.card__link .arrow {
  display: inline-block;
  transition: transform var(--dur-base) var(--ease-out-soft);
}
@media (hover: hover) {
  .card:hover .card__link {
    color: var(--blue-600);
  }
  .card:hover .card__link .arrow {
    transform: translateX(4px);
  }
}

/* Meta row (Card B) */
.card__meta {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 14px;
  font-size: 12.5px;
  line-height: 1.4;
  font-weight: 500;
  color: var(--ink-600);
}
.card__meta .meta-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.card__meta .meta-item svg {
  color: var(--ink-400);
  flex: none;
}
.card__meta .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* Pill button (Card B) */
.pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  margin-top: 16px;
  padding: 0 20px;
  border: 0;
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  background: var(--ink-900);
  color: #ffffff;
  box-shadow: var(--shadow-pill);
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.pill:hover {
  background: var(--blue-600);
}
.pill:active {
  transform: scale(0.98);
}

/* ============================================================
   BADGE — has-video "Motion" (spec §6)
   ============================================================ */
.badge--video {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border-radius: var(--radius-pill);
  background: rgba(21, 32, 51, 0.72);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: #ffffff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: var(--shadow-badge);
}
.badge--video svg {
  flex: none;
}

/* ============================================================
   9-STATE MATRIX — loading / empty / error (spec §7)
   ============================================================ */
/* Skeleton */
.skeleton {
  position: relative;
  overflow: hidden;
}
.skel-block,
.skel-bar {
  position: relative;
  background: var(--ink-100);
  overflow: hidden;
}
.skel-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ink-100);
}
.skel-bar {
  border-radius: 6px;
}
.skel-title {
  height: 16px;
  width: 60%;
  margin-bottom: 10px;
}
.skel-sub1 {
  height: 10px;
  width: 90%;
  margin-bottom: 8px;
}
.skel-sub2 {
  height: 10px;
  width: 70%;
}
.skeleton .skel-block::after,
.skeleton .skel-bar::after,
.skeleton .skel-media::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(
    100deg,
    transparent 30%,
    rgba(255, 255, 255, 0.6) 50%,
    transparent 70%
  );
  animation: skel-shimmer 1.4s var(--ease-smooth) infinite;
}

@keyframes skel-shimmer {
  to {
    transform: translateX(100%);
  }
}

/* Empty / error media field */
.media-fallback {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--ink-50);
  text-align: center;
  padding: 16px;
}
.media-fallback svg {
  color: var(--ink-300);
}
.media-fallback.is-error svg {
  color: var(--error);
}
.media-fallback .fallback-text {
  font-size: 13px;
  color: var(--ink-400);
}
.media-fallback .fallback-retry {
  font-size: 13px;
  font-weight: 500;
  color: var(--blue-600);
  margin-top: 2px;
}

/* ============================================================
   GRID LOAD-IN — staggered reveal (spec §2.7 / §8)
   ============================================================ */
.card-grid.reveal .card {
  opacity: 0;
  transform: translateY(12px);
}
.card-grid.reveal.is-in .card {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 420ms var(--ease-out-soft),
    transform 420ms var(--ease-out-soft);
  transition-delay: var(--reveal-delay, 0ms);
}

/* ============================================================
   COMMAND MODAL (stub — spec §9)
   ============================================================ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 14vh 20px 20px;
  background: rgba(16, 42, 72, 0.35);
}
.modal {
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border-radius: 20px;
  border: 1px solid var(--ink-200);
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.24);
  overflow: hidden;
}
.modal__search {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--ink-100);
}
.modal__search svg {
  color: var(--ink-400);
  flex: none;
}
.modal__search input {
  flex: 1;
  border: 0;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-size: 16px;
  color: var(--ink-700);
  caret-color: var(--ink-700);
}
.modal__search input::placeholder {
  color: var(--ink-400);
}
.cmd-count {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-600);
  white-space: nowrap;
}

/* scrollable results — every clickable destination, grouped */
.cmd-results {
  max-height: 54vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px;
}
.cmd-group {
  padding: 0;
}
.cmd-group + .cmd-group {
  margin-top: 4px;
}
.cmd-group__label {
  padding: 12px 12px 6px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.cmd-row {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  border-radius: 12px;
  text-align: left;
  cursor: pointer;
  scroll-margin: 8px;
}
.cmd-row.is-active {
  background: var(--ink-100);
}
.cmd-row__title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-900);
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cmd-row__slug {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--ink-600);
}
.cmd-empty {
  padding: 40px 24px 44px;
  text-align: center;
  font-size: 14px;
  color: var(--ink-500);
}
.modal__foot {
  display: flex;
  align-items: center;
  /* nowrap clipped "Esc close" to "Esc clo" below ~400px (scrollWidth 346 in a
     333px box). The hints are equal-weight, so let them stack. */
  flex-wrap: wrap;
  gap: 10px 18px;
  padding: 12px 20px;
  border-top: 1px solid var(--ink-100);
  font-size: 12px;
  color: var(--ink-600);
}
.cmd-hint {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.cmd-hint--end {
  margin-left: auto;
}
.modal__foot .kbd {
  font-size: 11px;
}

/* Modal enter transition (Alpine x-transition-driven classes) */
.modal-enter-active,
.modal-leave-active {
  transition: opacity var(--dur-base) var(--ease-out-soft);
}
.modal-scale-active {
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    opacity var(--dur-base) var(--ease-out-soft);
}

/* ============================================================
   WALK-AND-TALK — entry, popover, rail, session modal
   (walk-and-talk-build-brief). Reuses the same tokens, 48px
   corners, single SGA blue and ease-out-soft motion family.
   ============================================================ */

/* ---- Search hero row: [Walk & Talk entry] [search bar] ---- */
.search-hero__row {
  display: flex;
  align-items: center;
  gap: 22px;
  width: 100%;
  max-width: 900px;
}
.search-hero__row .searchbar {
  max-width: none;
  flex: 1 1 auto;
}

/* ---- Audio-levels / waveform icon (NEVER a microphone) ---- */
.wt-levels {
  display: inline-flex;
  align-items: flex-end;
  gap: 3px;
  height: 20px;
  color: inherit;
  flex: none;
}
.wt-levels i {
  display: block;
  width: 3px;
  height: 100%;
  border-radius: 2px;
  background: currentColor;
  transform: scaleY(0.4);
  transform-origin: center bottom;
  animation: wt-bar-idle 1.5s var(--ease-smooth) infinite;
}
.wt-levels.is-live i {
  animation-name: wt-bar-live;
  animation-duration: 0.95s;
}
/* Metered: the bars are being driven by a real AnalyserNode (see WalkVoice), so
   the canned animation has to get out of the way — a CSS animation outranks the
   inline transform the meter writes, and the bars would keep dancing to nothing
   while the microphone was muted or dead. The transition is what keeps 60fps
   RMS from looking like static. */
.wt-levels.is-metered i {
  animation: none;
  transition: transform 90ms linear;
}
.wt-levels--sm {
  height: 13px;
}
.wt-levels--lg {
  height: 34px;
  gap: 4px;
}
.wt-levels--lg i {
  width: 4px;
}
/* Larger waveform for the circular Walk & Talk button (change-brief-6 §1) */
.wt-levels--circle {
  height: 30px;
  gap: 4px;
}
.wt-levels--circle i {
  width: 4px;
  border-radius: 2.5px;
}
.wt-levels i:nth-child(1) {
  animation-delay: -0.2s;
}
.wt-levels i:nth-child(2) {
  animation-delay: -0.55s;
}
.wt-levels i:nth-child(3) {
  animation-delay: -0.85s;
}
.wt-levels i:nth-child(4) {
  animation-delay: -0.35s;
}
.wt-levels i:nth-child(5) {
  animation-delay: -0.65s;
}
.wt-levels i:nth-child(6) {
  animation-delay: -0.1s;
}
.wt-levels i:nth-child(7) {
  animation-delay: -0.5s;
}
@keyframes wt-bar-idle {
  0%,
  100% {
    transform: scaleY(0.35);
  }
  50% {
    transform: scaleY(0.72);
  }
}
@keyframes wt-bar-live {
  0%,
  100% {
    transform: scaleY(0.22);
  }
  50% {
    transform: scaleY(1);
  }
}
/* The audio levels are the one piece of always-running motion in the chrome, so
   they get an explicit kill rather than relying on the global reduce block
   further down (which only clamps iteration-count). Under `reduce` the bars
   hold their resting scaleY(.4) — the icon still reads as levels, it just
   stops moving. */
@media (prefers-reduced-motion: reduce) {
  .wt-levels i,
  .wt-levels.is-live i,
  .wt-entry:hover .wt-levels i,
  .wt-entry.is-open .wt-levels i,
  .pin-dock__wt:hover .wt-levels i,
  .pin-dock__wt.is-open .wt-levels i {
    animation: none !important;
  }
  .wt-rail__item.is-change.is-in-progress .wt-rail__line {
    animation: none !important;
  }
}

/* ---- Entry element — a CIRCLE, icon-only, near-black w/ white waveform.
   Diameter ~2x the 60px search field (120px). Vertically centered on the
   search bar; the taller circle extends above and below it. (change-brief-6 §1) */
.wt-entry-wrap {
  position: relative;
  flex: none;
}
.wt-entry {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 120px;
  height: 120px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950); /* solid near-black #0E1726 */
  color: #ffffff; /* white waveform icon */
  box-shadow:
    0 2px 8px rgba(14, 23, 38, 0.2),
    0 12px 32px rgba(14, 23, 38, 0.24);
  transition:
    box-shadow var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.wt-entry:hover {
  background: #060b14;
  box-shadow:
    0 3px 10px rgba(14, 23, 38, 0.24),
    0 18px 44px rgba(14, 23, 38, 0.3);
  transform: scale(1.045);
}
/* the bars come alive on hover / when the popover is open */
.wt-entry:hover .wt-levels i,
.wt-entry.is-open .wt-levels i {
  animation-name: wt-bar-live;
  animation-duration: 0.8s;
}
.wt-entry:active {
  transform: scale(0.99);
  transition-duration: var(--dur-fast);
}
.wt-entry.is-open {
  background: #060b14;
}
.wt-entry:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px #ffffff,
    0 0 0 6px var(--ink-950);
}

/* "Walk & Talk" wordmark — fades / slides in centered UNDER the circle on hover */
.wt-entry__label {
  position: absolute;
  top: calc(100% + 14px);
  left: 60px; /* circle center (120px wide wrap) */
  transform: translateX(-50%) translateY(5px);
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1;
  color: var(--ink-900);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.wt-entry-wrap:hover .wt-entry__label,
.wt-entry:focus-visible ~ .wt-entry__label {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* hide the hover label while the popover is open (the popover sits below) */
.wt-entry-wrap:has(.wt-entry.is-open) .wt-entry__label {
  opacity: 0;
}

/* ---- Popover (2 modes + Start) ---- */
/* The popover is a single shared element with two triggers (hero button /
   pinned dock), so it cannot live inside either one — the hero is display:none
   the moment you drill, and the dock is visibility:hidden until you do. It was
   position:absolute with NO positioned ancestor, so `top: calc(100% + 12px)`
   resolved against the initial containing block and parked the dialog at
   y=912 — a full viewport below the button that opened it. Anchoring is now
   done in JS (positionWtPopover) against whichever trigger is live; these are
   the pre-paint defaults. */
.wt-popover {
  position: fixed;
  top: 120px;
  left: 24px;
  z-index: 80;
  width: 344px;
  max-width: calc(100vw - 32px);
  padding: 20px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 26px;
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.22);
}
.wt-pop-active {
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.wt-popover__title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
}
.wt-popover__sub {
  margin: 4px 0 14px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-500);
}
.wt-modes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.wt-mode {
  position: relative;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  width: 100%;
  padding: 13px 40px 13px 14px;
  text-align: left;
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  background: var(--surface);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    background var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}
.wt-mode:hover {
  border-color: var(--ink-300);
  background: var(--ink-50);
}
.wt-mode.is-sel {
  border-color: var(--ink-900);
  background: var(--ink-50);
  box-shadow: 0 0 0 3px var(--focus-ink);
}
.wt-mode:focus-visible {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 3px var(--focus-ink);
}
.wt-mode__ico {
  flex: none;
  margin-top: 1px;
  color: var(--ink-700);
}
.wt-mode__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.wt-mode__name {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-900);
}
.wt-mode__desc {
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-500);
}
.wt-mode__tick {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1.5px solid var(--ink-300);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    background var(--dur-base) var(--ease-smooth);
}
.wt-mode.is-sel .wt-mode__tick {
  border-color: var(--ink-950);
  background: var(--ink-950);
  box-shadow: inset 0 0 0 3px #ffffff;
}
.wt-start {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: 46px;
  margin-top: 14px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--ink-950);
  color: #ffffff;
  font-size: 14px;
  font-weight: 600;
  box-shadow: var(--shadow-pill);
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.wt-start:hover {
  background: var(--ink-800, #1b2740);
}
.wt-start:active {
  transform: scale(0.98);
}

/* ============================================================
   LEFT-EDGE QUEUE RAIL
   ============================================================ */
.wt-rail {
  position: fixed;
  left: 40px; /* inset ~40px off the left edge (change-brief-6 §2) */
  top: 50%;
  transform: translateY(-50%);
  z-index: 70;
  display: flex;
  flex-direction: column;
  /* No gap: the 24px hit area on each item IS the rhythm now — see
     .wt-rail__item. A 7px gap plus a 6px item (the reference's spacing) put the
     lines on a 13px pitch, which axe flags as a serious 2.5.8 target-size
     failure and which no thumb can hit. */
  gap: 0;
  padding: 12px 12px 12px 0;
}
.wt-rail__head {
  display: grid;
  place-items: center;
  width: 24px;
  height: 20px;
  margin-bottom: 8px;
  color: var(--ink-400);
}
/* The visible mark stays a 2px hairline; the BUTTON is 24px tall so it clears
   WCAG 2.2 §2.5.8 (target size, minimum). Same trick the card actions use —
   expand the hit area with padding, leave the art alone. Deliberately 24 and
   not 44: at 44 the lines stop reading as a stack and start reading as a menu,
   and 24 with zero gap already means no two targets overlap. */
.wt-rail__item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 24px;
  padding: 11px 8px 11px 0;
  margin: 0;
  border: 0;
  background: transparent;
  position: relative;
}
/* the line — short hairline at rest; monochrome status encoding below */
.wt-rail__line {
  display: block;
  flex: none;
  width: 22px;
  height: 2px;
  border-radius: 1px;
  background: var(--ink-300);
  transition:
    width var(--dur-slow) var(--ease-out-soft),
    height var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth),
    opacity var(--dur-base) var(--ease-smooth);
}
/* MONOCHROME status encoding — ALL lines a uniform 2px; status by TONE only,
   never thickness (change-brief-7 §3). */
/* Proposed  → light gray */
.wt-rail__item.is-change.is-proposed .wt-rail__line {
  height: 2px;
  background: var(--ink-300);
}
/* In progress → dark gray, subtle opacity pulse */
.wt-rail__item.is-change.is-in-progress .wt-rail__line {
  height: 2px;
  background: var(--ink-600);
  animation: wt-pulse 2.4s var(--ease-smooth) infinite;
}
/* Executed → solid BLACK — the clear "done" cue, via tone not weight */
.wt-rail__item.is-change.is-executed .wt-rail__line {
  height: 2px;
  background: var(--ink-950);
}
/* Conversation logged → muted gray; keeps its distinct shorter length + rounded cap */
.wt-rail__item.is-conversation .wt-rail__line {
  width: 12px;
  height: 2px;
  border-radius: 9999px;
  background: var(--ink-400);
}
@keyframes wt-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.5;
  }
}

/* hover / focus: the line organically extends (still monochrome) */
.wt-rail__item:hover .wt-rail__line,
.wt-rail__item:focus-visible .wt-rail__line {
  width: 42px;
}
.wt-rail__item.is-conversation:hover .wt-rail__line,
.wt-rail__item.is-conversation:focus-visible .wt-rail__line {
  width: 32px;
}
.wt-rail__item:focus-visible {
  outline: none;
}
/* keyboard parity with hover: the line has no visible :focus-visible ring of
   its own, so revealing the card IS the focus indicator */
.wt-rail__item:focus-visible .wt-rail__card {
  opacity: 1;
  transform: translate(0, -50%);
}
.wt-rail__item:focus-visible .wt-rail__line {
  background: var(--ink-950);
}

/* revealed card — ABSOLUTELY positioned so it never occupies vertical space
   in the rail column (that's what lets the lines sit ~11px apart). Named
   __card, not __label: .wt-rail__label was also being used for the rail's own
   heading, and one selector cannot be both a floating popover and a caption. */
.wt-rail__card {
  position: absolute;
  left: 36px;
  top: 50%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 6px;
  /* width:max-content is load-bearing. The card is absolutely positioned
     inside .wt-rail__item, whose box is only the ~30px line — so shrink-to-fit
     resolved against a NEGATIVE available width and pinned the card at
     min-width, which then wrapped the author onto a second row no matter how
     high max-width went. Sizing to content and clamping fixes it.
     340, not the reference's 300: our chip also carries a "Sample" affix and
     real names are longer than "Chad". */
  width: max-content;
  min-width: 226px;
  max-width: 340px;
  padding: 11px 14px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 14px;
  box-shadow: var(--shadow-card-hover);
  text-align: left;
  opacity: 0;
  transform: translate(-6px, -50%);
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.wt-rail__item:hover .wt-rail__card {
  opacity: 1;
  transform: translate(0, -50%);
}
.wt-rail__title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-900);
}
.wt-rail__meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.wt-rail__by {
  font-size: 11.5px;
  /* --ink-500 is 4.76:1 on --surface; the card's background IS --surface, so
     this one stays where the token puts it. */
  color: var(--ink-500);
}

/* ---- empty pack → one dashed placeholder line, never an empty box ----
   The rail keeps its reserved lane (--rail-lane) so nothing reflows the day
   the first real walk lands; it just has nothing to list yet. */
.wt-rail__empty {
  display: flex;
  align-items: center;
  min-height: 24px;
  padding: 11px 8px 11px 0;
  pointer-events: none;
}
.wt-rail__line--empty {
  width: 22px;
  height: 0;
  border-radius: 0;
  background: transparent;
  border-top: 2px dashed var(--ink-300);
  opacity: 0.75;
}

@media (max-width: 480px) {
  .wt-rail {
    display: none;
  }
}

/* ---- status/type chip (shared: rail label + modal header) ---- */
.wt-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.wt-chip__dot {
  opacity: 0.5;
}
/* monochrome status chips (change-brief-6 §2/§4) */
.wt-chip--proposed {
  background: var(--ink-100);
  color: var(--ink-600);
  border-color: var(--ink-200);
}
.wt-chip--in-progress {
  background: var(--ink-200);
  color: var(--ink-700);
  border-color: var(--ink-300);
}
.wt-chip--executed {
  background: var(--ink-900);
  color: #ffffff;
  border-color: var(--ink-900);
}
.wt-chip--convo {
  background: var(--ink-50);
  /* --ink-500 measures 4.47:1 on --ink-50 — under the 1.4.3 bar by a hair, and
     this chip is now on every conversation in the rail. One step darker
     (--ink-600) puts it at 7.12:1. */
  color: var(--ink-600);
  border-color: var(--ink-200);
}
/* "Sample" affix — marks a demonstration session so nobody reads it as a real
   recording. Its own solid light pill rather than an inherited/faded one, so
   its contrast is fixed no matter which chip tone hosts it (including the
   near-black --executed chip). */
.wt-chip__affix {
  margin-left: 3px;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--ink-300);
  color: var(--ink-700);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* ============================================================
   WALK-AND-TALK SESSION MODAL
   ============================================================ */
.wt-backdrop {
  align-items: center;
  padding: 5vh 20px;
  background: rgba(16, 42, 72, 0.28);
  -webkit-backdrop-filter: blur(16px) saturate(0.9);
  backdrop-filter: blur(16px) saturate(0.9);
}
@media (prefers-reduced-motion: reduce) {
  .wt-backdrop {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
}
.wt-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 640px;
  max-height: 88vh;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-card); /* 48px soft corners */
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 40px 80px rgba(16, 42, 72, 0.28);
  overflow: hidden;
}
.wt-modal__head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 28px 32px 18px;
  border-bottom: 1px solid var(--ink-100);
}
.wt-modal__headmain {
  flex: 1;
  min-width: 0;
}
.wt-modal__mode {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.wt-modal__title {
  margin: 0;
  font-size: 22px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.wt-modal__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}
.wt-avatar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--ink-100);
  color: var(--ink-700);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
}
.wt-modal__by {
  font-size: 12.5px;
  color: var(--ink-500);
}
.wt-modal__by b {
  color: var(--ink-700);
  font-weight: 600;
}
.wt-modal__x {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 38px;
  border: 1px solid var(--ink-200);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink-500);
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth);
}
.wt-modal__x:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-700);
}

/* transcript body */
.wt-modal__body {
  flex: 1 1 auto;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 22px 32px 10px;
}
.wt-resume {
  margin: 0;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-400);
}
/* The handoff to voice. It is the only filled, dark element between the header
   and the transcript because it is the only thing on this screen that starts a
   real conversation — the composer beneath is the fallback, and it is styled
   like one. Sits OUTSIDE .wt-modal__body so it never scrolls away. */
.wt-voice {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 32px;
  padding: 12px 16px;
  border-radius: var(--radius-button);
  background: var(--ink-950);
  color: var(--surface);
  text-decoration: none;
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-smooth);
}
.wt-voice:hover {
  background: var(--ink-800);
  transform: translateY(-1px);
}
.wt-voice:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
.wt-voice__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
}
.wt-voice__ico .wt-levels i {
  background: var(--surface);
}
.wt-voice__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.wt-voice__name {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.wt-voice__desc {
  font-size: 11.5px;
  /* White at 72% over --ink-950, pre-blended to an OPAQUE value: the same
     colour to the eye, but a colour a contrast checker (ours and the browser's)
     can actually measure instead of reading the alpha off and scoring pure
     white. Computed 9.65:1 on --ink-950. */
  color: #bcbec2;
}
.wt-voice__go {
  flex: none;
  color: #bcbec2;
}

/* ---- Two ways to have the same walk ----
   "Talk here" runs the realtime session in this tab; "Talk on your phone"
   hands the same conversation to the phone app. Only ONE of them can be the
   primary, and it is the one that starts talking without leaving the screen —
   so .wt-talk takes the filled treatment and the phone link steps back to an
   outline BESIDE it. When the phone link is alone (every walk this browser
   didn't start) it keeps the filled treatment it always had: the modifier is
   applied by the template, not by the presence of a sibling. */
.wt-voicerow {
  display: flex;
  align-items: stretch;
  gap: 10px;
  margin: 0 32px;
}
.wt-voicerow > .wt-voice,
.wt-voicerow > .wt-talk {
  margin: 0;
  flex: 1 1 0;
  min-width: 0;
}
.wt-talk {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border: 0;
  border-radius: var(--radius-button);
  background: var(--ink-950);
  color: var(--surface);
  text-align: left;
  font: inherit;
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-smooth);
}
.wt-talk:hover {
  background: var(--ink-800);
  transform: translateY(-1px);
}
.wt-talk:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}
.wt-talk__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  color: var(--surface);
}
.wt-talk__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}
.wt-talk__name {
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.wt-talk__desc {
  font-size: 11.5px;
  /* Same pre-blended opaque value .wt-voice__desc uses, for the same reason:
     measurable by a contrast checker. 9.65:1 on --ink-950. */
  color: #bcbec2;
}
/* The phone handoff, demoted to secondary while "Talk here" is on offer. */
.wt-voice--second {
  background: var(--surface);
  color: var(--ink-900);
  border: 1px solid var(--ink-200);
}
.wt-voice--second:hover {
  background: var(--ink-100);
}
.wt-voice--second .wt-voice__ico {
  background: var(--ink-100);
}
.wt-voice--second .wt-voice__ico .wt-levels i {
  background: var(--ink-800);
}
.wt-voice--second .wt-voice__desc {
  color: var(--ink-600);
}
.wt-voice--second .wt-voice__go {
  color: var(--ink-500);
}

/* The live session bar. Replaces the two offers while a session is up, so the
   screen only ever shows ONE truth about the microphone: either you can start
   talking, or you are talking. The bars are driven by the mic's AnalyserNode
   (see WalkVoice), which is what makes them evidence rather than decoration. */
.wt-voicebar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 32px;
  padding: 12px 16px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-button);
  background: var(--ink-100);
}
.wt-voicebar__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  color: var(--ink-900);
}
.wt-voicebar__txt {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
}
.wt-voicebar__sub {
  font-size: 11.5px;
  font-weight: 400;
  color: var(--ink-600);
}
.wt-voicebar__btn {
  flex: none;
}
@media (max-width: 620px) {
  .wt-voicerow {
    flex-direction: column;
  }
}
/* An empty real walk. Same quiet register as .wt-resume: this is a state, not
   a message. */
.wt-empty-turns {
  margin: 0;
  padding: 10px 0;
  text-align: center;
  font-size: 12.5px;
  color: var(--ink-600);
}
/* Adapter failure, where it happened. Not an alert bar across the top of the
   app: the thing that failed was this walk, so it says so next to this walk's
   composer. */
.wt-modal__notice {
  margin: 0;
  padding: 8px 32px 0;
  font-size: 12.5px;
  color: var(--error);
}
.wt-turn {
  display: flex;
  flex-direction: column;
  gap: 5px;
  max-width: 82%;
}
.wt-turn--you {
  align-self: flex-end;
  align-items: flex-end;
}
.wt-turn--kb {
  align-self: flex-start;
  align-items: flex-start;
}
.wt-turn__who {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-400);
}
.wt-bubble {
  margin: 0;
  padding: 12px 16px;
  font-size: 14px;
  line-height: 1.55;
  border-radius: 18px;
}
/* monochrome conversation: speaker = near-black, KB = light-gray (change-brief-6 §4) */
.wt-turn--you .wt-bubble {
  background: var(--ink-950);
  color: #ffffff;
  border-bottom-right-radius: 6px;
}
.wt-turn--kb .wt-bubble {
  background: var(--ink-100);
  color: var(--ink-800);
  border: 1px solid var(--ink-200);
  border-bottom-left-radius: 6px;
}

/* transcribe mode → one flowing transcription, no bubbles */
.wt-modal__body.is-transcribe .wt-turn {
  max-width: 100%;
  align-self: stretch;
  align-items: stretch;
}
.wt-modal__body.is-transcribe .wt-turn__who {
  display: none;
}
.wt-modal__body.is-transcribe .wt-bubble {
  background: transparent;
  color: var(--ink-700);
  border: 0;
  padding: 0;
  border-radius: 0;
  font-size: 15.5px;
  line-height: 1.7;
}

/* live listening affordance (simulated) */
.wt-listening {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  align-self: flex-start;
  padding: 9px 16px;
  border-radius: 16px;
  background: var(--ink-100);
  color: var(--ink-700);
}
.wt-listening__txt {
  font-size: 13px;
  font-weight: 600;
}

/* queued confirmation — monochrome (change-brief-6 §4) */
.wt-queued {
  display: flex;
  align-items: center;
  gap: 10px;
  align-self: stretch;
  padding: 12px 16px;
  border-radius: 14px;
  background: var(--ink-100);
  color: var(--ink-900);
  font-size: 13px;
  font-weight: 600;
}
.wt-queued__ico {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  flex: none;
}

/* continue affordances (existing sessions) */
.wt-continue {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 32px 2px;
}
.wt-ghost {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-700);
  font-size: 12.5px;
  font-weight: 500;
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth);
}
.wt-ghost svg {
  color: var(--ink-400);
  transition: color var(--dur-base) var(--ease-smooth);
}
.wt-ghost:hover {
  background: var(--ink-50);
  border-color: var(--ink-400);
  color: var(--ink-900);
}
.wt-ghost:hover svg {
  color: var(--ink-700);
}

/* ---- typed composer -------------------------------------------------
   Talking is the primary mode — hence the two voice affordances ABOVE this
   row and the deliberately quieter, secondary weight here. It exists because
   there are rooms you cannot talk in. With a real backend wired the turn is
   persisted to the conversation (sendWtMessage -> adapter.sendTurn); with the
   Mock adapter it stays in the browser. */
.wt-composer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 32px 4px;
}
.wt-composer__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  padding: 0 16px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-pill);
  background: var(--surface);
  font-family: inherit;
  font-size: 14px;
  color: var(--ink-800);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}
/* --ink-400 measures 2.56:1 — a placeholder is the only instruction in an
   empty field, so it holds the full body-text bar (--ink-600 = 6.68:1). */
.wt-composer__input::placeholder {
  color: var(--ink-600);
}
.wt-composer__input:hover {
  border-color: var(--ink-300);
}
.wt-composer__input:focus {
  outline: none;
  border-color: var(--ink-950);
  box-shadow: 0 0 0 3px var(--focus-ink-strong);
}
.wt-composer__send {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.wt-composer__send:hover:not(:disabled) {
  background: #060b14;
}
.wt-composer__send:active:not(:disabled) {
  transform: scale(0.96);
}
/* disabled is a real visual state, not just a dead click */
.wt-composer__send:disabled {
  background: var(--ink-200);
  color: var(--ink-500);
  cursor: default;
}
.wt-composer__send:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px #ffffff,
    0 0 0 4px var(--ink-950);
}

/* footer actions */
.wt-modal__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 32px 22px;
  border-top: 1px solid var(--ink-100);
}
.wt-foot__left {
  display: flex;
  align-items: center;
  gap: 8px;
}
.wt-foot__hint {
  font-size: 12px;
  color: var(--ink-500);
}
.wt-foot__right {
  display: flex;
  align-items: center;
  gap: 10px;
}
.wt-btn {
  height: 44px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-size: 13.5px;
  font-weight: 600;
  transition:
    background var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.wt-btn:active {
  transform: scale(0.98);
}
/* primary action = solid black; secondary = ghost/outline B&W (change-brief-6 §4) */
.wt-btn--primary {
  background: var(--ink-950);
  color: #ffffff;
  box-shadow: var(--shadow-pill);
}
.wt-btn--primary:hover {
  background: var(--ink-800);
}
.wt-btn--primary:disabled {
  background: var(--ink-500);
  cursor: default;
}
.wt-btn--ghost {
  background: var(--surface);
  border-color: var(--ink-200);
  color: var(--ink-700);
}
.wt-btn--ghost:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
}
.wt-btn--close {
  background: var(--surface);
  border-color: var(--ink-200);
  color: var(--ink-700);
}
.wt-btn--close:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
}

@media (max-width: 620px) {
  .search-hero__row {
    flex-direction: column;
    align-items: center;
    gap: 18px;
  }
  .search-hero__row .searchbar {
    width: 100%;
  }
  /* circle stays a circle on mobile, just a touch smaller */
  .wt-entry {
    width: 96px;
    height: 96px;
  }
  .wt-entry__label {
    left: 48px;
  }
  .wt-levels--circle {
    height: 26px;
  }
  /* Centring by translate fought the JS anchor (inline `left` won, the
     transform then shifted it 172px off the trigger). positionWtPopover()
     clamps to the viewport instead, which handles narrow widths natively. */
  .wt-popover {
    transform: none;
    right: auto;
  }
  .wt-modal__head,
  .wt-modal__body,
  .wt-continue,
  .wt-composer,
  .wt-modal__foot {
    padding-left: 20px;
    padding-right: 20px;
  }
}

/* ============================================================
   PINNED CONTROL DOCK (change-brief-9)
   Persistent top-left cluster: compact Walk & Talk bars + a
   circular search button. Hidden at root-top; flies up into the
   corner once the hero scrolls away, and stays pinned at every
   drill level. Strictly monochrome LEVR chrome.
   ============================================================ */
.pin-dock {
  position: fixed;
  top: 18px;
  left: 24px;
  z-index: 80; /* above rail (70), below modals (100) */
  /* Hidden state: parked just up-and-right of its resting spot, ready to
     fly into the corner. visibility keeps it out of the a11y/hit tree. */
  opacity: 0;
  visibility: hidden;
  transform: translate(8px, -10px) scale(1.06);
  transform-origin: top left;
  pointer-events: none;
  transition:
    opacity 460ms var(--ease-out-soft),
    transform 460ms var(--ease-out-soft),
    visibility 0s linear 460ms;
}
.pin-dock.is-docked {
  opacity: 1;
  visibility: visible;
  transform: translate(0, 0) scale(1);
  pointer-events: auto;
  transition:
    opacity 460ms var(--ease-out-soft),
    transform 460ms var(--ease-out-soft),
    visibility 0s linear 0s;
}
@media (min-width: 481px) {
  .pin-dock {
    left: 28px;
  }
}

.pin-dock__cluster {
  display: inline-flex;
  flex-direction: column; /* WT on top, search below (change-brief-9 rev) */
  align-items: flex-start;
  gap: 10px;
}
/* each control owns a relative box so its hover label can sit to the right
   without pushing the cluster around */
.pin-dock__ctrl {
  position: relative;
  display: inline-flex;
}

/* ---- Walk & Talk dock button — near-black, white animated bars ---- */
.pin-dock__wt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  box-shadow:
    0 1px 3px rgba(14, 23, 38, 0.18),
    0 6px 18px rgba(14, 23, 38, 0.2);
  transition:
    box-shadow var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.pin-dock__wt:hover {
  background: #060b14;
  transform: scale(1.06);
  box-shadow:
    0 2px 6px rgba(14, 23, 38, 0.24),
    0 10px 26px rgba(14, 23, 38, 0.26);
}
.pin-dock__wt:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.pin-dock__wt.is-open {
  background: #060b14;
}
.pin-dock__wt:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px #ffffff,
    0 0 0 4px var(--ink-950);
}
/* bars come alive on hover / when the popover is open (mirrors .wt-entry) */
.pin-dock__wt:hover .wt-levels i,
.pin-dock__wt.is-open .wt-levels i {
  animation-name: wt-bar-live;
  animation-duration: 0.8s;
}
/* shrink the shared circle waveform to fit the compact 48px button */
.pin-dock__wt .wt-levels--circle {
  height: 18px;
  gap: 3px;
}
.pin-dock__wt .wt-levels--circle i {
  width: 3px;
  border-radius: 2px;
}

/* ---- Ask-anything dock button — light circle, ink glyph ---- */
.pin-dock__search {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--ink-200);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink-600);
  box-shadow: var(--shadow-search);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    background var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-out-soft);
}
.pin-dock__search:hover {
  border-color: var(--ink-300);
  background: var(--ink-50);
  color: var(--ink-900);
  transform: scale(1.06);
}
.pin-dock__search:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.pin-dock__search:focus-visible {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 3px var(--focus-ink);
}

/* ---- Hover label (subtle, absolute → no layout shift) ---- */
.pin-dock__label {
  position: absolute;
  top: 50%;
  left: calc(100% + 8px);
  transform: translate(-4px, -50%);
  padding: 4px 9px;
  background: var(--ink-950);
  color: #ffffff;
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.005em;
  white-space: nowrap;
  border-radius: var(--radius-badge);
  box-shadow: var(--shadow-badge);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.pin-dock__ctrl:hover .pin-dock__label,
.pin-dock__wt:focus-visible + .pin-dock__label,
.pin-dock__search:focus-visible + .pin-dock__label {
  opacity: 1;
  transform: translate(0, -50%);
}
/* hide the WT label while its popover is open (popover drops below the dock) */
.pin-dock:has(.pin-dock__wt.is-open)
  .pin-dock__ctrl:first-child
  .pin-dock__label {
  opacity: 0;
}

/* ---- Dock popover — same component, anchored under the dock, left origin.
   `transform: none` overrides the ≤620px hero-popover centering so the dock
   popover stays left-aligned under the dock at every width. ---- */
.wt-popover--dock {
  top: calc(100% + 10px);
  left: 0;
  right: auto;
  transform: none;
  transform-origin: top left;
}

@media (max-width: 480px) {
  .pin-dock {
    top: 12px;
    left: 16px;
  }
  .pin-dock__cluster {
    gap: 8px;
  }
  .pin-dock__wt,
  .pin-dock__search {
    width: 44px;
    height: 44px;
  }
}

/* ============================================================
   BRAND NAV ORB (bottom-left) — the LEVR curve-mark as the persistent
   navigation / settings entry point, mirroring the top-left dock. Dark
   circle + white mark (echoes the WT primary); alert badge top-right.
   ============================================================ */
.nav-orb-wrap {
  position: fixed;
  bottom: 20px;
  left: 24px;
  z-index: 80; /* same layer as the dock */
}
@media (min-width: 481px) {
  .nav-orb-wrap {
    left: 28px;
    bottom: 24px;
  }
}

.nav-orb {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  box-shadow:
    0 1px 3px rgba(14, 23, 38, 0.18),
    0 6px 18px rgba(14, 23, 38, 0.2);
  transition:
    box-shadow var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.nav-orb:hover {
  background: #060b14;
  transform: scale(1.06);
  box-shadow:
    0 2px 6px rgba(14, 23, 38, 0.24),
    0 10px 26px rgba(14, 23, 38, 0.26);
}
.nav-orb:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.nav-orb:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px #ffffff,
    0 0 0 4px var(--ink-950);
}
.nav-orb__mark {
  width: 24px;
  height: 24px;
  overflow: visible;
}

/* Review-count alert badge — the single sanctioned accent, top-right of
   the circle. White ring separates it from both the dark orb and the page. */
.nav-orb__badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: var(--alert);
  color: var(--alert-ink);
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
  letter-spacing: -0.01em;
  box-shadow: 0 0 0 2px var(--surface); /* ring against the page */
}

/* Hover label to the right (mirrors the dock labels) */
.nav-orb__label {
  position: absolute;
  top: 50%;
  left: calc(100% + 8px);
  transform: translate(-4px, -50%);
  padding: 4px 9px;
  white-space: nowrap;
  background: var(--ink-950);
  color: #ffffff;
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.005em;
  border-radius: var(--radius-badge);
  box-shadow: var(--shadow-badge);
  opacity: 0;
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.nav-orb-wrap:hover .nav-orb__label,
.nav-orb:focus-visible ~ .nav-orb__label {
  opacity: 1;
  transform: translate(0, -50%);
}

@media (max-width: 480px) {
  .nav-orb-wrap {
    left: 16px;
    bottom: 16px;
  }
  .nav-orb {
    width: 44px;
    height: 44px;
  }
  /* The orb is fixed at 44x44 in the bottom-left gutter, so on a phone it
     lands ON the bottom-left corner of whichever card happens to scroll under
     it — and because it owns pointer events, that corner taps the nav menu
     instead of the card. A soft page-tinted halo separates it visually, and
     the grids reserve its footprint so the LAST card never ends beneath it. */
  .nav-orb-wrap::before {
    content: "";
    position: absolute;
    inset: -14px -18px -14px -14px;
    z-index: -1;
    pointer-events: none;
    border-radius: 50%;
    background: radial-gradient(
      circle at 34% 62%,
      var(--page-bg) 0%,
      var(--page-bg) 46%,
      rgba(238, 241, 244, 0.82) 66%,
      rgba(238, 241, 244, 0) 100%
    );
  }
}
.nav-orb.is-open {
  background: #060b14;
}

/* ---- Nav menu — pops UP from the orb (This Week / Loops / Content Library) ---- */
.nav-menu {
  position: absolute;
  bottom: calc(100% + 12px);
  left: 0;
  z-index: 90;
  width: 292px;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 20px;
  overflow: hidden; /* clip the dark Organization zone to the corners */
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.2);
  transform-origin: bottom left;
}
/* Organization = a distinct DARK section at the bottom (org-level nav reads apart
   from the platform sections above). Reaches the menu edges + rounds with it. */
.nav-menu__org {
  margin: 8px -8px -8px;
  padding: 6px 8px 10px;
  background: var(--ink-950);
}
.nav-menu__org .nav-menu__eyebrow {
  color: rgba(255, 255, 255, 0.42);
}
.nav-menu__org .nav-menu__item {
  color: #ffffff;
}
.nav-menu__org .nav-menu__item:hover {
  background: rgba(255, 255, 255, 0.09);
}
.nav-menu__org .nav-menu__item:focus-visible {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.28);
}
.nav-menu__org .nav-menu__name {
  color: #ffffff;
}
.nav-menu__org .nav-menu__desc {
  color: rgba(255, 255, 255, 0.55);
}
.nav-menu__org .nav-menu__ico {
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}
.nav-menu__org .nav-menu__chev {
  color: rgba(255, 255, 255, 0.42);
}
/* Quiet inventory chip (how many locations, how many awaiting). The base is
   the LIGHT-zone treatment — it also renders in the white part of the menu, so
   the original white-on-translucent-white version was invisible there. */
.nav-menu__tag {
  flex: none;
  padding: 2px 8px;
  border-radius: 9999px;
  background: var(--ink-100);
  color: var(--ink-700);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 600;
  line-height: 1.45;
}
/* dark Organization zone → soft chip on near-black */
.nav-menu__org .nav-menu__tag {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
}
/* sub-account context header (which sub-account you're inside) — label, not a button */
.nav-menu__subacct {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px 10px;
}
.nav-menu__subacct .nav-menu__name {
  color: #ffffff;
}
.nav-menu__subacct .nav-menu__desc {
  color: rgba(255, 255, 255, 0.55);
}
.nav-menu__subacct .nav-menu__ico {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.14);
  color: #ffffff;
}
/* nested sub-account sections — inset + smaller tile so they read as children */
.nav-menu__item--sub {
  padding-left: 14px;
}
.nav-menu__item--sub .nav-menu__ico {
  width: 28px;
  height: 28px;
  border-radius: 8px;
}
.nav-menu__item--sub .nav-menu__name {
  font-size: 13.5px;
}
/* "All sub accounts" back link */
.nav-menu__back {
  display: block;
  width: 100%;
  margin-top: 2px;
  padding: 8px 12px 4px 14px;
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.5);
  transition: color var(--dur-fast) var(--ease-smooth);
}
.nav-menu__back:hover,
.nav-menu__back:focus-visible {
  outline: none;
  color: #ffffff;
}
.nav-menu-active {
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.nav-menu__eyebrow {
  margin: 10px 10px 4px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.nav-menu__eyebrow:first-child {
  margin-top: 4px;
}
.nav-menu__item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 9px 10px;
  border: 0;
  background: transparent;
  border-radius: 14px;
  text-align: left;
  cursor: pointer;
  color: var(--ink-800);
  transition: background var(--dur-fast) var(--ease-smooth);
}
.nav-menu__item:hover {
  background: var(--ink-50);
}
.nav-menu__item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--focus-ink);
}
.nav-menu__ico {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: var(--ink-950);
  color: #ffffff;
}
/* one grouped section of the menu (eyebrow + its items) */
.nav-menu__zone + .nav-menu__zone {
  margin-top: 2px;
}
/* the item's own text column — name over descriptor, each on one line */
.nav-menu__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.nav-menu__name {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
  white-space: nowrap;
}
.nav-menu__desc {
  font-size: 12px;
  /* --ink-500 is 4.76:1 on --surface, which is what the menu card is */
  color: var(--ink-500);
  /* free to wrap to a second line, like the reference — the NAME is the line
     that must stay intact */
  line-height: 1.35;
}
.nav-menu__chev {
  flex: none;
  color: var(--ink-300);
  display: grid;
  place-items: center;
}
.nav-menu__count {
  flex: none;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background: var(--alert);
  color: var(--alert-ink);
  font-size: 11px;
  font-weight: 650;
  line-height: 1;
}

/* ============================================================
   THIS WEEK — weekly briefings rendered as node cards (same grid, size and
   48px corners as every drilled section). A prominent centered play button
   sits above the text footer; play in place OR click the card to dive in.
   ============================================================ */
.card--pulse .pulse-card__field {
  position: relative;
  align-items: center;
  justify-content: center;
}
.pulse-card__field .node-card__top {
  position: absolute;
  top: 22px;
  left: 26px;
  right: 26px;
}
.pulse-card__flags {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.pulse-card__new {
  padding: 2px 8px;
  border-radius: 9999px;
  background: var(--alert);
  color: var(--alert-ink);
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.05em;
}
/* the centered play cluster sits ABOVE the whole-card stretch (z-index 4) so it
   plays in place, while clicking anywhere else on the card drills in */
.pulse-card__playwrap {
  position: relative;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.pulse-card__play {
  width: 78px;
  height: 78px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  cursor: pointer;
  box-shadow:
    0 2px 8px rgba(14, 23, 38, 0.2),
    0 14px 32px rgba(14, 23, 38, 0.24);
  transition:
    transform var(--dur-rise) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-rise) var(--ease-out-soft);
}
.pulse-card__play:hover {
  background: #060b14;
  box-shadow:
    0 3px 10px rgba(14, 23, 38, 0.24),
    0 18px 40px rgba(14, 23, 38, 0.28);
}
.pulse-card__play:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.pulse-card__play:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px #ffffff,
    0 0 0 6px var(--ink-950);
}
.pulse-card__play-ico {
  margin-left: 3px;
} /* optical-center the triangle */
@media (hover: hover) {
  .card--pulse:hover .pulse-card__play {
    transform: translateY(-4px) scale(1.05);
  }
}
.pulse-card__dur {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-500);
}
.pulse-card__dur .wt-levels {
  color: var(--ink-700);
}
.card--pulse .card__footer--node .card__subtitle {
  -webkit-line-clamp: 3;
}
.card--pulse.is-playing .node-card__field {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent) 15%, #ffffff) 0%,
    color-mix(in srgb, var(--accent) 5%, #ffffff) 46%,
    #ffffff 76%
  );
}

/* ---- Briefing detail — Email-Sequences theme + an audio header ---- */
.brief {
  display: block;
}
.brief__player {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 20px 24px;
  margin-bottom: 26px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  box-shadow: var(--shadow-search);
}
.brief__play {
  flex: none;
  width: 60px;
  height: 60px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  cursor: pointer;
  box-shadow:
    0 2px 8px rgba(14, 23, 38, 0.2),
    0 12px 28px rgba(14, 23, 38, 0.22);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.brief__play:hover {
  background: #060b14;
  transform: scale(1.05);
}
.brief__play:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.brief__play:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px #ffffff,
    0 0 0 6px var(--ink-950);
}
.brief__playmeta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.brief__title {
  margin: 2px 0;
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.brief__dur {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-500);
}
.brief__dur .wt-levels {
  color: var(--ink-700);
}

/* ============================================================
   BRIEFING DETAIL — full 3-column signal view (change-brief-10).
   Header band (player + synthesis) over: nav list · main signal
   card · What-Changed card. Monochrome LEVR chrome; --alert
   reserved for NEW / threatens-wedge emphasis (restrained).
   ============================================================ */

/* ---- Synthesis band (Tension / Word to own / Narrative + headline) ---- */
.synth {
  margin-bottom: 26px;
  padding: 26px 28px;
  background: var(--ink-50);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
}
/* when it sits at the bottom (below the 3-column view) it leads with top space */
.synth--foot {
  margin-top: 28px;
  margin-bottom: 0;
}
.synth__cols {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1.3fr;
  gap: 28px;
}
@media (max-width: 760px) {
  .synth__cols {
    grid-template-columns: 1fr;
    gap: 18px;
  }
}
.synth__label {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.synth__text {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-800);
}
.synth__text--own {
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
}
.synth__text--narr {
  font-style: italic;
  color: var(--ink-700);
}
.synth__headline {
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--ink-200);
}
.synth__lead {
  margin: 8px 0 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink-900);
  max-width: 88ch;
}
.synth__foot {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--ink-200);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}
.synth__trends {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-700);
}
.synth__formula {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-500);
}

/* ---- 3-column grid: nav · main · What-Changed ---- */
.brief3 {
  display: grid;
  grid-template-columns: minmax(240px, 300px) 1fr minmax(260px, 320px);
  grid-template-areas: "nav main changed";
  gap: 28px;
  align-items: start;
}
.brief3__nav {
  grid-area: nav;
}
.brief3 .signal {
  grid-area: main;
}
.brief3 .changed {
  grid-area: changed;
}
@media (min-width: 1101px) {
  .brief3 .changed {
    position: sticky;
    top: 24px;
  }
}
/* ≤1100 → nav + main; What-Changed drops full-width below */
@media (max-width: 1100px) {
  .brief3 {
    grid-template-columns: minmax(220px, 280px) 1fr;
    grid-template-areas: "nav main" "changed changed";
    gap: 24px;
  }
}
/* ≤760 → single column, order main → nav → changed */
@media (max-width: 760px) {
  .brief3 {
    grid-template-columns: 1fr;
    grid-template-areas: "main" "nav" "changed";
    gap: 22px;
  }
}

/* ---- Middle: main signal card ---- */
.signal {
  padding: 28px 30px 30px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  box-shadow: var(--shadow-card-rest);
  min-width: 0;
}
.signal__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
}
.signal__tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.signal__rank {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-500);
}
.chip {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 9999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border: 1px solid var(--ink-200);
  background: var(--ink-50);
  color: var(--ink-700);
  white-space: nowrap;
}
.chip--cat {
  background: var(--ink-900);
  border-color: var(--ink-900);
  color: #ffffff;
}
.chip--reinforces {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-700);
}
.chip--threatens {
  background: color-mix(in srgb, var(--alert) 8%, #ffffff);
  border-color: color-mix(in srgb, var(--alert) 40%, #ffffff);
  color: var(--alert);
}
.chip--new {
  background: var(--alert);
  border-color: var(--alert);
  color: var(--alert-ink);
}
.chip--delta {
  font-family: var(--font-mono);
  background: var(--ink-100);
  border-color: var(--ink-200);
  color: var(--ink-600);
}
.signal__score {
  flex: none;
  text-align: right;
}
.signal__composite {
  display: block;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 46px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.signal__composite-lbl {
  display: block;
  margin-top: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.signal__title {
  margin: 18px 0 20px;
  font-size: 23px;
  line-height: 1.2;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}

/* score meters — monochrome ink bar on ink-100 track */
.meters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 24px;
}
.meter {
  display: flex;
  align-items: center;
  gap: 14px;
}
.meter__label {
  flex: none;
  width: 108px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.meter__track {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 9999px;
  background: var(--ink-100);
  overflow: hidden;
}
.meter__fill {
  display: block;
  height: 100%;
  border-radius: 9999px;
  background: var(--ink-900);
  transition: width var(--dur-base) var(--ease-out-soft);
}
.meter__val {
  flex: none;
  width: 30px;
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-700);
}

.signal__p {
  margin: 0 0 14px;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-700);
  max-width: 70ch;
}

/* So What box */
.sowhat {
  margin: 20px 0;
  padding: 18px 20px;
  background: var(--ink-50);
  border: 1px solid var(--ink-200);
  border-radius: 16px;
}
.sowhat__label {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.sowhat__text {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-800);
}

/* pull-quote */
.signal__quote {
  margin: 20px 0;
  padding: 4px 0 4px 18px;
  border-left: 2px solid var(--ink-300);
  font-size: 15.5px;
  line-height: 1.5;
  font-style: italic;
  color: var(--ink-600);
}

/* tags — personas vs type chips (type in mono, distinct) */
.signal__taglist {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 22px 0;
}
.tag {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px;
  border-radius: 9999px;
  font-size: 12px;
  line-height: 1.3;
}
.tag--persona {
  background: var(--ink-100);
  color: var(--ink-700);
  font-weight: 550;
}
.tag--type {
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 500;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  color: var(--ink-500);
}

/* evidence + linked sources */
.evidence {
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--ink-100);
}
.evidence__head {
  margin: 0 0 14px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.evidence__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.evidence__row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--ink-100);
}
.evidence__row:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.evidence__text {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-700);
}
.evidence__src {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-500);
  text-decoration: none;
  transition: color var(--dur-base) var(--ease-smooth);
}
.evidence__src:hover {
  color: var(--ink-900);
  text-decoration: underline;
}
.evidence__src:focus-visible {
  outline: none;
  color: var(--ink-900);
  box-shadow: 0 0 0 2px var(--focus-ink);
  border-radius: 6px;
}
.evidence__src svg {
  flex: none;
}

/* ---- Right: What Changed · Jump In card ---- */
.changed {
  padding: 22px 22px 24px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  box-shadow: var(--shadow-card-rest);
}
.changed__head {
  margin: 0 0 16px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.changed__jumps {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.jump {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 14px;
  text-align: left;
  border: 1px solid var(--ink-200);
  border-radius: 14px;
  background: var(--ink-50);
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.jump:hover {
  background: var(--surface);
  border-color: var(--ink-400);
  box-shadow: var(--shadow-search);
}
.jump:active {
  transform: scale(0.98);
}
.jump:focus-visible {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 2px var(--focus-ink);
}
.jump__n {
  flex: none;
  min-width: 22px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-900);
}
.jump__label {
  flex: 1 1 auto;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-700);
}
.jump__chev {
  flex: none;
  color: var(--ink-400);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    color var(--dur-base) var(--ease-smooth);
}
.jump:hover .jump__chev {
  color: var(--ink-700);
  transform: translateX(2px);
}
.changed__bullets {
  list-style: none;
  margin: 18px 0 0;
  padding: 16px 0 0;
  border-top: 1px solid var(--ink-100);
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.changed__bullet {
  position: relative;
  padding-left: 16px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-600);
}
.changed__bullet::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-400);
}

/* ---- Graceful fallback (pulses without a full detail) ---- */
.brief-empty {
  max-width: 620px;
  margin: 8px auto;
  padding: 44px 28px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  box-shadow: var(--shadow-card-rest);
}
.brief-empty__mark {
  width: 60px;
  height: 60px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  background: var(--ink-50);
  color: var(--ink-500);
}
.brief-empty__title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.brief-empty__sub {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-600);
  max-width: 60ch;
}
.brief-empty__note {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  max-width: 62ch;
  margin-inline: auto;
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-700);
}
.brief-empty__note li {
  position: relative;
  padding-left: 16px;
}
.brief-empty__note li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-400);
}
.brief-empty__note span {
  font-family: var(--font-mono);
  color: var(--ink-500);
}

/* ---- Stub view — Loops / Content Library placeholder (next build) ---- */
.stub-view {
  max-width: 520px;
  margin: 32px auto;
  padding: 44px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
}
.stub-view__mark {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 20px;
  background: var(--ink-50);
  color: var(--ink-700);
}
.stub-view__title {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.stub-view__sub {
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-500);
  max-width: 42ch;
}

@media (max-width: 560px) {
  .nav-menu {
    width: 264px;
  }
  .brief__player {
    padding: 16px 18px;
    gap: 14px;
  }
  .brief__play {
    width: 52px;
    height: 52px;
  }
  .brief__title {
    font-size: 21px;
  }
}

/* ============================================================
   RECURSIVE CARD-DRILLING NAV (card-nav-build-brief)
   Cross-fade stage, node cards, expanding B&W breadcrumb,
   Email Sequences pill-tag view. LEVR chrome stays B&W; only
   client artifacts (the accent rule) carry SGA brand color.
   ============================================================ */

/* ---- Stage cross-fade (~260ms: 130 out + 130 in) ---- */
.stage {
  transition: opacity 130ms var(--ease-smooth);
}
.stage.is-out {
  opacity: 0;
}

/* Root note — flags that drill applies to all sections at scale */
.root-note {
  max-width: 640px;
  margin: 4px auto 40px;
  padding: 0 24px;
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-400);
}
.root-note strong {
  color: var(--ink-600);
  font-weight: 600;
}

/* ============================================================
   HOME CARD FOOTER META ROW — mono count/meta + Explore link
   (flat-home: every card shows its group-eyebrow / title /
   descriptor / mono count). Count left, Explore right.
   ============================================================ */
.card__footrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-top: 16px;
}
.card__footrow .card__link {
  margin-top: 0;
  flex: none;
}
.card__count-meta {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-600);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ============================================================
   LEAF CONTENT VIEW — a simple drilled content surface: the
   section's real capture, framed, with title / descriptor /
   count meta. Breadcrumb above reads Home › <group> › <label>.
   ============================================================ */
.leaf-view {
  /* was centred on the viewport at a fixed 1040px, which broke the app's one
     left edge by 294px on every leaf */
  max-width: min(100%, 1240px);
  margin: 0;
}
.leaf-view__meta {
  margin-bottom: 26px;
}
.leaf-view__title {
  margin: 8px 0 0;
  font-size: 30px;
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.leaf-view__sub {
  margin: 10px 0 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-600);
  max-width: 62ch;
}
.leaf-view__count {
  display: inline-block;
  margin-top: 16px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-600);
  padding: 5px 12px;
  border-radius: 9999px;
  background: var(--ink-100);
}
.leaf-view__frame {
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  overflow: hidden;
  overflow-y: auto;
  max-height: 78vh;
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.leaf-view__frame img {
  width: 100%;
  height: auto;
  display: block;
  /* was computing to `fill`: safe only while every source happens to match the
     frame's aspect ratio. `cover` crops instead of stretching. */
  object-fit: cover;
}

/* ============================================================
   LEAF DETAIL — the leaf's real payload.

   A leaf used to bottom out at a stock photograph; it now renders the
   section's own data from a generic `detail` record on the node
   (build_leaf_details.py). The shell knows the SCHEMA, never the facts:

     lede     one framing sentence
     stats[]  {k,v} -> a row of mono figures
     blocks[] {title, kind:"pairs"|"list"|"quotes", items}
     excerpt  {label,text,source} -> the pull quote in the rail
     note     provenance, under the art

   Surfaces reuse the card language: --radius-card (48px) on the big
   panels, --radius-image on the art, mono kickers, the ink scale.
   ============================================================ */
.leaf-view--rich {
  max-width: min(100%, 1480px);
}
.leaf-detail {
  margin-top: 4px;
}
.leaf-detail__lede {
  margin: 0 0 26px;
  max-width: 62ch;
  font-size: 17px;
  line-height: 1.55;
  color: var(--ink-800);
  text-wrap: pretty;
}

/* ---- the figure row ---- */
.leaf-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px;
  margin: 0 0 32px;
  padding: 0;
  list-style: none;
  background: var(--ink-200);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-search);
  overflow: hidden;
}
.leaf-stat {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 20px 22px;
  background: var(--surface);
}
.leaf-stat__v {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 24px;
  line-height: 1.1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-950);
  overflow-wrap: anywhere;
}
/* MINIMISED figure row — a leaf that drills into block cards keeps its score,
   it just stops shouting it. The row is the same data in the same order; it
   collapses each tile from a stacked block to one baseline so the cards below
   own the surface. Minimise, never delete: the number at the top is the thing
   the reader checks first. */
.leaf-stats--min {
  grid-template-columns: repeat(auto-fit, minmax(128px, 1fr));
  margin-bottom: 26px;
}
.leaf-stats--min .leaf-stat {
  flex-direction: row;
  align-items: baseline;
  gap: 8px;
  padding: 9px 14px;
}
.leaf-stats--min .leaf-stat__v {
  flex: none;
  font-size: 15px;
}
.leaf-stats--min .leaf-stat__k {
  margin-top: 0;
  font-size: 9.5px;
  letter-spacing: 0.06em;
}
.leaf-stat__k {
  /* a long figure wraps to two lines; pinning the label to the tile floor keeps
     every kicker on one baseline across the row */
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-600);
}

/* ---- main column + supporting rail ---- */
.leaf-detail__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
@media (min-width: 1080px) {
  .leaf-detail__cols {
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 36px;
  }
  /* the main column runs long; the rail travels with the reader instead of
     leaving several screens of dead white beside it */
  .leaf-detail__side {
    position: sticky;
    top: 28px;
  }
}
.leaf-detail__main {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}
.leaf-detail__side {
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-width: 0;
}

/* ---- one content block ---- */
.leaf-block {
  padding: 28px 30px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.leaf-block__title {
  margin: 0 0 18px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-600);
}

/* pairs — a definition table, key left, value right */
.leaf-pairs {
  margin: 0;
}
.leaf-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3px;
  padding: 13px 0;
  border-top: 1px solid var(--ink-100);
}
.leaf-pair:first-child {
  padding-top: 0;
  border-top: 0;
}
.leaf-pair:last-child {
  padding-bottom: 0;
}
@media (min-width: 720px) {
  .leaf-pair {
    grid-template-columns: minmax(140px, 33%) minmax(0, 1fr);
    gap: 24px;
    align-items: baseline;
  }
}
.leaf-pair__k {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  font-weight: 600;
  color: var(--ink-900);
  text-wrap: pretty;
}
.leaf-pair__v {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-700);
  text-wrap: pretty;
}

/* list — a numbered run of real lines */
.leaf-list {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: leafline;
}
.leaf-list__item {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 12px;
  padding: 11px 0;
  border-top: 1px solid var(--ink-100);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-800);
  text-wrap: pretty;
}
.leaf-list__item:first-child {
  padding-top: 0;
  border-top: 0;
}
.leaf-list__item::before {
  counter-increment: leafline;
  content: counter(leafline, decimal-leading-zero);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-500);
  padding-top: 3px;
}

/* quotes — verbatim source material */
.leaf-quotes {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.leaf-quote {
  padding-left: 16px;
  border-left: 2px solid var(--ink-300);
}
.leaf-quote__text {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-900);
  text-wrap: pretty;
}
.leaf-quote__src {
  margin: 7px 0 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-600);
}

/* ---- the rail: pull quote, art, provenance ---- */
.leaf-excerpt {
  margin: 0;
  padding: 26px 28px;
  border-radius: var(--radius-card);
  background: var(--ink-950);
  color: #ffffff;
}
.leaf-excerpt__kicker {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  /* on --ink-950 this measures 8.6:1 */
  color: rgba(255, 255, 255, 0.72);
}
.leaf-excerpt__text {
  margin: 12px 0 0;
  font-size: 16px;
  line-height: 1.5;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #ffffff;
  text-wrap: pretty;
}
.leaf-excerpt__src {
  margin: 14px 0 0;
  padding-top: 13px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  font-size: 12.5px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.76);
}
/* The photograph, demoted: it supports the data, it is no longer the payload.
   Fixed frame + `cover`, no scroll — so it never becomes a keyboard trap and
   never claims the height the content needs. */
.leaf-view__frame--aside {
  margin: 0;
  overflow: hidden;
  max-height: none;
  border-radius: var(--radius-image);
  box-shadow: none;
}
.leaf-view__frame--aside img {
  aspect-ratio: 4 / 3;
  height: 100%;
  object-fit: cover;
}
.leaf-detail__note {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.6;
  /* --ink-600 on --surface = 7.0:1 */
  color: var(--ink-600);
  text-wrap: pretty;
}

/* ---- the leaf, split in three -------------------------------------------
   A leaf whose payload has been derived into block cards renders as
   head (framing + the minimised score) → the shared card grid → context.
   A leaf with nothing to drill renders head → body, which is the unchanged
   legacy column. Both halves keep .leaf-view so one max-width governs the
   surface. */
.leaf-view--head {
  max-width: min(100%, 1480px);
}
.leaf-view--body .leaf-detail {
  margin-top: 0;
}
/* Supporting strip under the cards: the pull quote, the demoted photograph and
   the provenance note, laid out as one quiet row instead of a sticky rail. */
.leaf-context {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 24px;
  max-width: min(100%, 1480px);
  margin-top: 44px;
  padding-top: 30px;
  border-top: 1px solid var(--ink-200);
}
.leaf-context > .leaf-excerpt {
  flex: 1 1 360px;
}
.leaf-context > .leaf-view__frame--aside {
  flex: 0 1 300px;
}
.leaf-context > .leaf-detail__note {
  flex: 1 1 100%;
}
@media (max-width: 700px) {
  .leaf-block {
    padding: 24px 22px;
    border-radius: 30px;
  }
  .leaf-excerpt {
    padding: 22px 22px;
    border-radius: 30px;
  }
  .leaf-stat {
    padding: 16px 18px;
  }
  .leaf-stat__v {
    font-size: 21px;
  }
}

/* ---- Drilled container (matches grid container padding for alignment) ----
   Reserves the same left rail lane (change-brief-8 §2) so the drilled grid +
   breadcrumb clear the Walk-and-Talk rail; the drilled grid inherits the
   auto-fit + justify-content:center centering from .card-grid. */
.drill {
  max-width: 2100px;
  margin-inline: auto;
  padding: 24px;
  padding-left: max(24px, var(--rail-lane));
}
/* Drilled CONTENT aligns with the breadcrumb: both indent to --dock-lane (≥481)
   so search bars / pill tabs / left-navs line up with the crumb's left edge. */
@media (min-width: 481px) {
  .drill {
    padding-left: var(--dock-lane);
  }
}
@media (min-width: 1024px) {
  .drill {
    padding: 40px;
    padding-left: max(40px, var(--dock-lane));
  }
}
@media (min-width: 1600px) {
  .drill {
    padding: 48px;
    padding-left: max(48px, var(--dock-lane));
  }
}
@media (max-width: 360px) {
  .drill {
    padding: 16px;
  }
}
/* the drilled grid inherits the container's padding, so zero its own */
.card-grid--drill {
  padding: 0;
  max-width: none;
  margin: 0;
}

/* ---- Compact drilled header — breadcrumb IS the title (change-brief-7 §1/§2) ---- */
/* Extra bottom margin gives the content grid/pills breathing room now that the
   redundant heading + descriptor block is gone. */
.drill-head {
  position: relative;
  margin-bottom: 40px;
}

/* ============================================================
   EXPANDING BREADCRUMB — top-left; horizontal at rest, hover
   expands to a vertical clickable list. Adapted to B&W chrome.
   ============================================================ */
.crumb {
  position: relative;
  display: inline-block;
  z-index: 20;
  /* The lane is a flex row; without these the trail is sized by its widest
     nowrap label at EVERY viewport, not just ≤480 — 862px inside a 768px
     window, measured. Capping here plus min-width:0 on the segs is what lets
     the ellipsis in .crumb__link actually engage (1.4.10 Reflow). */
  max-width: 100%;
  min-width: 0;
}

/* Coexist with the pinned dock (change-brief-9): when the dock is present the
   breadcrumb starts to the right of it on the same top line. The drill already
   indents by --rail-lane; add only the extra needed to clear the dock cluster. */
/* Breadcrumb now inherits the drill's --dock-lane indent — aligned with the content. */
.drill.has-dock .drill-head {
  padding-left: 0;
}

/* At mobile the dock cluster sits at the very top-left; instead of reserving a
   lane beside it (which forces wide crumbs like a full date label to overflow),
   drop the crumb below the dock and let it wrap. Prevents horizontal overflow
   at ≤480 for every drilled view. */
@media (max-width: 480px) {
  .drill.has-dock .drill-head {
    padding-left: 0;
    padding-top: 56px;
  }
  .crumb,
  .crumb__bar {
    max-width: 100%;
  }
  .crumb__bar {
    flex-wrap: wrap;
  }
}

/* REST — roomier horizontal pill; the breadcrumb is now the page title, so it
   gets real presence, not a tight chip (change-brief-7 §2). B&W, soft-cornered. */
/* An <ol>, so the trail is exposed as an ordered list (1.3.1) — the list
   reset keeps the chip identical to the <div> it replaced. */
.crumb__bar {
  display: inline-flex;
  align-items: center;
  /* Wrapping is a no-op while the trail fits, and the only thing standing
     between a deep path and a sideways-scrolling body once it does not. */
  flex-wrap: wrap;
  max-width: 100%;
  gap: 6px;
  min-height: 56px;
  margin: 0;
  list-style: none;
  padding: 10px 20px 10px 10px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  box-shadow: var(--shadow-search);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}
.crumb.is-open .crumb__bar {
  border-color: var(--ink-300);
  box-shadow: var(--shadow-card-hover);
}
.crumb__home {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 11px;
  background: var(--ink-950);
  color: #ffffff;
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.crumb__home:hover {
  background: #060b14;
}
.crumb__home:active {
  transform: scale(0.94);
}
.crumb__home:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
.crumb__seg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  /* A flex item will not shrink below its content's intrinsic width unless it
     is told it may. Without this the nowrap label below pushes the trail past
     the viewport and the BODY scrolls sideways (1.4.10 Reflow) — measured at
     415px wide in a 390px window. */
  min-width: 0;
}
.crumb__chev {
  color: var(--ink-300);
  flex: none;
}
.crumb__ellipsis {
  padding: 0 4px;
  color: var(--ink-600); /* --ink-400 was 2.56:1 on the white crumb chip */
  font-weight: 600;
  letter-spacing: 0.04em;
}
.crumb__link {
  padding: 6px 9px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font-family: var(--font-ui);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink-500);
  white-space: nowrap;
  /* Truncate VISUALLY, never programmatically: text-overflow clips the glyphs
     but leaves the DOM text intact, so the button's accessible name is still
     the whole label for a screen reader, and the sibling menu below lists every
     label in full. This is what keeps a long section title from forcing a
     horizontal body scroll (1.4.10). */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  transition:
    background var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth);
}
.crumb__link:hover {
  background: var(--ink-50);
  color: var(--ink-800);
}
.crumb__link.is-current {
  color: var(--ink-900);
  font-weight: 600;
  cursor: default;
}
.crumb__link.is-current:hover {
  background: transparent;
}
.crumb__link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--ink-900);
}

/* EXPANDED — vertical menu of the full path */
.crumb__menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 40;
  min-width: 268px;
  max-width: min(360px, calc(100vw - 32px));
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 20px;
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.2);
}
.crumb-menu-active {
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
.crumb__row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  padding-left: calc(12px + var(--depth, 0) * 16px); /* indent by depth */
  border: 0;
  border-radius: 12px;
  background: transparent;
  text-align: left;
  color: var(--ink-600);
  transition:
    background var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth);
}
.crumb__row:hover {
  background: var(--ink-50);
  color: var(--ink-900);
}
.crumb__row:focus-visible {
  outline: none;
  background: var(--ink-50);
  box-shadow: inset 0 0 0 2px var(--ink-900);
}
.crumb__rowico {
  display: grid;
  place-items: center;
  color: var(--ink-400);
  flex: none;
}
.crumb__rowlabel {
  flex: 1 1 auto;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.3;
}
.crumb__rowcount {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  /* --ink-400 measured 2.56:1 on the white menu sheet at 11px — this is the
     "3 sections" count, real information, not decoration (1.4.3). */
  color: var(--ink-600);
  font-variant-numeric: tabular-nums;
}
/* current level = emphasized (filled black pill) */
.crumb__row.is-current {
  background: var(--ink-950);
  color: #ffffff;
  cursor: default;
}
.crumb__row.is-current .crumb__rowico,
.crumb__row.is-current .crumb__rowcount {
  color: rgba(255, 255, 255, 0.7);
}
.crumb__row.is-current:hover {
  background: var(--ink-950);
}

/* ============================================================
   NODE CARD — treatment 4: clean drillable content card, no
   screenshot. Same shell (48px corners, hairline, hover shadow),
   a client-brand accent field + glyph, mono count, standard footer.
   ============================================================ */
/* Built on the proven metric-card pattern: in-flow flex content (no absolutely
   positioned descendants), which avoids a Chromium compositing edge case that
   drops absolute children inside a will-change + aspect-ratio filling layer. */
.card--node {
  --accent: #2d6fb7;
  aspect-ratio: 4 / 5;
}
.card--node .card__inner {
  display: flex;
  flex-direction: column;
  position: absolute;
  inset: 0;
}
/* accent-tinted field (client brand) — analog of the metric hero */
.node-card__field {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding: 26px;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--accent) 11%, #ffffff) 0%,
    color-mix(in srgb, var(--accent) 4%, #ffffff) 44%,
    #ffffff 74%
  );
}
/* count/flags sit top-right; the old client-brand rule was removed (it read as
   distracting, change-brief-9 rev) so the row just right-aligns its content */
.node-card__top {
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  gap: 12px;
}
.node-card__rule {
  display: none;
}
.node-card__count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-500);
  flex: none;
}
/* glyph sits at the bottom of the field; rises + zooms on hover */
.node-card__glyph {
  margin-top: auto;
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  border-radius: 18px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  color: var(--ink-800);
  box-shadow: var(--shadow-pill);
  transform-origin: left bottom;
  transition:
    transform var(--dur-rise) var(--ease-out-soft),
    box-shadow var(--dur-rise) var(--ease-out-soft);
}
@media (hover: hover) {
  .card--node:hover .node-card__glyph {
    transform: translateY(-8px) scale(1.06);
    box-shadow: var(--shadow-card-hover);
  }
}
.node-card__tag {
  margin-top: 12px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-400);
}
.node-card__tag svg {
  color: var(--ink-400);
}

.card__footer--node {
  position: relative;
  z-index: 3;
  padding: 22px 26px 28px;
  border-top: 1px solid var(--ink-100);
  background: var(--surface);
}
.card__footer--node .card__subtitle {
  -webkit-line-clamp: 2;
}
.card__footer--node .card__link {
  margin-top: 16px;
}
/* leaf (terminal display) cards: calmer, no pointer affordance */
.card--node.is-leaf {
  cursor: default;
}
.card--node.is-leaf .node-card__glyph {
  box-shadow: var(--shadow-badge);
}

/* ============================================================
   DERIVED DETAIL CARDS — levels 2 and 3 of a section drill.

   `.card--block` is one of a leaf's detail blocks; `.card--item` is one
   fact inside a block. Both are the SAME node-treatment card the grid
   already owns — these modifiers only change the proportions, because a
   block card carries a title and a preview line while an item card carries
   a short label and a clipped value, and neither needs the 4:5 portrait a
   section capture does. No new component, no second grid.
   ============================================================ */
/* A block keeps the designed field — it is a container, and containers read as
   gallery cards here — just not the 4:5 portrait a section capture needs, or
   the field becomes 200px of empty gradient. */
.card--block {
  aspect-ratio: 4 / 3;
}
/* An item card is the only card in the system whose height is not knowable in
   advance: its title is a raw label from the pack (one word or three lines) and
   its face is a clipped value. Pinned to an aspect ratio it clipped its own
   "View →" footer, so it sizes to content instead — the grid row still
   equalises the heights, and dropping the absolute .card__inner is what makes
   `overflow: hidden` on .card stop cutting the footer off. */
.card--item {
  aspect-ratio: auto;
  min-height: 240px;
}
.card--item .card__inner {
  position: relative;
  inset: auto;
  height: 100%;
}
.card--item .node-card__field {
  flex: 0 0 auto;
  padding: 22px 24px 6px;
}
/* the item glyph is the same mark on every sibling, so it stops being
   information — shrink it back to a quiet corner mark */
.card--item .node-card__glyph {
  width: 40px;
  height: 40px;
  border-radius: 13px;
}
.card--item .node-card__glyph svg {
  width: 20px;
  height: 20px;
}
.card--item .card__footer--node {
  flex: 1 1 auto;
  padding-top: 18px;
}
.card--item .card__title--display {
  font-size: 18px;
  -webkit-line-clamp: 3;
}
.card--item .card__footer--node .card__subtitle {
  -webkit-line-clamp: 3;
}
/* On a section card the field carries artwork and the footer carries the
   count, so they never collide. A derived card has no artwork, so the shared
   footer printed the very same string ("7 entries", "3 / 7") a second time
   three lines under the badge. Keep the badge — on an item it reads as a slide
   number, which is exactly what it is — and drop the echo. */
.card--block .card__count-meta,
.card--item .card__count-meta {
  display: none;
}
.card--block .card__footrow,
.card--item .card__footrow {
  justify-content: flex-end;
}
/* Blocks and items are denser lists than the section gallery — let more of
   them into one row rather than blowing three findings across a 2100px page.
   These keep the 1fr max ON PURPOSE (density beats the gallery's fixed 380
   track here), but that means an UNDERFULL row — 3 findings where 4 tracks
   fit — flexes its tracks wider than .card's 420px cap. The cards then pin to
   the left of their oversized tracks and the row stops short of the right
   edge, reading left-heavy. justify-items:center re-centres each card in its
   track, so an underfull row is symmetric. It is a no-op on a full row, where
   the track is narrower than the cap and the card already fills it. */
.card-grid--blocks {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
  justify-items: center;
}
.card-grid--items {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 24px;
  justify-items: center;
}
@media (max-width: 480px) {
  .card-grid--blocks,
  .card-grid--items {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ============================================================
   TOGGLE SWITCH — reusable monochrome primitive (change-brief-11).
   OFF = ink-200 track / white knob · ON = ink-950 track / white knob.
   role="switch"; keyboard-operable (native <button>: Enter/Space fire
   click); visible focus ring; instant under prefers-reduced-motion
   (covered by the global reduce block). Clicking it must not navigate —
   the template stops propagation, like the This Week play button.
   ============================================================ */
.switch {
  --sw-w: 46px;
  --sw-h: 26px;
  --sw-pad: 3px;
  position: relative;
  flex: none;
  width: var(--sw-w);
  height: var(--sw-h);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 9999px;
  background: var(--ink-200);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background var(--dur-base) var(--ease-out-soft);
}
.switch.is-on {
  background: var(--ink-950);
}
.switch:hover {
  background: var(--ink-300);
}
.switch.is-on:hover {
  background: #060b14;
}
.switch__knob {
  position: absolute;
  top: var(--sw-pad);
  left: var(--sw-pad);
  width: calc(var(--sw-h) - 2 * var(--sw-pad));
  height: calc(var(--sw-h) - 2 * var(--sw-pad));
  border-radius: 50%;
  background: #ffffff;
  box-shadow:
    0 1px 2px rgba(16, 42, 72, 0.28),
    0 1px 3px rgba(16, 42, 72, 0.16);
  transition: transform var(--dur-base) var(--ease-out-soft);
}
.switch.is-on .switch__knob {
  transform: translateX(calc(var(--sw-w) - var(--sw-h)));
}
.switch:active .switch__knob {
  transform: translateX(0) scale(0.92);
}
.switch.is-on:active .switch__knob {
  transform: translateX(calc(var(--sw-w) - var(--sw-h))) scale(0.92);
}
.switch:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px var(--surface),
    0 0 0 5px var(--ink-950);
}

/* ============================================================
   LOOPS VIEW — the settings / control room (change-brief-11):
   header + running count · calm explainer card · 5-tile stat row ·
   "Your Loops" grid of loop cards with a prominent centered toggle.
   Monochrome throughout; only the awaiting-count uses --alert.
   ============================================================ */
.loops-view {
  display: block;
}

/* 1) Header + live running count */
.loops-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.loops-head__title {
  margin: 0;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink-900);
}
.loops-head__count {
  margin: 0;
  font-size: 14px;
  color: var(--ink-600); /* 4.19:1 → 7.0:1 on the tinted page */
}
.loops-head__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink-900);
}

/* 2) "What is a loop?" explainer — reuses the .synth ink-50 card shell */
.loops-explainer {
  margin-bottom: 28px;
}
.loops-explainer__lead {
  margin: 0;
  max-width: 78ch;
  font-size: 17px;
  line-height: 1.55;
  font-weight: 450;
  color: var(--ink-900);
}
.loops-explainer__levels {
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--ink-200);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 28px;
}
@media (max-width: 640px) {
  .loops-explainer__levels {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}
.loops-level {
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.loops-level__tag {
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.06em;
  color: var(--ink-700);
}
.loops-level__text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-600);
}

/* 3) Stat row — 5 metric tiles; first is the primary awaiting-approval tile */
.loop-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 18px;
  margin-bottom: 44px;
}
.loop-stat--primary {
  grid-column: span 2;
}
/* the one number that IS a review count gets the reserved accent */
.loop-stat--primary .loop-stat__num {
  color: var(--alert);
}
@media (max-width: 1100px) {
  .loop-stats {
    grid-template-columns: repeat(2, 1fr);
  }
  .loop-stat--primary {
    grid-column: 1 / -1;
  }
}
@media (max-width: 560px) {
  .loop-stats {
    grid-template-columns: 1fr;
  }
}
.loop-stat {
  padding: 22px 24px;
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.loop-stat--primary {
  background: var(--ink-50);
}
.loop-stat__inner {
  display: flex;
  flex-direction: column;
  gap: 8px;
  height: 100%;
}
.loop-stat__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 34px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.loop-stat__label {
  margin: 0;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.loop-stat__label--top {
  margin-bottom: 2px;
}
.loop-stat__row {
  display: flex;
  align-items: center;
  gap: 16px;
}
.loop-stat__review {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 550;
  color: var(--ink-700);
  transition: color var(--dur-base) var(--ease-smooth);
}
.loop-stat__review:hover {
  color: var(--ink-950);
}
.loop-stat__review .arrow {
  transition: transform var(--dur-base) var(--ease-out-soft);
}
.loop-stat__review:hover .arrow {
  transform: translateX(3px);
}
.loop-stat__review:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px var(--surface),
    0 0 0 5px var(--ink-950);
  border-radius: 6px;
}
.loop-stat__sub {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--ink-600);
}

/* 4) "Your Loops" grid label */
.loops-grid-label {
  margin: 0 0 20px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-700);
}

/* ---- Loop card — same .card--node shell (48px, 4/5, hairline, hover shadow),
   but the field CENTERS the prominent toggle instead of a glyph. Order:
   Title → toggle → description → meta footer. OFF loops stay fully readable
   (never grayed/disabled) — the visible switch carries the state. ---- */
.card--loop .loop-card__field {
  padding: 30px 30px 22px;
  background: linear-gradient(180deg, var(--ink-50) 0%, #ffffff 60%);
}
.loop-card__head {
  display: flex;
  align-items: flex-start;
  gap: 11px;
}
.loop-card__glyph {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  color: var(--ink-800);
  box-shadow: var(--shadow-badge);
}
.loop-card__title {
  flex: 1 1 auto;
  margin: 0;
  font-size: 17px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink-900);
}
.loop-card__badge {
  flex: none;
  margin-top: 2px;
  padding: 3px 8px;
  border-radius: 7px;
  background: var(--ink-950);
  color: #ffffff;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.06em;
}
/* the focal control — dead-centered in the field with generous whitespace */
.loop-card__togglewrap {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 26px 0 10px;
}
.loop-card__togglewrap .switch {
  --sw-w: 52px;
  --sw-h: 30px;
  --sw-pad: 3px;
}
.loop-card__togglecap {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
  transition: color var(--dur-base) var(--ease-smooth);
}
.card--loop.is-on .loop-card__togglecap {
  color: var(--ink-800);
}

/* footer: description + meta (status · cadence · awaiting · level · affordance) */
.loop-card__footer {
  display: flex;
  flex-direction: column;
  padding: 22px 30px 30px;
}
.loop-card__desc {
  margin: 0;
  max-width: none;
  /* -webkit-line-clamp is inert without the box display + orient, so real
     235-char copy grew the card to 5 lines and dragged its row sibling. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.loop-card__statusline {
  margin-top: 16px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12.5px;
  color: var(--ink-600);
}
.loop-card__status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 550;
  color: var(--ink-800);
}
.loop-card__statusdot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-300);
  flex: none;
}
.loop-card__status[data-status="running"] .loop-card__statusdot {
  background: var(--ink-900);
}
.loop-card__status[data-status="paused"] .loop-card__statusdot {
  background: var(--ink-400);
}
.loop-card__sep {
  color: var(--ink-300);
}
.loop-card__cadence {
  color: var(--ink-600);
}
.loop-card__await {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--ink-600);
}
.loop-card__awaitnum {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--alert);
}
.loop-card__foot {
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--ink-100);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.loop-card__level {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.loop-card__leveltag {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-700);
}
.loop-card__connect {
  font-size: 12px;
  color: var(--ink-500);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.loop-card__aff {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-700);
}
.loop-card__aff .arrow {
  transition: transform var(--dur-base) var(--ease-out-soft);
}
@media (hover: hover) {
  .card--loop:hover .loop-card__aff .arrow {
    transform: translateX(3px);
  }
}

/* ============================================================
   CONTENT LIBRARY VIEW — the review surface (change-brief-12, Phase 2
   SHELL). Header + controls + email-seq pill filters + edge-to-edge
   card grid with PER-TYPE rendering (§5.2). Monochrome LEVR chrome;
   only the attention (awaiting) flag carries --alert. Display-only —
   no hover actions / no modal / no click-through this phase.
   ============================================================ */
.cl-view {
  display: block;
}

/* 1) Header — title + subtitle + running count (mirrors .loops-head) */
.cl-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.cl-head__title {
  margin: 0 0 8px;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink-900);
}
.cl-head__sub {
  margin: 0;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink-500);
}
.cl-head__count {
  margin: 6px 0 0;
  flex: none;
  font-size: 14px;
  color: var(--ink-600); /* 4.19:1 → 7.0:1 on the tinted page */
  white-space: nowrap;
}
.cl-head__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink-900);
}

/* 2) Controls bar — search · channel · sort (NO grid/list toggle) */
.cl-controls {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}
.cl-search {
  flex: 1 1 320px;
  min-width: 220px;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 48px;
  padding: 0 16px;
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-search);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}
.cl-search:hover {
  border-color: var(--ink-300);
}
.cl-search:focus-within {
  border-color: var(--ink-950);
  box-shadow:
    var(--shadow-search),
    0 0 0 3px var(--focus-ink-strong);
}
.cl-search__ico {
  flex: none;
  color: var(--ink-400);
}
.cl-search__input {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  /* The visual affordance is the 48px wrapper, but the TARGET is the input —
     it measured 928x21, under the 24x24 floor (2.5.8). Stretching it to fill
     the wrapper makes the whole chip the hit area without moving a pixel. */
  align-self: stretch;
  min-height: 24px;
  border: 0;
  background: transparent;
  font-family: var(--font-ui);
  font-size: 15px;
  color: var(--ink-800);
  caret-color: var(--blue-500);
}
.cl-search__input::placeholder {
  color: var(--ink-400);
}
.cl-search__input:focus {
  outline: none;
}
.cl-search__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.cl-selects {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}
.cl-select {
  position: relative;
  display: inline-flex;
  align-items: center;
}
.cl-select__cap {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.cl-select__field {
  -webkit-appearance: none;
  appearance: none;
  height: 48px;
  padding: 0 38px 0 16px;
  margin: 0;
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  background: var(--surface);
  box-shadow: var(--shadow-search);
  cursor: pointer;
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 550;
  color: var(--ink-800);
  transition: border-color var(--dur-base) var(--ease-smooth);
}
.cl-select__field:hover {
  border-color: var(--ink-300);
}
.cl-select__field:focus-visible {
  outline: none;
  border-color: var(--ink-700);
  box-shadow:
    var(--shadow-search),
    0 0 0 3px var(--focus-ring);
}
.cl-select__chev {
  position: absolute;
  right: 14px;
  color: var(--ink-400);
  pointer-events: none;
}

/* 3) Pill row — email-seq pills (left) + "N of M pieces" (right) */
.cl-pillrow {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 32px;
}
.cl-pilltags {
  margin-bottom: 0;
}
.cl-count {
  margin: 0;
  flex: none;
  font-size: 13px;
  color: var(--ink-500);
  white-space: nowrap;
}
.cl-count__num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--ink-800);
}

/* 4) Grid — same centered multi-column drill grid. Each item = card + source. */
.cl-grid {
  align-items: start;
}
.cl-item {
  display: flex;
  flex-direction: column;
}

/* the content card: same 48px shell, 4/5 shape, hairline + hover shadow */
.cl-card {
  position: relative;
  aspect-ratio: 4 / 5;
  cursor: pointer;
}
.cl-card__inner {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
}

/* ---- Hover actions (change-brief-13 §1) — Approve · Refresh · Preview.
   Real buttons, revealed on hover OR focus-within (keyboard-reachable),
   monochrome: dark-glass over social/sms, light chips over blog/email. ---- */
.cl-actions {
  position: absolute;
  bottom: 64px;
  right: 16px;
  z-index: 7;
  display: flex;
  gap: 8px;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition:
    opacity var(--dur-base) var(--ease-out-soft),
    transform var(--dur-base) var(--ease-out-soft);
}
@media (hover: hover) {
  .cl-card:hover .cl-actions {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
}
.cl-card:focus-within .cl-actions {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.cl-act {
  position: relative;
  width: 34px;
  height: 34px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 11px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  color: var(--ink-700);
  box-shadow: var(--shadow-badge);
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
/* 34px is the design size; the TOUCH target has to be 44 (2.5.8 AAA / native
   guidance). An invisible bleed gets there without resizing the chip.
   -5px vertical (34+10 = 44 tall) but only -4px horizontal: the row gap is
   8px, so 4px a side exactly meets the neighbour's edge and two adjacent
   actions can never claim the same pixel. inset resolves against the PADDING
   box, so the 1px border is added back: -6px/-5px = 5px/4px beyond the visible
   34px chip → a 44x42 hit area. The small radius keeps the corners from eating
   the expansion back (a 16px one clipped the top edge). */
.cl-act::after {
  content: "";
  position: absolute;
  inset: -6px -5px;
  border-radius: 8px;
}
.cl-act:hover {
  background: var(--ink-950);
  border-color: var(--ink-950);
  color: #ffffff;
}
.cl-act:active {
  transform: scale(0.94);
}
.cl-act:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
/* dark bodies (social photo / sms field) → dark-glass chips, white icons */
.cl-card--social .cl-act,
.cl-card--sms .cl-act {
  background: rgba(14, 23, 38, 0.62);
  border-color: rgba(255, 255, 255, 0.16);
  color: #ffffff;
  box-shadow: none;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.cl-card--social .cl-act:hover,
.cl-card--sms .cl-act:hover {
  background: rgba(14, 23, 38, 0.9);
  border-color: rgba(255, 255, 255, 0.4);
}
.cl-card--social .cl-act:focus-visible,
.cl-card--sms .cl-act:focus-visible {
  box-shadow:
    0 0 0 2px rgba(14, 23, 38, 0.55),
    0 0 0 4px #ffffff;
}

/* Card-action feedback (mock) — Approve confirm badge + Refresh regenerating pulse */
.cl-card.is-approved-flash::after {
  content: "✓";
  position: absolute;
  z-index: 9;
  top: 50%;
  left: 50%;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--ink-950);
  color: #ffffff;
  font-size: 25px;
  font-weight: 600;
  transform: translate(-50%, -50%);
  pointer-events: none;
  animation: cl-approve-pop 900ms var(--ease-out-soft);
}
@keyframes cl-approve-pop {
  0% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5);
  }
  22% {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
  }
  74% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) scale(1);
  }
}
.cl-card.is-refreshing .cl-card__inner {
  animation: cl-regen 1100ms var(--ease-smooth);
}
@keyframes cl-regen {
  0% {
    opacity: 1;
  }
  42% {
    opacity: 0.5;
  }
  100% {
    opacity: 1;
  }
}

/* shared chrome: channel tag (top-left) + status flag (top-right) */
.cl-card__chrome {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 6;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 22px;
  pointer-events: none;
}
.cl-tag,
.cl-flag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* light bodies (blog / email) → light chips with ink text */
.cl-tag {
  background: var(--ink-100);
  color: var(--ink-700);
  border: 1px solid var(--ink-200);
}
.cl-flag {
  background: var(--surface);
  color: var(--ink-600);
  border: 1px solid var(--ink-200);
  box-shadow: var(--shadow-badge);
}
/* dark bodies (social photo / sms field) → dark-glass chips with white text */
.cl-card--social .cl-tag,
.cl-card--sms .cl-tag {
  background: rgba(14, 23, 38, 0.62);
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.14);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.cl-card--social .cl-flag,
.cl-card--sms .cl-flag {
  background: rgba(14, 23, 38, 0.62);
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.14);
  box-shadow: none;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
/* the ONE sanctioned accent — the attention (awaiting) flag gets an --alert dot */
.cl-flag--alert::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--alert);
  flex: none;
}
.cl-card--social .cl-flag--alert,
.cl-card--sms .cl-flag--alert {
  color: #ffffff;
}

/* ---- BODY: social — edge-to-edge full-bleed photo + scrim + play (reuse literal) ---- */
.cl-social {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
}
.cl-social__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  filter: saturate(0.98) contrast(0.98);
  transform: scale(1.04);
  transform-origin: center;
  transition: transform var(--dur-rise) var(--ease-out-soft);
}
@media (hover: hover) {
  .cl-card--social:hover .cl-social__img {
    transform: translateY(-8px) scale(1.1);
  }
}
.cl-social__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(14, 23, 38, 0.34) 0%, rgba(14, 23, 38, 0) 22%),
    linear-gradient(
      0deg,
      rgba(14, 23, 38, 0.86) 0%,
      rgba(14, 23, 38, 0.55) 24%,
      rgba(14, 23, 38, 0.12) 46%,
      rgba(14, 23, 38, 0) 62%
    );
}
.cl-play {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  transform: translate(-50%, -50%);
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(14, 23, 38, 0.42);
  color: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.cl-play svg {
  margin-left: 3px;
}
@media (hover: hover) {
  .cl-card--social:hover .cl-play {
    transform: translate(-50%, -50%) scale(1.08);
    background: rgba(14, 23, 38, 0.56);
  }
}

/* ---- BODY: sms — dark field + incoming message bubble + Delivered ---- */
.cl-card--sms .cl-card__inner {
  background: var(--ink-950);
}
.cl-sms {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  padding: 60px 26px 0;
}
.cl-sms__sender {
  margin: 0 0 4px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.cl-sms__bubble {
  max-width: 84%;
  padding: 13px 16px;
  border-radius: 18px 18px 18px 6px;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.92);
  font-size: 14px;
  line-height: 1.5;
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.cl-sms__state {
  align-self: flex-start;
  padding: 3px 9px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* ---- BODY: blog — HTML document/page panel + hover rollover (reuse floating) ---- */
.cl-doc {
  flex: 1 1 auto;
  position: relative;
  z-index: 0;
  padding: 58px 26px 24px;
  background: linear-gradient(
    165deg,
    var(--ink-100) 0%,
    var(--ink-50) 46%,
    #ffffff 88%
  );
  overflow: hidden;
}
.cl-doc__frame {
  height: 100%;
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  box-shadow: var(--shadow-card-rest);
  overflow: hidden;
  transform: translateY(0) scale(1);
  transform-origin: center top;
  transition:
    transform var(--dur-rise) var(--ease-out-soft),
    box-shadow var(--dur-rise) var(--ease-out-soft);
}
@media (hover: hover) {
  .cl-card--blog:hover .cl-doc__frame {
    transform: translateY(-8px) scale(1.03);
    box-shadow: var(--shadow-card-hover);
  }
}
.cl-doc__bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--ink-100);
  background: var(--ink-50);
}
.cl-doc__bar span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ink-200);
}
.cl-doc__page {
  flex: 1 1 auto;
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
}
.cl-doc__kicker {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.1em;
  color: var(--ink-400);
}
.cl-doc__headline {
  margin: 0 0 9px;
  font-size: 18px;
  line-height: 1.22;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink-900);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cl-doc__snippet {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-500);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cl-doc__lines {
  margin-top: auto;
  padding-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.cl-doc__lines span {
  height: 5px;
  border-radius: 3px;
  background: var(--ink-100);
}
.cl-doc__lines span:nth-child(1) {
  width: 100%;
}
.cl-doc__lines span:nth-child(2) {
  width: 92%;
}
.cl-doc__lines span:nth-child(3) {
  width: 68%;
}

/* ---- BODY: email — HTML in-card email preview ---- */
.cl-email {
  flex: 1 1 auto;
  position: relative;
  z-index: 0;
  padding: 58px 26px 22px;
  background: linear-gradient(180deg, var(--ink-50) 0%, #ffffff 40%);
  display: flex;
  flex-direction: column;
}
.cl-email__head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 14px;
}
.cl-email__avatar {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  color: var(--ink-700);
  box-shadow: var(--shadow-badge);
}
.cl-email__who {
  min-width: 0;
}
.cl-email__sender {
  margin: 0;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-900);
}
.cl-email__to {
  margin: 1px 0 0;
  font-size: 12px;
  color: var(--ink-400);
}
.cl-email__subject {
  margin: 0 0 8px;
  font-size: 15px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cl-email__snippet {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-500);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cl-email__lines {
  margin-top: auto;
  padding-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.cl-email__lines span {
  height: 5px;
  border-radius: 3px;
  background: var(--ink-100);
}
.cl-email__lines span:nth-child(1) {
  width: 90%;
}
.cl-email__lines span:nth-child(2) {
  width: 60%;
}

/* ---- Footer: title + meta row (impact dots · cost · freshness) ---- */
.cl-card__footer {
  position: relative;
  z-index: 3;
  padding: 20px 26px 24px;
}
/* light-body cards → in-flow footer on white with a hairline */
.cl-card--blog .cl-card__footer,
.cl-card--email .cl-card__footer {
  border-top: 1px solid var(--ink-100);
  background: var(--surface);
}
.cl-card--blog .cl-card__title,
.cl-card--email .cl-card__title {
  color: var(--ink-900);
}
/* dark-body cards → footer overlays the scrim, white text */
.cl-card__footer--over {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 20px 22px 22px;
}
.cl-card__footer--over .cl-card__title {
  color: #ffffff;
}
.cl-card__title {
  margin: 0;
  font-size: 16px;
  line-height: 1.24;
  font-weight: 600;
  letter-spacing: -0.015em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cl-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 11px;
}
.cl-dots {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}
/* The 5-dot impact meter is a graphical object (1.4.11): BOTH states need 3:1
   against their backdrop, or you cannot count the unlit dots and "4 of 5"
   becomes unreadable. Unlit was --ink-300 (1.32:1 on white) / 30% white
   (2.43:1 on the scrim). Lit stays clearly the stronger of the pair. */
.cl-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-500); /* 4.76:1 on white */
}
.cl-dot.is-on {
  background: var(--ink-900); /* 16.3:1 — 3.4x the unlit dot */
}
.cl-card__footer--over .cl-dot {
  background: rgba(255, 255, 255, 0.45); /* ~4.1:1 on the footer scrim */
}
.cl-card__footer--over .cl-dot.is-on {
  background: #ffffff;
}
.cl-meta__cost,
.cl-meta__fresh {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--ink-500);
}
.cl-card__footer--over .cl-meta__cost,
.cl-card__footer--over .cl-meta__fresh {
  color: rgba(255, 255, 255, 0.72);
}
.cl-meta__fresh {
  color: var(--ink-700);
}
.cl-card__footer--over .cl-meta__fresh {
  color: #ffffff;
}

/* source line — below the card, in the grid gap (date · originating loop) */
.cl-source {
  margin: 12px 2px 0;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-600); /* 4.19:1 → 7.0:1 on --page-bg at 11px */
}

/* empty state — a filter/search returned nothing */
.cl-empty {
  padding: 48px 24px;
  text-align: center;
}
.cl-empty__title {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-700);
}
.cl-empty__sub {
  margin: 0;
  font-size: 14px;
  color: var(--ink-500);
}

/* ============================================================
   LOCATIONS — sub-knowledge bases (change-brief-15).
   Reuses .card--node + .card-grid--drill + .cl-search wholesale;
   only the activation-status cue and the lighter detail need CSS.
   ============================================================ */
.loc-controls {
  margin-bottom: 26px;
}
/* channel-activation cue on a location card (replaces the Explore link) */
.loc-status {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}
.loc-status__label {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-500);
}
.card--loc {
  cursor: pointer;
}
/* glyph left, activation cue right — the only node card whose top row carries
   two things, so it overrides the shared flex-end alignment */
.card--loc .node-card__top {
  justify-content: space-between;
  align-items: center;
}
.card--loc .loc-status {
  margin-top: 0;
}

/* Location detail = the simplified activation dashboard. Deliberately calmer &
   lighter than the full home: capped width, centered, no page-title heading. */
.loc-detail {
  display: flex;
  flex-direction: column;
}
.loc-detail__meta {
  margin: 0 0 24px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--ink-500);
}
/* grid reflows exactly like every other drilled section (was capped at 1180px,
   which forced a stuck 2-up that didn't respond to resize). */
/* terminal activation cards read quietly (no pointer, softer glyph) */
.card--loc-asset {
  cursor: default;
}

/* Responsive — pill row + controls collapse; count moves under pills */
@media (max-width: 720px) {
  .cl-controls {
    gap: 10px;
  }
  .cl-search {
    flex-basis: 100%;
  }
  .cl-selects {
    flex: 1 1 auto;
  }
  .cl-select {
    flex: 1 1 0;
  }
  .cl-select__field {
    width: 100%;
  }
  .cl-pillrow {
    align-items: flex-start;
  }
}

/* ============================================================
   CONTENT LIBRARY — PREVIEW MODAL (change-brief-13, Phase 3 / §5.4)
   Centered card-like modal (NOT a drawer). Reuses .modal-backdrop +
   x-trap + Esc family. Monochrome LEVR chrome; the client mockup
   ("how the post will look") carries its own presentation. Channel-
   accurate mockups for all 4 render types; metrics + canon gate.
   ============================================================ */
.cl-preview-backdrop {
  align-items: center;
  padding: 24px 20px;
  background: rgba(16, 42, 72, 0.42);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  z-index: 110;
}
.cl-preview {
  display: flex;
  /* head / wrap / foot are SIBLINGS. Without an explicit column direction they
     laid out as a row: the header alone was 650px inside a 640px shell and the
     footer's right edge landed 543px past the modal, so overflow:hidden ate
     the mockup, the metrics, the canon gate and every action button. */
  flex-direction: column;
  width: 100%;
  max-width: 640px;
  max-height: 88vh;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-card); /* 48px family */
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.24);
  overflow: hidden;
}
.cl-preview__wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}

/* Header — CHANNEL · TYPE · status · prev/next · close */
.cl-preview__head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 28px 18px;
  border-bottom: 1px solid var(--ink-100);
}
.cl-preview__headmain {
  min-width: 0;
}
.cl-preview__eyebrow {
  margin: 0 0 9px;
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.cl-preview__sep {
  color: var(--ink-300);
}
.cl-preview__status {
  margin-left: 4px;
  padding: 3px 9px;
  border-radius: 9999px;
  background: var(--ink-100);
  color: var(--ink-600);
  letter-spacing: 0.06em;
}
.cl-preview__status.is-alert::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 6px;
  border-radius: 50%;
  background: var(--alert);
  vertical-align: middle;
}
.cl-preview__title {
  margin: 0;
  font-size: 21px;
  line-height: 1.22;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.cl-preview__nav {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.cl-nav-btn {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  color: var(--ink-600);
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.cl-nav-btn:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-900);
}
.cl-nav-btn:active {
  transform: scale(0.94);
}
.cl-nav-btn:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}

/* Body — internal scroll */
.cl-preview__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 22px 28px 26px;
  /* soft bottom fade — a quiet cue that content continues below (Gate 3 fix) */
  -webkit-mask-image: linear-gradient(
    to bottom,
    #000 calc(100% - 18px),
    transparent
  );
  mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
}
.cl-preview.is-refreshing .cl-preview__body {
  animation: cl-regen 1100ms var(--ease-smooth);
}
.cl-preview__caplabel {
  margin: 0 0 14px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-400);
}

/* ---- MOCKUP: social — Instagram post (the centerpiece) ---- */
.ig-post {
  max-width: 400px;
  margin: 0 auto;
  border: 1px solid var(--ink-200);
  border-radius: 18px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.ig-post__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
}
.ig-post__avatar {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--ink-950);
  color: #ffffff;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
}
.ig-post__handle {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-900);
}
.ig-post__badge {
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--ink-100);
  color: var(--ink-600);
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
}
.ig-post__more {
  margin-left: auto;
  color: var(--ink-600);
  font-size: 18px;
  line-height: 1;
}
/* cap the reel/post height in the modal so the metrics row + canon gate stay
   above the fold on a common laptop (Gate 3 fix) */
.ig-post__media {
  position: relative;
  aspect-ratio: 4 / 5;
  height: auto;
  background: var(--ink-100);
  overflow: hidden;
}
.ig-post__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ig-post__play {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(14, 23, 38, 0.42);
  color: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.ig-post__play svg {
  margin-left: 3px;
}
.ig-post__actions {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 14px 2px;
  color: var(--ink-800);
}
.ig-post__actions svg {
  width: 24px;
  height: 24px;
}
.ig-post__bookmark {
  margin-left: auto;
}
.ig-post__caption {
  margin: 8px 14px 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-800);
}
.ig-post__caphandle {
  font-weight: 600;
  color: var(--ink-900);
  margin-right: 6px;
}
.ig-post__tags {
  margin: 6px 14px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-500);
}

/* ---- MOCKUP: sms — message thread ---- */
.sms-thread {
  max-width: 400px;
  margin: 0 auto;
  padding: 22px 20px 18px;
  border-radius: 18px;
  background: var(--ink-950);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.sms-thread__sender {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}
.sms-thread__bubble {
  max-width: 88%;
  padding: 12px 15px;
  border-radius: 18px 18px 18px 6px;
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.94);
  font-size: 14px;
  line-height: 1.5;
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.sms-thread__state {
  align-self: flex-start;
  padding: 3px 9px;
  border-radius: 9999px;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.6);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
}

/* ---- MOCKUP: email — inbox message ---- */
.mail-mock {
  max-width: 480px;
  margin: 0 auto;
  padding: 20px 22px 22px;
  border: 1px solid var(--ink-200);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.mail-mock__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--ink-100);
  margin-bottom: 16px;
}
.mail-mock__avatar {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 11px;
  background: var(--ink-100);
  color: var(--ink-700);
}
.mail-mock__who {
  min-width: 0;
}
.mail-mock__sender {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-900);
}
.mail-mock__to {
  margin: 2px 0 0;
  font-size: 12.5px;
  color: var(--ink-400);
}
.mail-mock__subject {
  margin: 0 0 10px;
  font-size: 17px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
}
.mail-mock__body {
  margin: 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-600);
}

/* ---- MOCKUP: blog — document ---- */
.blog-mock {
  max-width: 480px;
  margin: 0 auto;
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-card-rest);
}
.blog-mock__bar {
  display: flex;
  gap: 6px;
  padding: 12px 16px;
  background: var(--ink-50);
  border-bottom: 1px solid var(--ink-100);
}
.blog-mock__bar span {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ink-200);
}
.blog-mock__page {
  padding: 24px 26px 26px;
}
.blog-mock__kicker {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.blog-mock__headline {
  margin: 0 0 12px;
  font-size: 24px;
  line-height: 1.18;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.blog-mock__deck {
  margin: 0 0 20px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-500);
}
.blog-mock__lines {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.blog-mock__lines span {
  height: 7px;
  border-radius: 4px;
  background: var(--ink-100);
}
.blog-mock__lines span:nth-child(1) {
  width: 100%;
}
.blog-mock__lines span:nth-child(2) {
  width: 97%;
}
.blog-mock__lines span:nth-child(3) {
  width: 99%;
}
.blog-mock__lines span:nth-child(4) {
  width: 92%;
}
.blog-mock__lines span:nth-child(5) {
  width: 58%;
}

/* ---- signals line + metrics row ---- */
.cl-preview__signals {
  margin: 18px auto 0;
  max-width: 480px;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-700);
}
.cl-metrics {
  margin: 12px auto 0;
  max-width: 480px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  padding: 16px 18px;
  border: 1px solid var(--ink-200);
  border-radius: 16px;
  background: var(--ink-50);
}
.cl-metric {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
}
.cl-metric__cap {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.cl-metric__val {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-900);
}
.cl-dots--lg {
  gap: 4px;
}
.cl-dots--lg .cl-dot {
  width: 8px;
  height: 8px;
}
.cl-metric .cl-dot {
  background: var(--ink-500); /* --ink-300 read 1.32:1 on white (1.4.11) */
}
.cl-metric .cl-dot.is-on {
  background: var(--ink-900);
}

/* ---- The gate — aligned to canon, evidence enough? ---- */
.cl-gate {
  margin: 20px auto 0;
  max-width: 480px;
}
.cl-gate__head {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.cl-gate__row {
  display: flex;
  gap: 11px;
  align-items: flex-start;
}
.cl-gate__row + .cl-gate__row {
  margin-top: 12px;
}
.cl-gate__ck {
  flex: none;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  margin-top: 1px;
}
.cl-gate__txt {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-600);
}
.cl-gate__txt b {
  color: var(--ink-900);
  font-weight: 600;
}

/* ---- Footer — Approve · Refresh · Reject · Edit (primary) + shortcuts ---- */
.cl-preview__foot {
  flex: none;
  padding: 16px 28px 18px;
  border-top: 1px solid var(--ink-100);
}
.cl-preview__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}
.cl-pbtn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--ink-200);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink-700);
  font-family: var(--font-ui);
  font-size: 13.5px;
  font-weight: 600;
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.cl-pbtn svg {
  color: var(--ink-500);
}
.cl-pbtn:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-900);
}
.cl-pbtn:hover svg {
  color: var(--ink-700);
}
.cl-pbtn:active {
  transform: scale(0.97);
}
.cl-pbtn:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
.cl-pbtn--primary {
  margin-left: auto;
  background: var(--ink-950);
  border-color: var(--ink-950);
  color: #ffffff;
}
.cl-pbtn--primary svg {
  color: #ffffff;
}
.cl-pbtn--primary:hover {
  background: var(--ink-800);
  border-color: var(--ink-800);
  color: #ffffff;
}
.cl-pbtn--primary:hover svg {
  color: #ffffff;
}
.cl-preview__hints {
  margin: 14px 0 0;
  min-height: 18px;
  font-size: 12px;
  color: var(--ink-500);
}
.cl-preview__keys .kbd,
.cl-preview__hints .kbd {
  margin: 0 1px;
  font-size: 10.5px;
}
/* Preview modal — small-screen: near-full-width, tighter gutters */
@media (max-width: 620px) {
  .cl-preview-backdrop {
    padding: 14px 10px;
  }
  .cl-preview {
    max-height: 94vh;
    border-radius: 30px;
  }
  .cl-preview__head {
    padding: 20px 18px 14px;
  }
  .cl-preview__body {
    padding: 18px 16px 20px;
  }
  .cl-preview__foot {
    padding: 14px 18px 16px;
  }
  .cl-preview__title {
    font-size: 19px;
  }
  .cl-pbtn {
    flex: 1 1 auto;
    justify-content: center;
  }
  .cl-pbtn--primary {
    margin-left: 0;
    flex-basis: 100%;
  }
}

/* ============================================================
   DETAIL ITEM MODAL — level 3 of a section drill.

   Deliberately the preview modal's smaller sibling: same backdrop, same
   .cl-nav-btn prev/next primitive, same head / scrolling body / foot
   skeleton. It reads as one entry out of a set you are stepping through,
   so it is narrower than the preview (it holds prose, not a mockup) and
   its position lives in the header as "3 / 7".
   ============================================================ */
.item-backdrop {
  align-items: center;
  padding: 24px 20px;
  background: rgba(16, 42, 72, 0.42);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  z-index: 110;
}
.item-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 620px;
  max-height: 86vh;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-card);
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.24);
  overflow: hidden;
}
.item-modal__head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 24px 28px 18px;
  border-bottom: 1px solid var(--ink-100);
}
.item-modal__headmain {
  min-width: 0;
}
/* no bottom margin: the title owns the gap, so a heading-less entry (a quote,
   a tagline) does not leave 9px of dangling space above the nav buttons */
.item-modal__eyebrow {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.item-modal__sep {
  color: var(--ink-300);
}
.item-modal__pos {
  font-variant-numeric: tabular-nums;
  color: var(--ink-600);
}
.item-modal__title {
  margin: 9px 0 0;
  font-size: 20px;
  line-height: 1.28;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
  text-wrap: pretty;
}
.item-modal__nav {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
.item-modal__x {
  flex: none;
}
.item-modal__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 24px 28px 26px;
}
.item-modal__body:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--ink-900);
}
.item-modal__text {
  margin: 0;
  font-size: 16px;
  line-height: 1.62;
  color: var(--ink-800);
  text-wrap: pretty;
}
.item-modal__quote {
  margin: 0;
  padding: 24px 26px;
  border-radius: var(--radius-image);
  background: var(--ink-950);
  color: #ffffff;
}
.item-modal__quotetext {
  margin: 0;
  font-size: 17px;
  line-height: 1.55;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #ffffff;
  text-wrap: pretty;
}
.item-modal__quotesrc {
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  font-size: 12.5px;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.76);
}
.item-modal__foot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 28px 18px;
  border-top: 1px solid var(--ink-100);
}
.item-modal__src {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink-500);
}
/* .cl-preview__keys carries no size of its own (it inherits the preview
   footer's), so the shortcut hint has to state one here. */
.item-modal__foot .cl-preview__keys {
  margin: 0;
  font-size: 12px;
  color: var(--ink-500);
}
@media (max-width: 620px) {
  .item-backdrop {
    padding: 14px 10px;
  }
  .item-modal {
    max-height: 94vh;
    border-radius: 30px;
  }
  .item-modal__head {
    padding: 20px 18px 14px;
  }
  .item-modal__body {
    padding: 18px 16px 20px;
  }
  .item-modal__foot {
    padding: 12px 18px 16px;
  }
  .item-modal__title {
    font-size: 18px;
  }
}

/* ============================================================
   CONTENT LIBRARY — EDIT MODAL (change-brief-14, Phase 4)
   Near-full-screen, two-pane focused workspace one level deeper
   than the preview. Monochrome chrome; styled inputs (no raw
   browser chrome); reduced-motion clean.
   ============================================================ */
.cl-edit-backdrop {
  align-items: center;
  padding: 24px;
  background: rgba(16, 42, 72, 0.48);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  z-index: 120; /* above the preview modal (110) */
}
.cl-edit {
  display: flex;
  width: min(1200px, 94vw);
  height: min(860px, 92vh);
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 40px; /* 48px family, slightly tighter on the big surface */
  box-shadow:
    0 10px 30px rgba(16, 42, 72, 0.16),
    0 40px 80px rgba(16, 42, 72, 0.28);
  overflow: hidden;
}
.cl-edit__wrap {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}

/* Header */
.cl-edit__head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 28px 18px;
  border-bottom: 1px solid var(--ink-100);
}
.cl-edit__headmain {
  min-width: 0;
}
.cl-edit__eyebrow {
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.cl-edit__sep {
  color: var(--ink-300);
}
.cl-edit__title {
  margin: 0;
  font-size: 21px;
  line-height: 1.22;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
  overflow: hidden;
  text-overflow: ellipsis;
}
.cl-edit__headact {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
}
.cl-ebtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 38px;
  padding: 0 18px;
  border-radius: 12px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-700);
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.cl-ebtn svg {
  color: var(--ink-500);
}
.cl-ebtn:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-900);
}
.cl-ebtn:active {
  transform: scale(0.97);
}
.cl-ebtn:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
.cl-ebtn--primary {
  background: var(--ink-950);
  border-color: var(--ink-950);
  color: #ffffff;
}
.cl-ebtn--primary svg {
  color: #ffffff;
}
.cl-ebtn--primary:hover {
  background: var(--ink-800);
  border-color: var(--ink-800);
  color: #ffffff;
}
.cl-edit__x {
  flex: none;
}

/* Two panes */
.cl-edit__panes {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(340px, 0.95fr);
  overflow: hidden;
}

/* LEFT — live preview stage */
.cl-edit__preview {
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 30px 24px;
  background: var(--ink-50);
  border-right: 1px solid var(--ink-100);
}
.cl-edit__plabel {
  margin: 0;
  flex: none;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.cl-edit__stage {
  flex: 1 1 auto;
  display: grid;
  place-items: center;
  min-height: 0;
  padding: 6px 0;
}
.cl-edit__stage > * {
  width: 100%;
}
.cl-edit__livenote {
  margin: 0;
  flex: none;
  text-align: center;
  font-size: 12px;
  color: var(--ink-400);
}

/* RIGHT — editor toolset */
.cl-edit__tools {
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding: 24px 28px 26px;
  background: var(--surface);
}
.cl-edit__toolhead {
  margin: 0;
  flex: none;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.cl-toolset {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* Field group */
.cl-field {
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.cl-field__lab {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 22px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.cl-field__hint {
  font-weight: 500;
  letter-spacing: 0.04em;
  color: var(--ink-400);
  text-transform: none;
}
.cl-field__note {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ink-500);
}
.cl-field__note code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--ink-100);
  padding: 1px 5px;
  border-radius: 6px;
  color: var(--ink-700);
}
.cl-field--split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.cl-field--split > div {
  display: flex;
  flex-direction: column;
  gap: 9px;
  min-width: 0;
}

/* Inputs — styled to the system, not raw browser chrome */
.cl-ctl {
  position: relative;
}
.cl-input,
.cl-textarea {
  width: 100%;
  display: block;
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-900);
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 14px;
  padding: 11px 13px;
  caret-color: var(--ink-900);
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth);
}
.cl-textarea {
  resize: vertical;
  min-height: 84px;
  max-height: 320px;
}
.cl-input::placeholder,
.cl-textarea::placeholder {
  color: var(--ink-400);
}
.cl-input:hover,
.cl-textarea:hover {
  border-color: var(--ink-300);
}
.cl-input:focus,
.cl-textarea:focus {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 3px var(--focus-ink);
}

/* Refine shimmer overlay — monochrome sweep over the control while busy */
.cl-ctl::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 14px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(
    100deg,
    transparent 34%,
    rgba(21, 32, 51, 0.1) 50%,
    transparent 66%
  );
  background-size: 220% 100%;
  background-position: 130% 0;
}
.cl-ctl.is-refining::after {
  opacity: 1;
  animation: cl-refine-sweep 820ms var(--ease-smooth);
}
.cl-ctl.is-refining .cl-input,
.cl-ctl.is-refining .cl-textarea {
  border-color: var(--ink-300);
}
@keyframes cl-refine-sweep {
  from {
    background-position: 130% 0;
  }
  to {
    background-position: -30% 0;
  }
}

/* ✨ Refine affordance */
.cl-refine {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 11px;
  border-radius: 9999px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  font-family: var(--font-ui);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-600);
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth);
}
.cl-refine__spark {
  color: var(--ink-500);
  flex: none;
}
.cl-refine:hover {
  background: var(--ink-50);
  border-color: var(--ink-300);
  color: var(--ink-900);
}
.cl-refine:hover .cl-refine__spark {
  color: var(--ink-700);
}
.cl-refine:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
.cl-refine.is-busy {
  opacity: 0.65;
  cursor: default;
}
.cl-refine.is-busy .cl-refine__spark {
  animation: cl-spark-pulse 820ms var(--ease-smooth) infinite;
}
@keyframes cl-spark-pulse {
  0%,
  100% {
    opacity: 0.4;
    transform: scale(0.9);
  }
  50% {
    opacity: 1;
    transform: scale(1.15);
  }
}

/* Swap-image thumbnails */
.cl-swap {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.cl-swap__thumb {
  position: relative;
  width: 68px;
  height: 68px;
  padding: 0;
  flex: none;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--ink-200);
  background: var(--ink-100);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    box-shadow var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth);
}
.cl-swap__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cl-swap__thumb:hover {
  border-color: var(--ink-400);
  transform: translateY(-2px);
}
.cl-swap__thumb:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
.cl-swap__thumb.is-sel {
  border-color: transparent;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
.cl-swap__ck {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  box-shadow: 0 1px 3px rgba(16, 42, 72, 0.35);
}

.cl-edit__keys {
  margin: auto 0 0;
  padding-top: 4px;
  flex: none;
  font-size: 12px;
  color: var(--ink-400);
}
.cl-edit__keys .kbd {
  margin: 0 1px;
  font-size: 10.5px;
}

/* Edit modal — stack panes on narrow widths (≤900) */
@media (max-width: 900px) {
  .cl-edit-backdrop {
    padding: 14px;
  }
  .cl-edit {
    width: 96vw;
    height: 94vh;
    border-radius: 30px;
  }
  .cl-edit__panes {
    display: block;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .cl-edit__preview {
    overflow: visible;
    border-right: none;
    border-bottom: 1px solid var(--ink-100);
  }
  .cl-edit__stage {
    min-height: 300px;
  }
  .cl-edit__tools {
    overflow: visible;
  }
}

/* Edit modal — phone (~390) */
@media (max-width: 560px) {
  .cl-edit {
    border-radius: 24px;
  }
  .cl-edit__head {
    padding: 18px 16px 14px;
    flex-wrap: wrap;
  }
  .cl-edit__title {
    font-size: 18px;
  }
  .cl-edit__headact {
    gap: 8px;
  }
  .cl-ebtn {
    height: 36px;
    padding: 0 14px;
  }
  .cl-edit__preview {
    padding: 20px 16px 18px;
  }
  .cl-edit__tools {
    padding: 20px 16px 22px;
  }
  .cl-field--split {
    grid-template-columns: 1fr;
  }
  .cl-swap__thumb {
    width: 58px;
    height: 58px;
  }
}

/* ============================================================
   EMAIL SEQUENCES — interactive: reusable pill tags + a stripped
   email view with NO traditional page chrome (brief §Interactive).
   ============================================================ */
.email-view {
  display: block;
}

/* ---- Reusable PILL TAGS (B&W chrome) ---- */
.pilltags {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 26px;
}
.pilltag {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--ink-700);
  font-size: 13.5px;
  font-weight: 600;
  box-shadow: var(--shadow-search);
  transition:
    background var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.pilltag__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-300);
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-out-soft);
}
.pilltag__count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-600);
  padding: 2px 7px;
  border-radius: 9999px;
  background: var(--ink-100);
}
.pilltag:hover {
  border-color: var(--ink-300);
  background: var(--ink-50);
}
.pilltag:active {
  transform: scale(0.97);
}
.pilltag:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-900);
}
.pilltag.is-on {
  background: var(--ink-950);
  color: #ffffff;
  border-color: var(--ink-950);
}
.pilltag.is-on .pilltag__dot {
  background: #ffffff;
  transform: scale(1.15);
}
.pilltag.is-on .pilltag__count {
  background: rgba(255, 255, 255, 0.16);
  color: #ffffff;
}

/* ---- A filter with nothing behind it ----
   Six of the seven Content Library statuses sit at 0. Hiding them would lie
   about the shape of the library, so they stay — just quieter. Only colour,
   border-colour and shadow change, never a metric that affects layout, so a
   count going 0 -> 1 un-dims in place without moving the row.

   `:not(.is-on)` keeps the selected state untouched even when the filter the
   user picked is the empty one.
   Measured: label + count are --ink-500 (#64748B) on --surface = 4.76:1, so a
   de-emphasised pill still clears 1.4.3 AA. The dot drops to --ink-200 and is
   decorative — the number beside it carries the same information as text. */
.pilltag.is-empty:not(.is-on) {
  color: var(--ink-500);
  border-color: var(--ink-100);
  box-shadow: none;
}
.pilltag.is-empty:not(.is-on) .pilltag__dot {
  background: var(--ink-200);
}
.pilltag.is-empty:not(.is-on) .pilltag__count {
  color: var(--ink-500);
  background: transparent;
}
/* still a control: pointing at it or tabbing to it restores full weight */
.pilltag.is-empty:not(.is-on):hover,
.pilltag.is-empty:not(.is-on):focus-visible {
  color: var(--ink-700);
  border-color: var(--ink-300);
  background: var(--ink-50);
}
.pilltag.is-empty:not(.is-on):hover .pilltag__count,
.pilltag.is-empty:not(.is-on):focus-visible .pilltag__count {
  color: var(--ink-600);
  background: var(--ink-100);
}

/* ---- Stripped email view: list + light preview pane ---- */
.email-strip {
  display: grid;
  grid-template-columns: minmax(280px, 380px) 1fr;
  gap: 28px;
  align-items: start;
}
@media (max-width: 860px) {
  .email-strip {
    grid-template-columns: 1fr;
  }
}

.email-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.email-row {
  display: flex;
  gap: 14px;
  width: 100%;
  padding: 14px 16px;
  text-align: left;
  border: 1px solid transparent;
  border-radius: 18px;
  background: transparent;
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth);
}
.email-row:hover {
  background: var(--ink-50);
}
.email-row.is-sel {
  background: var(--surface);
  border-color: var(--ink-200);
  box-shadow: var(--shadow-search);
}
.email-row__day {
  flex: none;
  width: 52px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-600);
  padding-top: 2px;
}
.email-row.is-sel .email-row__day {
  color: var(--ink-700);
}
.email-row__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.email-row__subj {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink-900);
}
.email-row__prev {
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--ink-600);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.email-row:focus-visible {
  outline: none;
  border-color: var(--ink-900);
  box-shadow: 0 0 0 2px var(--focus-ink);
}

/* Light preview pane — minimal, no app chrome; client content may carry SGA blue */
.email-preview {
  padding: 28px 30px 30px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 24px;
  box-shadow: var(--shadow-card-rest);
}
.email-preview__from {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--ink-100);
}
.email-preview__avatar {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: var(
    --client-accent,
    var(--blue-500)
  ); /* client brand — this is client CONTENT, not chrome */
  color: #ffffff;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  flex: none;
}
.email-preview__fromtext {
  flex: 1 1 auto;
  min-width: 0;
}
.email-preview__sender {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-900);
}
.email-preview__meta {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--ink-500);
}
.email-preview__seq {
  flex: none;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-500);
  padding: 4px 10px;
  border-radius: 9999px;
  background: var(--ink-100);
}
.email-preview__subject {
  margin: 20px 0 14px;
  font-size: 20px;
  line-height: 1.25;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink-900);
}
.email-preview__p {
  margin: 0 0 14px;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-700);
  max-width: 62ch;
}
.email-preview__cta {
  display: inline-block;
  margin-top: 4px;
  font-size: 14px;
  font-weight: 600;
  color: var(--client-600, var(--blue-600)); /* client-content link accent */
}

/* ============================================================
   REDUCED MOTION — kill all motion (spec §2.7)
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .card:hover {
    transform: none;
  }
  .card:hover .card__media img,
  .card:hover .card__media video {
    transform: scale(1.04);
  }
  .card:hover .card__panel {
    transform: none;
  }
  .card:hover .metric-figure {
    transform: none;
  }
  .cl-card:hover,
  .cl-card:hover .cl-doc__frame,
  .cl-card:hover .cl-media img {
    transform: none;
  }
  .card-grid.reveal .card {
    opacity: 1;
    transform: none;
  }
  .card__video {
    display: none;
  }

  /* Walk-and-Talk: no idle audio-bar animation, no rail pulse, instant reveals.
     Bars settle to a calm static waveform (varied heights, no motion). */
  .wt-levels i {
    animation: none !important;
  }
  .wt-levels i:nth-child(1) {
    transform: scaleY(0.45);
  }
  .wt-levels i:nth-child(2) {
    transform: scaleY(0.8);
  }
  .wt-levels i:nth-child(3) {
    transform: scaleY(1);
  }
  .wt-levels i:nth-child(4) {
    transform: scaleY(0.65);
  }
  .wt-levels i:nth-child(5) {
    transform: scaleY(0.85);
  }
  .wt-levels i:nth-child(6) {
    transform: scaleY(0.5);
  }
  .wt-levels i:nth-child(7) {
    transform: scaleY(0.7);
  }
  .wt-rail__item.is-change.is-in-progress .wt-rail__line {
    animation: none !important;
  }

  /* circular Walk & Talk button: no scale, label appears instantly */
  .wt-entry:hover {
    transform: none;
  }
  .wt-entry-wrap:hover .wt-entry__label,
  .wt-entry:focus-visible ~ .wt-entry__label {
    transform: translateX(-50%) translateY(0);
  }

  /* Pinned dock: no fly-in transform — appear/disappear by opacity only */
  .pin-dock {
    transform: none !important;
  }
  .pin-dock.is-docked {
    transform: none !important;
  }

  /* Card-drilling nav: instant level swap, no fade, static node glyph */
  .stage {
    transition: none !important;
  }
  .stage.is-out {
    opacity: 1;
  }
  .card--node:hover .node-card__glyph {
    transform: none;
  }
  .crumb__menu {
    transition: none !important;
  }

  /* Edit modal: no thumbnail lift, no Refine shimmer/spark motion */
  .cl-swap__thumb:hover {
    transform: none;
  }
  .cl-ctl.is-refining::after {
    animation: none;
    opacity: 0;
  }
  .cl-refine.is-busy .cl-refine__spark {
    animation: none;
  }
}

/* Cloak for Alpine (prevent flash of unstyled template) */
[x-cloak] {
  display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   v8 additions — hero, shared-footer plumbing, and the conversations strip.
   Tokens only; no new colours. Chrome stays monochrome.
   ═══════════════════════════════════════════════════════════════════════ */

/* The floating treatment needs one wrapper element to satisfy x-if's
   single-root rule; display:contents keeps it out of the layout entirely so
   the wash/panel still resolve against .card__inner. */
.card__pane {
  display: contents;
}

/* The footer is now shared across all four treatments; floating just needs
   the same in-flow-over-wash placement the other variants already had. */
.card__footer--floating {
  padding: 20px 24px 26px;
}

/* ---- hero caption ----------------------------------------------------
   The old .hero was a card-grid clone that left-aligned the search row on the
   first card's edge. The benchmark centres the whole band instead, so the grid
   geometry moved to .search-hero / .search-hero__stack (see §SEARCH BAR) and
   only the caption's own type survives here.
   The top margin clears .wt-entry__label, which drops 14px below the circle on
   hover — anything tighter and the wordmark lands on top of this line. */
.hero__note {
  margin: 38px 0 0;
  font-size: 13px;
  text-align: center;
  text-wrap: balance;
  /* --ink-500 is 4.76:1 on white but only 4.19:1 on the --page-bg tint.
     Every muted line that sits on the tinted page moves one step darker. */
  color: var(--ink-600);
  letter-spacing: 0.01em;
}
.hero__note strong {
  color: var(--ink-700);
  font-weight: 600;
}
@media (max-width: 620px) {
  /* the row goes column here, so the circle's hover label has room already */
  .hero__note {
    margin-top: 26px;
  }
}

/* ---- stage cross-fade between levels --------------------------------- */
.stage.is-fading {
  opacity: 0;
}
.stage {
  transition: opacity var(--dur-fast) var(--ease-smooth);
}

/* ---- drilled node states --------------------------------------------- */
.card.is-asset .card__link {
  color: var(--ink-700);
}

/* ---- briefing synthesis column --------------------------------------- */
.synth__col {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

/* The walk transcript used to be styled twice: .wt-modal__body / .wt-turn--you
   / .wt-turn--kb up in the WALK-AND-TALK section, and a second, flatter
   .wt-transcript / .wt-turn.is-you set down here. Because this one came later
   it won every shared property — max-width, padding, radius — and put the
   bubble's padding on the turn WRAPPER. The modal now uses the benchmark's
   markup, so the duplicate is gone rather than overridden. */

.blog-mock__body {
  margin: 8px 0 0;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-600);
}

/* ---- preview modal, editing state ------------------------------------
   Edit is a deeper STATE of preview, not a second modal — it widens to a
   two-pane workspace with the live mockup on the left. */
.cl-preview.is-editing {
  max-width: min(1560px, 96vw);
  width: 96vw;
  height: 92vh;
}
.cl-preview.is-editing .cl-preview__wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 420px);
  gap: 28px;
  align-items: start;
  overflow: hidden;
}
@media (max-width: 900px) {
  .cl-preview.is-editing .cl-preview__wrap {
    grid-template-columns: 1fr;
  }
}

/* ---- conversations for the current context ---------------------------
   Walks started from this page, surfaced on this page. */
.convos {
  max-width: 2100px;
  margin: 8px auto 0;
  padding: 40px 24px 72px;
  border-top: 1px solid var(--ink-200);
}
@media (min-width: 1024px) {
  .convos {
    padding: 48px 40px 88px;
  }
}
/* Same doctrine as .stage: reserve the fixed orb's footprint on phones so the
   "Talk about…" CTA — the last thing on every drilled surface — is not sitting
   under the orb once you have scrolled to the end. */
@media (max-width: 480px) {
  .convos {
    padding-bottom: 96px;
  }
}
.convos__head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 20px;
}
.convos__title {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
}
.convos__ctx {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-600); /* --ink-400 measured 2.26:1 on --page-bg */
}
.convos__loading {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 520px;
}
.convos__loading .skel-bar {
  height: 12px;
}
.convos__empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 14px;
}
.convos__empty-title {
  margin: 0;
  font-size: 14px;
  color: var(--ink-600);
}
.convos__cta {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 12px 20px;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--ink-900);
  color: #fff;
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: var(--shadow-pill);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    box-shadow var(--dur-base) var(--ease-smooth);
}
.convos__cta:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card-hover);
}
.convos__cta:active {
  transform: scale(0.98);
}
.convos__cta:focus-visible {
  outline: 2px solid var(--ink-900);
  outline-offset: 3px;
}
.convos__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}
.convos__item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  padding: 18px 20px;
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-image);
  background: var(--surface);
  font: inherit;
  cursor: pointer;
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-out-soft);
}
.convos__item:hover {
  border-color: var(--ink-300);
  box-shadow: var(--shadow-card-rest);
  transform: translateY(-2px);
}
.convos__item:focus-visible {
  outline: 2px solid var(--ink-900);
  outline-offset: 2px;
}
.convos__item-title {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink-900);
}
.convos__item-meta {
  font-family: "Geist Mono", ui-monospace, monospace;
  font-size: 11px;
  color: var(--ink-400);
}
.convos__item-snip {
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-500);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .stage,
  .convos__cta,
  .convos__item {
    transition: none !important;
  }
  .convos__cta:hover,
  .convos__item:hover {
    transform: none;
  }
}

/* ---- stage as THE container -------------------------------------------
   Drilled surfaces (library, loops, briefing, leaf) were rendering edge-to-edge
   because only .card-grid carried the container geometry. Move it up to .stage
   and let the grids inside just lay out. Matches .hero exactly so the hero,
   the home grid and every drilled surface share one left edge. */
.stage {
  max-width: 2100px;
  margin-inline: auto;
  padding: 24px;
  padding-left: max(24px, var(--rail-lane));
}
@media (min-width: 1024px) {
  .stage {
    padding: 40px;
    padding-left: max(40px, var(--rail-lane));
  }
}
@media (min-width: 1600px) {
  .stage {
    padding: 48px;
    padding-left: max(48px, var(--rail-lane));
  }
}
/* Reserve the fixed orb's footprint on phones so the last card in any surface
   never terminates underneath it (its halo separates it mid-scroll; this stops
   the bottom of the list being permanently un-tappable). */
@media (max-width: 480px) {
  .stage {
    padding-bottom: 88px;
  }
}
.stage > .card-grid {
  padding: 0;
  padding-left: 0;
  max-width: none;
  margin: 0;
}
.convos {
  padding-left: 0;
  padding-right: 0;
  max-width: none;
}

/* .cl-grid only ever set align-items; the grid itself was never declared. */
.cl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  justify-content: center;
  gap: 36px;
  max-width: 1400px;
  align-items: start;
}
/* minmax(0,1fr) not 1fr: a bare 1fr track has an AUTO minimum, so the
   searchbar's 499px min-content blew the .cl-grid 102px past a 375px
   viewport and scrolled the whole page sideways. */
@media (max-width: 480px) {
  .cl-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The media layers (.cl-social/.cl-doc/.cl-email/.cl-sms) are absolutely
   positioned, so the footer is the only in-flow child of the flex column and
   lands at the TOP, colliding with .cl-card__chrome. Push it to the bottom. */
.cl-card__inner > .cl-card__footer {
  margin-top: auto;
}

/* Pulse / loop cards carry short content; the 4:5 shell leaves dead space
   under the footer. Let them size to their content instead. */
.card--pulse,
.card--loop {
  aspect-ratio: auto;
}
.card--pulse .card__inner,
.card--loop .card__inner {
  position: relative;
}

/* .crumb is display:inline-block and relies on a parent for placement; without
   one it pins to 0,0 underneath the pinned dock. This lane mirrors .stage's
   container (including the rail lane, which also clears the dock cluster). */
/* The lane is a flex row so the drill-out control sits on the crumb baseline.
   .crumb is inline-block, so it becomes a flex item without moving. */
.crumb-lane {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  max-width: 2100px;
  margin-inline: auto;
  padding: 24px 24px 0;
  padding-left: max(24px, var(--rail-lane));
}
/* Inverted twin of .crumb__home: same 36px square and 11px radius, but it
   reads as the way OUT rather than the way home, so it is outlined, not solid. */
.crumb-out {
  flex: none;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--ink-200);
  border-radius: 11px;
  background: var(--surface);
  color: var(--ink-600);
  cursor: pointer;
  transition:
    background var(--dur-base) var(--ease-smooth),
    border-color var(--dur-base) var(--ease-smooth),
    color var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.crumb-out:hover {
  border-color: var(--ink-400);
  color: var(--ink-900);
  background: var(--ink-50);
}
.crumb-out:active {
  transform: scale(0.94);
}
.crumb-out:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
@media (min-width: 1024px) {
  .crumb-lane {
    padding: 40px 40px 0;
    padding-left: max(40px, var(--rail-lane));
  }
}
@media (min-width: 1600px) {
  .crumb-lane {
    padding: 48px 48px 0;
    padding-left: max(48px, var(--rail-lane));
  }
}
.crumb-lane + .stage {
  padding-top: 20px;
}

/* Asset cards now carry a real page screenshot, so the "opens in new tab" tag
   needs a legible variant sitting over the image rather than on the flat field. */
.node-card__tag--over {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 4;
  margin-top: 0;
  padding: 5px 9px;
  border-radius: var(--radius-badge);
  line-height: 1;
  background: rgba(14, 23, 38, 0.72);
  color: #fff;
  border: 0;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

/* Child cards that carry a screenshot: .card__media is absolutely positioned, so
   the static footer both stacks at the top of the card AND gets painted over by
   the media. Push it to the bottom and give it its own stacking context. */
.card--node .card__inner > .card__footer {
  margin-top: auto;
  position: relative;
  z-index: 3;
}

/* ---- child cards that carry a real page capture ------------------------
   The home-card treatment (absolute media + signature white fade) washes a
   light screenshot out to nothing and pushes the footer out of the 4:5 shell.
   For these, the capture is a banded thumbnail and the footer sits in flow. */
.card--node.has-media {
  aspect-ratio: auto;
}
/* .card--node .card__inner is absolute+inset:0, which collapses the card to zero
   height once the aspect-ratio is released. Put it back in flow so the band +
   footer drive the height. */
.card--node.has-media .card__inner {
  position: static;
  inset: auto;
  display: flex;
  flex-direction: column;
  /* without this the inner stops at content height while the card stretches to
     the row, leaving 21px of dead white under every 1-line card's footer */
  height: 100%;
}
.card--node.has-media .card__media {
  position: relative;
  inset: auto;
  flex: none;
  /* aspect-driven, so the crop never severs a line of body type in the capture */
  aspect-ratio: 1400 / 875;
  height: auto;
  overflow: hidden;
  border-bottom: 1px solid var(--ink-100);
}
.card--node.has-media .card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  transition: transform var(--dur-rise) var(--ease-out-soft);
}
.card--node.has-media:hover .card__media img {
  transform: translateY(-6px) scale(calc(var(--hover-zoom) + 0.03));
}
/* the signature fade belongs to full-bleed hero cards, not to a thumbnail band */
.card--node.has-media .card__fade {
  display: none;
}
.card--node.has-media .card__footer {
  margin-top: 0;
  padding: 20px 22px 22px;
}
.node-card__tag--over[data-corner="br"] {
  top: auto;
  bottom: 14px;
  right: 14px;
}
@media (prefers-reduced-motion: reduce) {
  .card--node.has-media:hover .card__media img {
    transform: none;
  }
}

/* ============================================================
   ICON SPRITE — the one rule that makes every glyph an icon
   ------------------------------------------------------------
   The sprite is 24-unit LINE art (<line>, <polyline>, <circle>).
   Without this, a <use> inherits the SVG defaults fill:black /
   stroke:none, so every clipped path painted as a solid silhouette
   — the "icons are kind of hidden" the client reported. fill,
   stroke, stroke-width, stroke-linecap and stroke-linejoin are all
   inherited properties, so setting them on <use> reaches the
   referenced content. The sprite entries are <symbol viewBox="0 0
   24 24">, which also makes every glyph scale to its host <svg>
   box instead of drawing 1:1 from the origin (#i-play / #i-pause
   opt back into fill via their own presentation attributes).
   ============================================================ */
use {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ============================================================
   WAVE-1 REPAIRS — rules the markup now has structure for
   ============================================================ */

/* ---- Loops: running / paused / off must be distinguishable ----
   The two existing selectors keyed off a [data-status] attribute the
   template never set, so all six dots painted the same ink-300 and nothing
   on the card told a running loop from a dead one. */
.loop-card__statusdot.is-running {
  background: var(--ink-900);
}
.loop-card__statusdot.is-paused {
  background: var(--ink-400);
}
.loop-card__statusdot.is-off {
  background: var(--ink-300);
  box-shadow: inset 0 0 0 1px var(--ink-400);
}

/* Toggle: keep the 52x30 pill but sit it inside a 44px-tall hit target. */
.loop-card__togglewrap .switch {
  padding: 7px 0;
  height: calc(var(--sw-h) + 14px);
  background-clip: content-box;
}
.loop-card__togglewrap .switch__knob {
  top: calc(var(--sw-pad) + 7px);
}

/* ---- This Week / Briefing: a disabled play button must LOOK disabled ----
   11 of 15 pulses have no audio; their buttons were byte-identical to the
   enabled ones (same ink-950 fill, same shadow, cursor:pointer, and the
   hover rise still fired). */
.pulse-card__play:disabled,
.brief__play:disabled {
  background: var(--ink-100);
  color: var(--ink-400);
  box-shadow: none;
  cursor: default;
}
.pulse-card__play:disabled:hover,
.brief__play:disabled:hover {
  background: var(--ink-100);
  box-shadow: none;
}
@media (hover: hover) {
  .card--pulse:hover .pulse-card__play:disabled {
    transform: none;
  }
}

/* ---- This Week: headline claims as discrete lines ----
   Real headlines are 100-170 chars of pipe-delimited claims; one 2-line
   clamp cut them mid-token. */
.pulse-card__claims {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.pulse-card__claim {
  position: relative;
  padding-left: 13px;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-600);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.pulse-card__claim::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--ink-300);
}
/* keeps the foot row a constant height whether or not a "Read" link renders,
   so rows 4-5 stop stepping 14px shorter than rows 1-3 */
.card__footrow {
  min-height: 20px;
}

/* ---- Briefing: the What-Changed rail ---- */
.changed__bullet strong {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-900);
}
.changed__note {
  margin: 14px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--ink-100);
  font-size: 12.5px;
  line-height: 1.55;
  font-weight: 400;
  color: var(--ink-600);
}
/* nav labels are a list of things you can click, not the thing you're reading */
.brief3__nav .synth__label {
  margin-bottom: 12px;
}

/* ---- Content Library: select chevrons ---- */
.cl-select__chev {
  transform: rotate(90deg);
}

/* prev/next reuse the chevron; point them the way they move */
.cl-nav-btn--prev svg {
  transform: rotate(180deg);
}

/* Reject is destructive — read it as such (it is also off the R key now). */
.cl-pbtn--danger:hover {
  border-color: color-mix(in srgb, var(--alert) 45%, #ffffff);
  color: var(--alert);
  background: color-mix(in srgb, var(--alert) 6%, #ffffff);
}
.cl-pbtn--danger:hover svg {
  color: var(--alert);
}

/* ---- Preview modal composition ----
   In PREVIEW state head/mockup/metrics/foot are one column, so the wrap is
   the single scroll container; the mockup must not be squashed by the flex
   column (its caption and hashtags were laid out below their own parent box
   and clipped away entirely). */
.cl-edit__preview > * {
  flex: 0 0 auto;
}
.cl-preview:not(.is-editing) .cl-preview__wrap {
  overflow-y: auto;
  overscroll-behavior: contain;
}
.cl-preview:not(.is-editing) .cl-edit__preview {
  /* MUST be 0 0 auto: as a shrinkable flex child the stage collapsed to 244px
     while the mockup inside it stood 1026px tall, so the IG card painted
     straight over the metrics row and the canon gate. */
  flex: 0 0 auto;
  overflow: visible;
  border-right: 0;
  border-bottom: 1px solid var(--ink-100);
}
.cl-preview:not(.is-editing) .cl-preview__body {
  flex: 0 0 auto;
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}
/* EDIT state: grid children need min-height:0 or the live-preview stage
   overflows the modal floor instead of scrolling inside its pane. */
.cl-preview.is-editing .cl-preview__wrap > * {
  min-height: 0;
  max-height: 100%;
}
.cl-preview.is-editing .cl-edit__preview {
  overflow-y: auto;
}

/* ---- Content Library card: headline over the scrim ----
   57 near-identical gym photos with no title on any of them. */
.cl-card__footer--over .cl-card__title {
  text-wrap: balance;
  text-shadow: 0 1px 2px rgba(14, 23, 38, 0.5);
}
.cl-card__footer .cl-meta {
  margin-top: 9px;
}

/* ============================================================================
   MEDIA GALLERY — a section whose payload is the artwork
   (see index.html "GALLERY" + app.js loadGalleries)

   Two rules govern the whole thing:
     · on the GRID the creative is cropped to a common frame, because a grid of
       mixed aspect ratios reads as a bug rather than a catalogue;
     · in the LIGHTBOX it is never cropped, because that is the moment the
       reader asked to see the actual thing.
   The frame's ratio is data — --gal-ratio comes off the gallery definition, so
   a square ad wall and a 4:5 social wall share one stylesheet.
   ========================================================================= */
.gal {
  max-width: 2100px;
  margin-inline: auto;
  padding: 8px 24px 24px;
  padding-left: max(24px, var(--rail-lane));
}
@media (min-width: 1024px) {
  .gal {
    padding: 8px 40px 40px;
    padding-left: max(40px, var(--rail-lane));
  }
}
@media (min-width: 1600px) {
  .gal {
    padding: 8px 48px 48px;
    padding-left: max(48px, var(--rail-lane));
  }
}
.gal__bar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}
/* the filter row already carries the app's bottom rhythm; the count rides it */
.gal__bar .pilltags {
  margin-bottom: 20px;
}
.gal__count {
  margin: 8px 0 20px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.gal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 22px;
}
@media (max-width: 480px) {
  .gal-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 14px;
  }
}
.gal-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-image);
  background: var(--surface);
  border: 1px solid var(--ink-200);
  overflow: hidden;
  transition:
    border-color var(--dur-base) var(--ease-smooth),
    box-shadow var(--dur-base) var(--ease-smooth),
    transform var(--dur-base) var(--ease-out-soft);
}
.gal-card:hover {
  border-color: var(--ink-300);
  box-shadow: 0 10px 30px rgba(16, 42, 72, 0.12);
  transform: translateY(-2px);
}
.gal-card:has(.gal-card__stretch:focus-visible) {
  border-color: var(--ink-950);
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
.gal-card__media,
.gal-card__field {
  position: relative;
  aspect-ratio: var(--gal-ratio, 1 / 1);
  background: var(--ink-100);
  overflow: hidden;
}
.gal-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--dur-slow, 420ms) var(--ease-out-soft);
}
.gal-card:hover .gal-card__media img {
  transform: scale(1.03);
}
@media (prefers-reduced-motion: reduce) {
  .gal-card:hover {
    transform: none;
  }
  .gal-card:hover .gal-card__media img {
    transform: none;
  }
}
.gal-card__chip {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 4px 9px;
  border-radius: var(--radius-pill);
  background: rgba(14, 23, 38, 0.72);
  color: #ffffff;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.gal-card__chip--flat {
  position: static;
  align-self: flex-start;
  background: var(--ink-950);
}
.gal-card__frames {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: var(--radius-pill);
  background: rgba(14, 23, 38, 0.72);
  color: #ffffff;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.gal-card__frames svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
/* art pending: the copy is real, so it is typeset — not an error message */
.gal-card__field {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
  padding: 16px;
  background: linear-gradient(160deg, var(--ink-100), var(--ink-50));
}
.gal-card__pendline {
  margin: 0;
  font-size: 16px;
  line-height: 1.3;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--ink-900);
  text-wrap: pretty;
}
.gal-card__pendtag {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.gal-card__foot {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 13px 15px 15px;
}
.gal-card__title {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.32;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink-900);
  text-wrap: pretty;
  /* the headline, not the whole ad — the lightbox holds the rest */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.gal-card__note {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-600);
  /* a format note can run to a full sentence in some packs; two lines is the
     most a card face can carry before it stops being a caption */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.gal-card__stretch {
  position: absolute;
  inset: 0;
  z-index: 3;
  border: 0;
  background: transparent;
  cursor: pointer;
  font: inherit;
  color: transparent;
}
.gal-card__stretch:focus-visible {
  outline: none;
}

/* ---- lightbox ---------------------------------------------------------- */
/* the Walk-and-Talk backdrop values, deliberately: this is the same "the page
   steps back and one thing is in front of you" moment Chase referenced */
.gal-backdrop {
  align-items: center;
  padding: 4vh 20px;
  background: rgba(16, 42, 72, 0.34);
  -webkit-backdrop-filter: blur(16px) saturate(0.9);
  backdrop-filter: blur(16px) saturate(0.9);
  z-index: 112;
}
@media (prefers-reduced-motion: reduce) {
  .gal-backdrop {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
  }
}
.gal-light {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1120px;
  max-height: 92vh;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-card);
  box-shadow:
    0 8px 24px rgba(16, 42, 72, 0.12),
    0 30px 60px rgba(16, 42, 72, 0.24);
  overflow: hidden;
}
.gal-light__head {
  flex: none;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 22px 26px 16px;
  border-bottom: 1px solid var(--ink-100);
}
.gal-light__headmain {
  min-width: 0;
}
.gal-light__eyebrow {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.gal-light__title {
  margin: 8px 0 0;
  font-size: 20px;
  line-height: 1.28;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-900);
  text-wrap: pretty;
}
/* grid with one definite row, not a plain block: a flex item's height is used,
   not computed, so `height:100%` on the wrap fell back to auto and the creative
   sized the panel instead of the other way round. */
.gal-light__body {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  display: grid;
  grid-template-rows: minmax(0, 1fr);
}
.gal-light__wrap {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  /* the implicit row would otherwise be `auto` — sized by the tallest child,
     which is exactly the creative we are trying to constrain */
  grid-template-rows: minmax(0, 1fr);
  min-height: 0;
}
/* one column below 860: the creative takes a natural share of the viewport and
   the copy scrolls under it, rather than both halves fighting for 50%. */
@media (max-width: 860px) {
  .gal-light__wrap {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto;
    overflow-y: auto;
  }
  .gal-light__stage {
    border-right: 0;
    border-bottom: 1px solid var(--ink-200);
  }
  .gal-light__art {
    height: auto;
    max-height: 46vh;
  }
  .gal-light__panel {
    overflow: visible;
  }
}
/* grid, not flex: a replaced element in a flex column resolves its height from
   its own intrinsic ratio first, so a portrait creative overflowed the stage
   and got clipped at the bottom. minmax(0,1fr) makes the track authoritative. */
.gal-light__stage {
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
  margin: 0;
  min-height: 0;
  background: var(--ink-100);
  border-right: 1px solid var(--ink-100);
}
.gal-light__art {
  min-width: 0;
  min-height: 0;
  width: 100%;
  height: 100%;
  /* contain, not cover: the reader opened this to see the whole creative */
  object-fit: contain;
  padding: 18px;
  display: block;
}
.gal-slides {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-top: 1px solid var(--ink-200);
  background: var(--surface);
}
.gal-slides__text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: center;
}
.gal-slides__pos {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.gal-slides__copy {
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink-800);
  text-wrap: pretty;
}
.gal-light__panel {
  min-height: 0;
  overflow-y: auto;
  padding: 22px 26px 26px;
}
.gal-light__panel:focus-visible {
  outline: 2px solid var(--ink-950);
  outline-offset: -3px;
}
.gal-light__byline {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.gal-light__body-copy {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-800);
  white-space: pre-wrap;
  text-wrap: pretty;
}
.gal-light__tags {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-600);
  word-break: break-word;
}
.gal-light__cta {
  margin: 18px 0 0;
}
.gal-light__ctabtn {
  display: inline-flex;
  align-items: center;
  height: 34px;
  padding: 0 16px;
  border-radius: var(--radius-button);
  background: var(--ink-950);
  color: #ffffff;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
}
.gal-light__meta {
  margin: 20px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--ink-100);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.gal-light__metarow {
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.gal-light__metarow dt {
  flex: none;
  width: 108px;
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}
.gal-light__metarow dd {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-800);
}
/* the organic-post variant of the CTA: direction to the publisher, set as a
   labelled note rather than a button that does not exist */
.gal-light__ctanote {
  margin: 18px 0 0;
  padding: 12px 14px;
  border-radius: var(--radius-button);
  background: var(--ink-50);
  border: 1px solid var(--ink-100);
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-800);
  text-wrap: pretty;
}
.gal-light__ctakicker {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-600);
}

/* ============================================================
   STRATEGY — the day-one layer

   A strategy doc is not a finished asset, and the design says so before a
   word is read: these cards are the only black surfaces in a light,
   monochrome shell. Three levels, no modals — card → section grid →
   reading page — because strategy is read, not previewed.
   ============================================================ */

/* ---- the black card: the doc on home, and each section inside it ---- */
.card--strategy {
  aspect-ratio: 4 / 5;
  background: var(--ink-950);
}
.card--strategy .card__inner {
  display: flex;
  flex-direction: column;
  position: absolute;
  inset: 0;
}
.card--strategy::after {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
@media (hover: hover) {
  .card--strategy:hover {
    background: #060b14;
  }
}

/* the doc card's face: one large, centred audio-bars glyph. There is no
   capture to show and a stock image would be a lie, so the card carries the
   one mark the whole strategy layer is organised around. */
.strat-card__field {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 26px;
  background: radial-gradient(
    130% 90% at 16% -8%,
    rgba(255, 255, 255, 0.06) 0%,
    rgba(255, 255, 255, 0) 56%
  );
}
.strat-card__glyph {
  height: 60px;
  gap: 9px;
  color: rgba(255, 255, 255, 0.88);
  transform-origin: center bottom;
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    color var(--dur-base) var(--ease-smooth);
}
/* STATIC at rest. Thirty of these will sit on a landing page; the shared
   .wt-levels idle loop would turn the whole screen into an equaliser. A fixed
   silhouette instead, and the only motion is a small extension on hover. */
.strat-card__glyph i {
  width: 7px;
  border-radius: 4px;
  animation: none;
}
.strat-card__glyph i:nth-child(1) {
  transform: scaleY(0.5);
}
.strat-card__glyph i:nth-child(2) {
  transform: scaleY(0.82);
}
.strat-card__glyph i:nth-child(3) {
  transform: scaleY(0.62);
}
.strat-card__glyph i:nth-child(4) {
  transform: scaleY(1);
}
@media (hover: hover) {
  .card--strategy:hover .strat-card__glyph {
    transform: scaleY(1.14);
    color: #ffffff;
  }
}

/* the shared footer, inverted */
.card__footer--strategy {
  position: relative;
  z-index: 3;
  padding: 22px 26px 28px;
  background: var(--ink-950);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.card--strategy:hover .card__footer--strategy {
  background: #060b14;
}
.card__footer--strategy .eyebrow {
  display: none;
}
.card__footer--strategy .card__title--display {
  color: #ffffff;
}
.card__footer--strategy .card__subtitle {
  color: rgba(255, 255, 255, 0.56);
}
.card__footer--strategy .card__count-meta {
  display: none;
}
.card__footer--strategy .card__link {
  margin-top: 18px;
  color: rgba(255, 255, 255, 0.82);
}
@media (hover: hover) {
  .card--strategy:hover .card__footer--strategy .card__link {
    color: #ffffff;
  }
  .card--strategy:hover .card__footer--strategy .card__link .arrow {
    transform: translateX(4px);
  }
}

/* ---- the section card: its own opening sentence, at reading size ---- */
/* display:block, NOT flex. A flex item's display is blockified, which turns
   the paragraph's -webkit-box into a plain block and silently kills the
   line-clamp below — openings then ran eight lines and out through the
   footer. Keep the field a plain block and let the clamp do its job. */
.strat-sec__field {
  flex: 1 1 auto;
  min-height: 0;
  display: block;
  overflow: hidden;
  padding: 34px 30px 20px;
}
.strat-sec__opening {
  margin: 0;
  font-size: 30px;
  line-height: 1.22;
  font-weight: 550;
  letter-spacing: -0.021em;
  color: rgba(255, 255, 255, 0.95);
  text-wrap: pretty;
  /* an opening can carry a file path or a URL from the source document; without
     this it runs off the right edge instead of breaking */
  overflow-wrap: anywhere;
  /* openings run from four words to twenty-five; the long ones clamp rather
     than shrink, so every card in the grid keeps one type size */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 6;
  overflow: hidden;
  transition: color var(--dur-base) var(--ease-smooth);
}
@media (hover: hover) {
  .card--strategy-section:hover .strat-sec__opening {
    color: #ffffff;
  }
}
/* bottom of the card is the title and nothing else — no number, no verb */
.card--strategy-section .card__footer--strategy {
  padding-bottom: 34px;
}
.card--strategy-section .card__title--display {
  font-size: 17.5px;
  -webkit-line-clamp: 3;
}
.card--strategy-section .card__footrow {
  display: none;
}

/* ---- in-development placeholders ("Build some examples") ----
   Dashed and inert on purpose: it must be obvious at a glance that these are
   an intent, not an artefact. */
/* A real dashed edge, not a hairline: an outline (which follows the 48px
   radius) rather than the shared ::after ring, so the card reads as unbuilt
   from across the grid and not just up close. */
.card--dev {
  aspect-ratio: 4 / 5;
  background: var(--ink-50);
  box-shadow: none;
  cursor: default;
  outline: 1.5px dashed var(--ink-300);
  outline-offset: -2px;
}
.card--dev::after {
  box-shadow: none;
}
.card--dev:hover {
  transform: none;
  box-shadow: none;
}
.card--dev .card__inner {
  display: flex;
  flex-direction: column;
  position: absolute;
  inset: 0;
}
.dev-card__field {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 26px 28px 12px;
}
.dev-card__flag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-500);
}
.dev-card__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-400);
  animation: dev-pulse 2s var(--ease-smooth) infinite;
}
@keyframes dev-pulse {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 1;
  }
}
.dev-card__bars {
  display: inline-flex;
  align-items: flex-end;
  gap: 3px;
  height: 16px;
}
.dev-card__bars i {
  display: block;
  width: 4px;
  height: 100%;
  border-radius: 2px;
  background: var(--ink-300);
  transform-origin: center bottom;
  transform: scaleY(0.4);
  animation: dev-build 1.5s var(--ease-smooth) infinite;
}
.dev-card__bars i:nth-child(2) {
  animation-delay: 0.25s;
}
.dev-card__bars i:nth-child(3) {
  animation-delay: 0.5s;
}
@keyframes dev-build {
  0%,
  100% {
    transform: scaleY(0.4);
  }
  50% {
    transform: scaleY(1);
  }
}
.dev-card__bars--btn {
  height: 13px;
}
.dev-card__bars--btn i {
  background: rgba(255, 255, 255, 0.8);
}
.card__footer--dev {
  position: relative;
  z-index: 3;
  padding: 20px 28px 28px;
  border-top: 1px dashed var(--ink-200);
  background: transparent;
}
.card__footer--dev .eyebrow {
  color: var(--ink-400);
}
.card__footer--dev .card__title--display {
  color: var(--ink-700);
}
.card__footer--dev .card__subtitle {
  color: var(--ink-500);
}

/* ============================================================
   STRATEGY — the section reading page (no modal, by contract)
   ============================================================ */
.strat-page {
  max-width: 740px;
  margin-inline: auto;
}

/* ---- audio + build: the two things you can DO with a section ----
   The play button is deliberately oversized. Most people open a section to
   listen, not to read 4,000 words, and the control that serves them should
   not be a 24px pill in a corner. */
.strat-player {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 84px 0 44px;
  padding: 18px 20px 18px 22px;
  background: var(--surface);
  border: 1px solid var(--ink-200);
  border-radius: 26px;
  box-shadow: var(--shadow-card-rest);
}
.strat-player__play {
  flex: none;
  width: 62px;
  height: 62px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--ink-950);
  color: #ffffff;
  cursor: pointer;
  box-shadow:
    0 2px 8px rgba(14, 23, 38, 0.2),
    0 12px 28px rgba(14, 23, 38, 0.22);
  transition:
    transform var(--dur-base) var(--ease-out-soft),
    background var(--dur-base) var(--ease-smooth);
}
.strat-player__play svg {
  fill: currentColor;
  stroke: none;
  margin-left: 2px;
}
.strat-player__play.is-playing svg {
  margin-left: 0;
}
.strat-player__play:hover {
  background: #060b14;
  transform: scale(1.05);
}
.strat-player__play:active {
  transform: scale(0.97);
  transition-duration: var(--dur-fast);
}
.strat-player__play:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 3px var(--surface),
    0 0 0 6px var(--ink-950);
}
.strat-player__play[disabled] {
  background: var(--ink-200);
  color: var(--ink-500);
  cursor: not-allowed;
  box-shadow: none;
}
/* basis 0, not auto: with an auto basis the provenance chip's own width is the
   column's preferred width, which on a phone pushed the whole meta block onto
   its own line and left the play button sitting alone in a white field */
.strat-player__meta {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.strat-player__meta .eyebrow {
  margin: 0;
}
.strat-player__dur {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--ink-600);
}
.strat-player__dur .wt-levels {
  color: var(--ink-800);
}

/* ---- audio provenance ----
   Five of the seven summaries in this prototype are borrowed from another
   client to convey the format. Anyone who believed that was their own
   strategy being read back to them would have been misled by us, so the fact
   is stated in the one place it matters — beside the play button — in a mark
   that reads as a label, not as an error. The hatched swatch is the same
   "this is a stand-in" language the dev cards use. */
.strat-standin {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 5px 0 0;
  padding: 4px 10px 4px 6px;
  align-self: flex-start;
  border: 1px solid var(--ink-200);
  border-radius: 9999px;
  background: var(--ink-50);
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1.35;
  letter-spacing: 0.02em;
  color: var(--ink-600);
  text-wrap: pretty;
}
.strat-standin__swatch {
  flex: none;
  width: 14px;
  height: 14px;
  border-radius: 4px;
  background: repeating-linear-gradient(
    -45deg,
    var(--ink-300),
    var(--ink-300) 2px,
    var(--ink-100) 2px,
    var(--ink-100) 5px
  );
}

/* ---- "Build some examples" — the primary action, and a promise we do NOT
   make. It changes to an underway state and reveals dashed placeholders one
   level up; nothing is requested and nothing is produced. ---- */
.strat-build {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 52px;
  padding: 0 26px;
  border: 0;
  border-radius: 9999px;
  background: var(--ink-950);
  color: #ffffff;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  box-shadow:
    0 1px 2px rgba(14, 23, 38, 0.18),
    0 8px 22px rgba(14, 23, 38, 0.18);
  transition:
    background var(--dur-base) var(--ease-smooth),
    transform var(--dur-fast) var(--ease-press);
}
.strat-build:hover {
  background: #060b14;
}
.strat-build:active {
  transform: scale(0.98);
}
.strat-build:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--ink-950);
}
.strat-build.is-building {
  background: var(--ink-800);
}

/* ---- the reading column ---- */
.strat-doc {
  padding-bottom: 40px;
}
.strat-doc__kicker {
  margin: 0 0 14px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  /* --ink-500 is 4.19:1 on --page-bg — below 4.5:1, and this is 11.5px text so
     the large-text exemption does not apply. --ink-600 is the documented floor
     for body/meta on this background (1.4.3). */
  color: var(--ink-600);
}
/* the thesis is the section, compressed — set large enough that a reader who
   only reads this line has still read something true */
.strat-doc__thesis {
  margin: 0;
  font-size: 33px;
  line-height: 1.2;
  font-weight: 550;
  letter-spacing: -0.024em;
  color: var(--ink-950);
  text-wrap: pretty;
}
.strat-block {
  margin-top: 24px;
}
.strat-h {
  margin: 0;
  padding-top: 14px;
  font-size: 19px;
  line-height: 1.25;
  font-weight: 650;
  letter-spacing: -0.018em;
  color: var(--ink-950);
}
.strat-prose {
  margin: 0;
  font-size: 16px;
  line-height: 1.66;
  font-weight: 450;
  color: var(--ink-700);
  text-wrap: pretty;
}
.strat-prose strong,
.strat-cc__b strong,
.strat-callout__b strong {
  font-weight: 650;
  color: var(--ink-900);
}
.strat-prose em {
  font-style: italic;
}
.strat-prose code,
.strat-cc__b code,
.strat-callout__b code,
.strat-table code {
  padding: 1px 5px;
  border-radius: 6px;
  background: var(--ink-50);
  font-family: var(--font-mono);
  font-size: 0.88em;
  color: var(--ink-800);
}
.strat-pull {
  margin: 0;
  padding-left: 18px;
  border-left: 2px solid var(--ink-950);
  font-size: 21px;
  line-height: 1.34;
  font-weight: 550;
  letter-spacing: -0.017em;
  color: var(--ink-900);
  text-wrap: pretty;
}

/* stat — a standout figure, given the room a figure needs */
.strat-stat {
  padding: 28px 30px;
  border-radius: 26px;
  background: var(--ink-950);
  color: #ffffff;
}
.strat-stat__fig {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.strat-stat__value {
  font-size: 46px;
  line-height: 1;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.strat-stat__unit {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.66);
}
.strat-stat__note {
  margin: 14px 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.8);
}

/* table — client financials; they scroll, they never wrap into nonsense */
.strat-tablewrap {
  overflow-x: auto;
  border: 1px solid var(--ink-200);
  border-radius: 20px;
  /* the stage is grey; without this the body rows read as a hole in the page
     rather than as a table */
  background: var(--surface);
}
.strat-tablewrap:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--ink-950);
}
.strat-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
.strat-table th {
  padding: 13px 16px;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  /* --ink-500 on --ink-50 measured 4.47:1 — a rounding error short of 4.5:1,
     across every table in the pack. These are the column keys for the client's
     financials; if any text has to be legible, it is this (1.4.3). */
  color: var(--ink-600);
  background: var(--ink-50);
  border-bottom: 1px solid var(--ink-200);
  white-space: nowrap;
}
.strat-table td {
  padding: 13px 16px;
  line-height: 1.5;
  color: var(--ink-700);
  border-bottom: 1px solid var(--ink-100);
  vertical-align: top;
}
.strat-table tbody tr:last-child td {
  border-bottom: 0;
}
.strat-table td:first-child {
  font-weight: 600;
  color: var(--ink-900);
}

/* content-cards — a bullet list that stopped pretending to be a bullet list */
.strat-cards {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.strat-cc {
  padding: 15px 18px;
  border: 1px solid var(--ink-100);
  border-radius: 18px;
  background: var(--surface);
}
.strat-cc__h {
  margin: 0 0 5px;
  font-size: 15.5px;
  line-height: 1.3;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--ink-900);
}
.strat-cc__b {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.58;
  color: var(--ink-600);
}

/* callout-cards — named things: people, tiers, options */
.strat-callouts {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
@media (min-width: 720px) {
  .strat-callouts {
    grid-template-columns: 1fr 1fr;
  }
}
.strat-callout {
  padding: 18px 20px;
  border: 1px solid var(--ink-200);
  border-radius: 20px;
  background: var(--surface);
}
.strat-callout__name {
  margin: 0 0 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ink-100);
  font-size: 16px;
  font-weight: 650;
  letter-spacing: -0.015em;
  color: var(--ink-950);
}
.strat-callout__b {
  margin: 0;
  font-size: 14px;
  line-height: 1.56;
  color: var(--ink-600);
}

/* verdict — run / skip. The one place --alert is sanctioned. */
.strat-verdict {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
@media (min-width: 720px) {
  .strat-verdict {
    flex-direction: row;
    align-items: flex-start;
  }
  .strat-verdict__col {
    flex: 1 1 0;
  }
}
.strat-verdict__col {
  padding: 18px 20px;
  border: 1px solid var(--ink-200);
  border-radius: 20px;
  background: var(--surface);
}
.strat-verdict__col--skip {
  border-color: color-mix(in srgb, var(--alert) 32%, var(--ink-200));
  background: color-mix(in srgb, var(--alert) 5%, var(--surface));
}
.strat-verdict__lab {
  margin: 0 0 12px;
}
.strat-badge {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 9999px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.strat-badge--run {
  background: var(--ink-950);
  color: #ffffff;
}
.strat-badge--skip {
  background: var(--alert);
  color: var(--alert-ink);
}
.strat-verdict__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.strat-verdict__list li {
  position: relative;
  padding-left: 16px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-700);
}
.strat-verdict__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 9px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-950);
}
.strat-verdict__col--skip .strat-verdict__list li::before {
  background: var(--alert);
}

/* letter — quoted copy is the artefact, not the argument */
.strat-letter {
  margin: 0;
}
.strat-letter__from {
  margin: 0 0 12px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-400);
}
.strat-letter__sheet {
  padding: 34px 38px;
  border-radius: 22px;
  border: 1px solid var(--ink-200);
  background: var(--surface);
  font-family: var(--font-serif, Georgia, "Times New Roman", serif);
}
.strat-letter__sheet p {
  margin: 0 0 16px;
  font-size: 16px;
  line-height: 2;
  color: var(--ink-800);
}
.strat-letter__sheet p:last-child {
  margin-bottom: 0;
}

/* ---- breadcrumb siblings ---- */
.crumb__sibs {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--ink-100);
}
.crumb__row--sib .crumb__rowlabel {
  font-size: 13px;
}
/* an invisible bridge across the bar↔menu gap, so travelling to a sibling
   never leaves the hover target (the 260ms delay covers the rest) */
.crumb__menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -10px;
  height: 10px;
}

/* ---- narrow viewports ---- */
/* Below 480 the rail lane collapses to 0, so the breadcrumb starts at the
   page gutter — directly underneath the fixed dock (x 16–60). A three-level
   strategy path wraps to three lines there and the first of them sat behind
   the Walk & Talk orb. Reserve the dock's column instead of its whole height,
   so the trail clears it without being pushed 120px down the page. */
@media (max-width: 480px) {
  .crumb-lane {
    padding-left: 72px;
  }
}
@media (max-width: 720px) {
  .strat-player {
    flex-wrap: wrap;
    margin-top: 40px;
    padding: 16px;
    border-radius: 22px;
  }
  .strat-build {
    width: 100%;
    justify-content: center;
  }
  .strat-doc__thesis {
    font-size: 26px;
  }
  .strat-sec__opening {
    font-size: 24px;
    -webkit-line-clamp: 5;
  }
  .strat-letter__sheet {
    padding: 24px 22px;
  }
}

/* ---- reduced motion: the strategy surfaces hold still ---- */
@media (prefers-reduced-motion: reduce) {
  .card--strategy:hover .strat-card__glyph {
    transform: none;
  }
  .strat-player__play:hover {
    transform: none;
  }
  .dev-card__dot,
  .dev-card__bars i {
    animation: none;
  }
  .dev-card__bars i {
    transform: scaleY(0.7);
  }
}
