/* ============================================================
   STSL CASE STUDY — STYLE
   Inherits portfolio tokens. Vanilla CSS. No frameworks.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  overscroll-behavior-y: none;
}
body {
  background: var(--bg);
  overscroll-behavior-y: none;
  color: var(--text);
  font-family: var(--font-sans);
  font-weight: 300;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, video { display: block; max-width: 100%; height: auto; }
button { cursor: pointer; border: none; background: none; font-family: inherit; }
a { text-decoration: none; color: inherit; }
ul { list-style: none; }

/* ============================================================
   TOKENS (mirrored from Portfolio/style.css + article extensions)
   ============================================================ */
:root {
  /* ── Brand palette (single source of truth) ── */
  --color-white:    #FFFFFF;
  --color-yellow:   #FFC919;
  --color-midnight: #14141A;
  --color-red:      #E40202;
  --color-purple:   #9B91F6;

  /* portfolio core */
  /* Page bg is pure black (was #14141A, a navy-tinted near-black). The
     midnight token still drives accent surfaces (toggle text on yellow,
     chapter type colour) but the canvas itself reads as black. */
  --bg:           #000000;
  --bg-card:      #1e1e1e;
  --bg-btn:       #464646;
  --bg-btn-light: #f1f1f4;
  --accent:       var(--color-red);
  --text:         var(--color-white);
  --text-dark:    var(--color-midnight);
  --text-muted:   rgba(255,255,255,0.5);

  /* article extensions — DARK theme (article sits on page bg) */
  --bg-light:     transparent;
  --bg-light-2:   rgba(255,255,255,0.05);
  --rule-light:   rgba(255,255,255,0.10);
  --rule-dark:    rgba(255,255,255,0.10);
  --text-light:   #f4f0e6;
  --text-light-muted: rgba(244,240,230,0.55);


  --font-sans:    'DM Sans', sans-serif;
  --font-script:  'Carattere', cursive;
  /* Deprecated aliases — keep so legacy selectors resolve to portfolio brand */
  --font-serif:   var(--font-sans);
  --font-mono:    var(--font-sans);
  --bg-cream:     var(--bg-light);
  --bg-cream-2:   var(--bg-light-2);
  --text-cream:   var(--text-light);
  --text-cream-muted: var(--text-light-muted);
  --rule-cream:   var(--rule-light);

  /* 12-col article grid */
  --grid-cols:    12;
  --grid-gap:     clamp(8px, 1.2vw, 18px);
  --grid-max:     1320px;

  --ease-expo: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Radius scale — 5 tokens replacing 23 ad-hoc values across the page.
     --r-sharp: tight UI edges (gauge well, segment corners)
     --r-card:  small interior cards (token-snippet, day-cost, ledger)
     --r-bento: mid bento (ratio-block, paper bento, prompts)
     --r-frame: large frames (bleed-shot, demo-card, side-frame, mockups)
     --r-pill:  fully rounded (badges, day-rail, scrollbars, buttons) */
  --r-sharp:  4px;
  --r-card:   clamp(10px, 1vw, 14px);
  --r-bento:  clamp(14px, 1.3vw, 18px);
  --r-frame:  clamp(18px, 1.7vw, 24px);
  --r-pill:   999px;

  --page-x:  clamp(20px, 4.2vw, 56px);
  --col:     min(720px, 100%);

  /* portfolio scale tokens (needed for transplanted profile component) */
  --fw-extralight: 200;
  --fw-light:     300;
  --fw-regular:   400;
  --fw-medium:    500;

  --text-xs:   clamp(0.58rem, 0.68vw, 0.65rem);
  --text-sm:   clamp(0.68rem, 0.82vw, 0.78rem);
  --text-base: clamp(0.8rem,  1vw,    0.95rem);
  --text-md:   clamp(0.9rem,  1.2vw,  1.1rem);
  --text-lg:   clamp(1rem,    1.5vw,  1.4rem);
  --text-xl:   clamp(1.15rem, 2vw,    1.75rem);

  --sp-1: clamp(2px,  0.3vh,  4px);
  --sp-2: clamp(4px,  0.55vh, 7px);
  --sp-3: clamp(6px,  0.85vh, 10px);
  --sp-4: clamp(8px,  1.2vh,  14px);
  --sp-5: clamp(12px, 1.7vh,  20px);
  --sp-6: clamp(16px, 2.4vh,  28px);
  --sp-8: clamp(22px, 3.2vh,  42px);
}

/* ============================================================
   COVER (Figma node 5826:10775)
   ============================================================ */
.cover {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  height: 100vh;
  height: 100dvh;
  background: var(--bg);
  overflow: hidden;
  isolation: isolate;
}
/* Smooth handoff into the article body: the bottom of the hero fades
   from the live ripple canvas into the page bg so there's no hard edge
   where the cover ends and the overview begins. Sits above the mockup
   (z=1) but below cover-title (z=2) and cover-profile (z=3) so the
   foreground content stays untouched. */
.cover::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 32%;
  background: linear-gradient(to bottom,
    rgba(0, 0, 0, 0)    0%,
    rgba(0, 0, 0, 0.55) 55%,
    #000                100%
  );
  pointer-events: none;
  z-index: 1;
}
/* Three.js liquid-ripple canvas — sits BEHIND the hero image so its
   mouse-driven ripple FX reads through the semi-transparent mockup. */
.cover #bg-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  display: block;
  opacity: 1;
}

/* ── Profile sidebar (transplanted from main portfolio).
   top/left match homepage's --page-y / --page-x exactly so the
   profile sits at the identical pixel position from the viewport. */
.cover-profile {
  position: absolute;
  z-index: 3;
  top: clamp(16px, 2.8vh, 48px);
  left: clamp(28px, 3.8vw, 68px);
  width: min(440px, 80vw);
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
}

/* — profile-card (avatar + meta) — */
.profile-card {
  display: flex;
  align-items: stretch;
  gap: var(--sp-4);
}
.avatar-wrap {
  flex-shrink: 0;
  width:  clamp(72px, 8vw, 130px);
  height: clamp(72px, 8vw, 130px);
  border-radius: 50%;
  overflow: hidden;
  background: #e9e9e9;
}
.avatar { width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.profile-meta {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-1) 0;
}
.profile-meta .social-icons { margin-top: auto; }
.profile-name {
  font-family: var(--font-sans);
  font-weight: var(--fw-light);
  font-size: var(--text-lg);
  line-height: 1.1;
  white-space: nowrap;
  color: var(--text);
}
.experience-badge {
  font-family: var(--font-sans);
  font-weight: var(--fw-light);
  font-size: var(--text-base);
  color: var(--text-muted);
  line-height: 1.2;
}

/* — availability badge — */
.avail-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--font-sans);
  font-weight: var(--fw-light);
  font-size: var(--text-base);
  color: var(--text-muted);
  letter-spacing: 0.02em;
}
.avail-dot {
  position: relative;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #22c55e;
  flex-shrink: 0;
  box-shadow: 0 0 6px rgba(34, 197, 94, 0.6);
}
.avail-dot::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.2);
  animation: pulse-ring 2.2s ease-out infinite;
}
.avail-dot::after {
  content: '';
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  background: rgba(34, 197, 94, 0.08);
  animation: pulse-ring 2.2s ease-out 0.4s infinite;
}
@keyframes pulse-ring {
  0%   { transform: scale(0.5); opacity: 1; }
  80%  { transform: scale(1);   opacity: 0; }
  100% { transform: scale(1);   opacity: 0; }
}

/* — social icons — */
.social-icons {
  display: flex;
  align-items: center;
  gap: clamp(8px, 0.9vw, 14px);
}
.social-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width:  clamp(16px, 1.4vw, 22px);
  height: clamp(16px, 1.4vw, 22px);
  flex-shrink: 0;
  transition: transform 0.35s var(--ease-back), opacity 0.3s var(--ease-expo);
  opacity: 0.55;
  color: var(--text);
}
.social-icon img {
  width: 100%; height: 100%;
  object-fit: contain; display: block;
  filter: brightness(0) invert(1);
}
.social-icon svg {
  width: 100%; height: 100%; display: block;
  color: inherit;
}
.social-icon:hover  { opacity: 1; transform: translateY(-4px) scale(1.18); }
.social-icon:active { transform: scale(0.92); }
.social-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

/* — profile-bottom (CTA + tools) — */
.profile-bottom {
  display: flex;
  flex-direction: column;
  width: fit-content;
  gap: var(--sp-4);
}
.cta-group { display: flex; width: 100%; }
.btn-pill-group {
  display: flex;
  align-items: center;
  gap: 5px;
  width: 100%;
}
.btn-pill {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(5px, 0.5vw, 9px);
  height: clamp(36px, 3.2vh, 47px);
  border-radius: var(--r-pill);
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  font-size: var(--text-base);
  letter-spacing: 0.006em;
  white-space: nowrap;
  overflow: hidden;
  outline: none;
  border: none;
  cursor: pointer;
  min-width: max-content;
  transition: transform 0.25s var(--ease-expo), background 0.25s var(--ease-expo);
}
.btn-pill:hover { transform: translateY(-1px); }
.btn-pill:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-pill--contact {
  background: var(--bg-btn-light);
  color: var(--text-dark);
  flex: 3 1 0;
  padding: 0 clamp(12px, 1.2vw, 18px);
}
.btn-pill--resume {
  background: #707070;
  color: #ffffff;
  flex: 1 1 0;
  padding: 0 clamp(12px, 1.2vw, 18px);
}
.btn-pill-arrow { font-size: 0.88em; flex-shrink: 0; }

/* — tools bar — */
.tools-bar {
  display: flex;
  align-items: center;
  gap: clamp(5px, 0.7vw, 12px);
  background: rgba(70,70,70,0.84);
  padding: clamp(6px, 0.7vh, 10px) clamp(10px, 1.2vw, 18px);
  border-radius: 20px;
  box-shadow: inset 0 0 5px rgba(255,255,255,0.22);
  width: fit-content;
}
.tool-wrap {
  width:  clamp(24px, 2.2vw, 32px);
  height: clamp(24px, 2.2vw, 32px);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #3c3c3c;
  border: 0.5px solid rgba(255, 255, 255, 0.2);
  border-radius: 10px;
  overflow: hidden;
  position: relative;
  transition: transform 0.32s var(--ease-back), border-color 0.32s ease, box-shadow 0.32s ease;
}
.tool-wrap:hover {
  border-color: rgba(255,255,255,0.5);
  transform: translateY(-5px) scale(1.14);
  box-shadow: 0 8px 20px rgba(0,0,0,0.4);
}
.tool-icon {
  width: 100%; height: 100%;
  object-fit: contain; display: block;
  filter: grayscale(1) brightness(1.5) opacity(0.65);
  transition: filter 0.32s var(--ease-expo);
}
.tool-icon--svg {
  width: 55%; height: 55%;
  color: rgba(255,255,255,0.65);
  filter: none;
  transition: color 0.32s var(--ease-expo);
}
.tool-icon--padded { width: 70%; height: 70%; }
.tool-wrap:hover .tool-icon      { filter: none; }
.tool-wrap:hover .tool-icon--svg { color: #fff; }

/* ── Layered hero composition (full backdrop) ─────────────── */
.cover-mockup {
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.cover-mockup img {
  position: absolute;
  inset: auto 0 -110px 0;
  width: 100%;
  height: auto;
  transform: scale(1.10);
  transform-origin: center bottom;
  transition: transform 3.6s cubic-bezier(0.16, 1, 0.3, 1);
  will-change: transform;
}
body.is-loaded .cover-mockup img {
  transform: scale(1);
}
@media (prefers-reduced-motion: reduce) {
  .cover-mockup img,
  body.is-loaded .cover-mockup img {
    transition: none;
    transform: scale(1);
  }
}
.cover-mockup::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom, rgba(12,12,12,0.55) 0%, rgba(12,12,12,0.18) 14%, rgba(12,12,12,0) 28%, rgba(12,12,12,0) 50%, rgba(12,12,12,0.6) 75%, rgba(12,12,12,0.95) 100%),
    linear-gradient(to right, rgba(12,12,12,0.6) 0%, rgba(12,12,12,0) 30%);
  pointer-events: none;
}

/* ── Massive title (bottom) ──────────────────────────────── */
.cover-title {
  position: absolute;
  z-index: 2;
  left: clamp(20px, 4vw, 68px);
  right: clamp(20px, 4vw, 68px);
  bottom: clamp(16px, 2.8vh, 48px);
  font-family: var(--font-sans);
  line-height: 0.95;
  letter-spacing: -0.048em;
  color: var(--text);
  /* No overflow:hidden — match homepage's "text can breathe" rule */
  padding-bottom: clamp(4px, 0.8vh, 12px);
}
.cover-line {
  display: block;
  animation: hero-drift 8s ease-in-out infinite;
}
.cover-line:nth-child(2) { animation-delay: -3s; }
@keyframes hero-drift {
  0%, 100% { transform: translateY(0px);  opacity: 1; }
  50%      { transform: translateY(-4px); opacity: 0.88; }
}
.cover-line > span:not(.cover-script) {
  font-family: var(--font-sans);
  font-weight: var(--fw-extralight);
  font-size: clamp(2.8rem, 8.07vw, 9.6875rem);
  letter-spacing: -0.039em;
  color: var(--text);
  display: inline-block;
  vertical-align: bottom;
}
.cover-script {
  font-family: var(--font-script);
  font-style: italic;
  font-weight: var(--fw-regular);
  color: var(--accent);
  font-size: clamp(3.4rem, 9.9vw, 11.875rem);
  letter-spacing: 0;
  margin-right: 0.12em;
  display: inline-block;
  vertical-align: bottom;
  position: relative;
  top: 0.06em;
}

.cover-status {
  position: absolute;
  z-index: 2;
  bottom: clamp(28px, 3.5vh, 44px);
  right: clamp(20px, 4vw, 68px);
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(13px, 1vw, 15px);
  color: var(--text);
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  transition: color 0.25s var(--ease-expo);
}
.cover-status:hover { color: var(--accent); }
.cover-status-dots { color: var(--accent); opacity: 0.4; letter-spacing: 0.04em; }

/* ── Tablet (≤1024px): tighten cover ──────────────────────── */
@media (max-width: 1024px) {
  .cover-mockup img { object-position: 55% center; }
}

/* ── Mobile hero text — matches the homepage's mobile breakpoint
   (≤767) so cover-line / cover-script render at the same size as
   the homepage hero on phones and tablet portrait. */
@media (max-width: 767px) {
  .cover-line > span:not(.cover-script),
  .cover-script {
    font-size: clamp(2.2rem, 11vw, 3.8rem);
  }
}

/* ── iPad Pro 11" portrait window (821–900): bumps the base @900
   tablet scale so the larger Pro screen gets a proportionally
   larger laptop, while Mini/Air (≤820) keep the smaller base. ── */
@media (min-width: 821px) and (max-width: 900px) {
  .cover-mockup img {
    height: 80%;
    transform: scale(1.7);
  }
  body.is-loaded .cover-mockup img {
    transform: scale(1.55);
  }
}

/* ── iPad Pro 12.9 portrait window (901–1024): the desktop scale (1.10)
   reads small at this width; bump it so the laptop has presence. ── */
@media (min-width: 901px) and (max-width: 1024px) {
  .cover-mockup img {
    transform: scale(1.7);
    transform-origin: center bottom;
  }
  body.is-loaded .cover-mockup img {
    transform: scale(1.55);
  }
}

/* ── Tablet-mid (≤900px): scale up + shift left so the laptop sits
   centred on screen; right-weight of the source frame overflows off ── */
@media (max-width: 900px) {
  /* Base tablet rule. Tuned for Mini/Air (~768-820): conservative
     scale so the laptop doesn't dominate the cover. iPad Pro 11"
     (821-900) gets a bigger scale via the more-specific block below. */
  .cover-mockup img {
    inset: auto 0 0 0;
    width: 100%;
    height: 70%;
    left: 0;
    object-fit: cover;
    object-position: 65% 32%;
    transform: scale(1.3);
    transform-origin: center bottom;
  }
  body.is-loaded .cover-mockup img {
    transform: scale(1.2);
  }
  .cover-mockup::after {
    background:
      /* left-to-right title-protection gradient */
      linear-gradient(to right, rgba(12,12,12,0.72) 0%, rgba(12,12,12,0.18) 36%, rgba(12,12,12,0) 60%),
      /* top-darken for profile readability — held deeper through ~28% so the
         scaled-up laptop image (transform: scale(2.4)) doesn't bleed bright
         pixels into the profile-card / CTA / tools-bar zone at 720–900px */
      linear-gradient(to bottom, rgba(12,12,12,0.92) 0%, rgba(12,12,12,0.78) 12%, rgba(12,12,12,0.55) 22%, rgba(12,12,12,0.22) 32%, rgba(12,12,12,0.05) 42%, rgba(12,12,12,0) 52%, rgba(12,12,12,0.92) 95%);
  }
  .cover-profile { width: calc(100% - 40px); top: clamp(20px, 3vh, 36px); }
  .profile-card { gap: 16px; }
  .profile-name { font-size: 1.05rem; }
  .experience-badge,
  .avail-badge { font-size: 0.85rem; }
  .cover-title {
    bottom: clamp(56px, 9vh, 96px);
    line-height: 0.98;
  }
  .cover-status { bottom: 22px; font-size: 12px; }
}

/* ── Tablet-narrow (≤720px): cap canvas opacity, tame profile ── */
@media (max-width: 720px) {
  .cover #bg-canvas { opacity: 0.42; }
  .cover-profile { gap: var(--sp-4); }
  .profile-bottom { gap: var(--sp-3); width: 100%; }
  .cta-group { width: 100%; }
  .btn-pill { min-width: 0; }
}

/* ── Mobile (≤540px): collapse profile, full-strength top fade ── */
@media (max-width: 540px) {
  /* Phone tier (covers 14 Pro Max @ 430 too): smaller scale than tablet
     so the laptop doesn't dominate the title, but still enlarged + left-
     shifted so the laptop screen reads as the focal point. */
  .cover-mockup img {
    width: 100%;
    height: 64%;
    /* Use object-position 70% (instead of translateX) to visually shift
       the laptop toward the left of the viewport: cover crops more of
       the right of source, so the laptop sits in the left half of the
       visible window. */
    object-fit: cover;
    object-position: 70% 36%;
    /* translateX lives BEFORE scale in the chain so it stays an exact
       pixel shift in screen pixels (translate-after-scale would
       multiply by the scale factor). */
    transform: translateX(10px) scale(1.23);
  }
  body.is-loaded .cover-mockup img {
    transform: translateX(10px) scale(1.11);
  }
  .cover-mockup::after {
    background:
      linear-gradient(to right, rgba(12,12,12,0.82) 0%, rgba(12,12,12,0.25) 42%, rgba(12,12,12,0) 65%),
      linear-gradient(to bottom, rgba(12,12,12,0.92) 0%, rgba(12,12,12,0.55) 16%, rgba(12,12,12,0.15) 36%, rgba(12,12,12,0) 55%, rgba(12,12,12,0.96) 96%);
  }
  .cover #bg-canvas { opacity: 0.32; }
  .cover-profile {
    width: calc(100% - 32px);
    left: 16px;
    top: clamp(16px, 2.4vh, 28px);
    gap: 14px;
  }
  .profile-card { flex-direction: column; align-items: flex-start; gap: 12px; }
  .avatar-wrap { width: 64px; height: 64px; }
  .profile-meta { padding: 0; gap: 6px; width: 100%; }
  .profile-meta .social-icons { margin-top: 8px; flex-wrap: wrap; gap: 12px; }
  .social-icon { width: 20px; height: 20px; opacity: 0.7; }
  /* Buttons + tools share the same horizontal footprint on mobile —
     button group goes content-shaped so its width equals the tools-bar
     row below it. cta-group + profile-bottom also collapse to
     fit-content so the row hugs its labels. */
  .profile-bottom { width: fit-content; }
  .cta-group { width: fit-content; }
  .btn-pill-group { gap: 6px; width: fit-content; }
  .btn-pill {
    font-size: 0.92rem;
    height: 44px;
    padding: 0 16px;
    min-width: 0;
    flex: 0 0 auto;
  }
  .btn-pill--contact,
  .btn-pill--resume { flex: 0 0 auto; }
  .tools-bar {
    gap: 6px;
    padding: 5px 10px;
    border-radius: 16px;
    flex-wrap: wrap;
    max-width: 100%;
  }
  .tool-wrap { width: 26px; height: 26px; border-radius: 7px; }
  .cover-title {
    left: 16px;
    right: 16px;
    bottom: clamp(56px, 8vh, 88px);
  }
  .cover-status { bottom: 18px; right: 16px; font-size: 11px; }
}

/* ── Phone (≤414px) — hide tertiary chrome, hold the title ─── */
@media (max-width: 414px) {
  .cover-profile { width: calc(100% - 28px); left: 14px; }
  .experience-badge { display: none; }
  .cover-title { bottom: clamp(52px, 7.5vh, 80px); }
}

/* ── Tiny phone (≤375px) — final fit pass ────────────────── */
@media (max-width: 375px) {
  .cover-profile { width: calc(100% - 24px); left: 12px; }
  .avail-badge { display: none; }
  .tools-bar { gap: 5px; padding: 4px 8px; }
  .tool-wrap { width: 24px; height: 24px; border-radius: 6px; }
  .btn-pill { font-size: 0.8rem; height: 36px; padding: 0 12px; }
  .cover-title { left: 12px; right: 12px; bottom: 64px; }
  .cover-status { right: 12px; bottom: 16px; }
}

/* ============================================================
   ARTICLE BODY — 12-col grid, white surface, all DM Sans
   ============================================================ */
.article-body {
  background: var(--bg-light);
  color: var(--text-light);
  margin: 0 var(--page-x);
  max-width: none;
  border-radius: 0;
  padding: clamp(56px, 9vh, 120px) clamp(28px, 3vw, 56px);
  position: relative;
  /* overflow-x: clip contains tooltip pseudo-elements (which absolutely
     position past their inline .tip parents) and any other rogue overflow,
     WITHOUT creating a scroll context — sticky positioning still works. */
  overflow-x: clip;

  display: grid;
  /* minmax(0, 1fr) prevents intrinsic-size children (esp. wide images
     in .bleed-shot and .bleed-shot--scroll) from pushing the track
     wider than the viewport on mobile. Plain 1fr resolves to
     minmax(auto, 1fr) which honours min-content. */
  grid-template-columns: repeat(var(--grid-cols), minmax(0, 1fr));
  column-gap: var(--grid-gap);
  row-gap: 0;
  /* Clamp the body itself so a stray wide child can never blow it out */
  min-width: 0;
}

/* Chapter wrappers vanish — children participate in the article-body grid */
.chapter,
.chapter-body {
  display: contents;
}

/* Prose / headings: full grid width, max-width caps line length for readability */
.chapter-head,
.chapter-body > p,
.chapter-body > ul,
.chapter-body > ol,
.chapter-body > .pull-quote,
.chapter-body > .demo-card,
.chapter-body > .prompt-hint {
  grid-column: 1 / -1;
}
.chapter-body > .prompt-hint {
  max-width: 72ch;
}
/* Prose fills the full assigned grid range — no fixed character cap */
.chapter-body > p,
.chapter-body > ul,
.chapter-body > ol {
  max-width: none;
}
/* Pull-quote figure spans the full grid column so the top + bottom rules
   read as full-width dividers. The TEXT inside hangs left-aligned (Day 1
   reference) — the rules don't shrink with it. */
.chapter-body > .pull-quote {
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  text-align: left;
}
.chapter-body > .demo-card {
  max-width: none;
}

/* ── chapter--spread: left-aligned, paragraphs alternate width ───
   Each paragraph occupies a different fraction of the grid so the
   chapter reads as a Tony-and-Co spread instead of a tidy column. */
.chapter--spread .chapter-head {
  grid-column: 1 / -1;
}
.chapter--spread .chapter-body > p:nth-of-type(1) {
  grid-column: 1 / span 11;
  max-width: none;
  font-size: clamp(20px, 1.8vw, 28px);
  font-weight: 300;
  line-height: 1.4;
  letter-spacing: -0.012em;
  margin-top: clamp(28px, 4vh, 44px);
}
.chapter--spread .chapter-body > p:nth-of-type(2) {
  grid-column: 1 / span 6;
  max-width: none;
}
.chapter--spread .chapter-body > p:nth-of-type(3) {
  grid-column: 4 / span 8;
  max-width: none;
}
.chapter--spread .chapter-body > p:nth-of-type(4) {
  grid-column: 1 / span 7;
  max-width: none;
}
.chapter--spread .chapter-body > p:nth-of-type(5) {
  grid-column: 6 / span 7;
  max-width: none;
  margin-top: clamp(40px, 5vh, 64px);
}
.chapter--spread .chapter-body > p:nth-of-type(n+6) {
  grid-column: 1 / span 7;
  max-width: none;
}

/* Wider artifacts span more cols */
.article-body > .bleed-shot,
.chapter-body > .live-frame,
.chapter-body > .token-snippet,
.chapter-body > .cost-value,
.chapter-body > .ledger,
.chapter-body > .receipt-tape {
  grid-column: 1 / -1;
}

/* Inter-chapter spacing applied to chapter-head margin-top */
.chapter-head {
  margin-top: clamp(80px, 12vh, 128px);
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding-bottom: clamp(18px, 2.4vh, 28px);
  border-bottom: 1px solid var(--rule-light);
}
.chapter:first-of-type .chapter-head { margin-top: 0; }

.chapter-num { display: none; }
.chapter-title {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(1.6rem, 3.2vw, 2.6rem);
  letter-spacing: -0.025em;
  line-height: 1.1;
  color: var(--text-light);
  min-width: 0;          /* allow wrap inside flex chapter-head */
  flex: 1 1 auto;
  overflow-wrap: break-word;
  word-wrap: break-word;
}

.chapter-body > p,
.chapter-body > ul,
.chapter-body > ol {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(16px, 1.12vw, 19px);
  line-height: 1.62;
  color: var(--text-light);
  margin-top: clamp(20px, 3vh, 28px);
  margin-bottom: 0;
}
.chapter-body > p:first-child,
.chapter-body > ul:first-child,
.chapter-body > ol:first-child { margin-top: clamp(28px, 4vh, 44px); }

/* Pull-quote — DM Sans large, script accent on first letter.
   Day 1 reference standard: left-aligned, top + bottom rule lines,
   larger display weight. All pull-quotes on the page match this. */
.pull-quote {
  margin-top: clamp(48px, 7vh, 80px) !important;
  padding: clamp(24px, 4vh, 40px) 0;
  border-top: 1px solid var(--rule-light);
  border-bottom: 1px solid var(--rule-light);
  text-align: left;
}
.pull-quote p {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(26px, 2.6vw, 38px);
  line-height: 1.28;
  color: var(--text-light);
  letter-spacing: -0.018em;
  max-width: 52ch;
  margin: 0 !important;
  text-align: left;
}
.pull-quote .qb {
  display: block;
}
.quote-script {
  font-family: var(--font-script);
  color: var(--accent);
  font-weight: 400;
  font-size: 1.5em;
  line-height: 0.8;
  margin-right: 0.04em;
}

/* ── Prompt hint — pill with a lightbulb glyph.
   Rest:   pill shows [lightbulb] Hint. Reads at a glance.
   Hover:  the dot + sub label "how I'd describe …" slides in after
           Hint. Mouse leaves the hint area → CSS-auto outro (sub
           label slides back, pill bg returns to rest).
   Open:   icon picks up a soft yellow halo so state is legible even
           after the cursor moves. Body bento drops below.
   Outros: mouseleave on .prompt-hint reverses :hover automatically;
   script.js closes [open] 120ms after mouseleave. IntersectionObserver
   also closes [open] when the hint scrolls out of view. */
.prompt-hint {
  display: block;
  margin: clamp(24px, 3.4vh, 32px) 0;
  max-width: 72ch;
}
.ph-trigger {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 3px 14px 3px 3px;
  /* Frosted-glass capsule, matching the .day-rail-list aesthetic.
     Soft dark surface, hairline white border, backdrop blur. Red glyph
     disc inside reads as the focal "active dot" against the dim
     surface, same as the active day-rail node. */
  background: rgba(20, 20, 20, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-pill);
  overflow: hidden;
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.005em;
  color: var(--text);
  user-select: none;
  /* Outro path: short, normal ease so the pill bg + border return to
     rest in sync with the WAAPI body close. easeOutQuart over 720ms
     was leaving a long dead tail — the body had already disappeared
     but the pill was still fading for ~500ms past it. */
  transition:
    background 280ms var(--ease-expo),
    border-color 280ms var(--ease-expo),
    box-shadow 320ms var(--ease-expo);
}
.ph-trigger::-webkit-details-marker { display: none; }
.ph-trigger::marker { display: none; content: ""; }
.ph-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Expansion rules skip while data-closing is set so the pill outro
   runs in parallel with the WAAPI body close, not after it.
   :has(:focus-visible) instead of :focus-within so that click-driven
   focus on the <summary> doesn't keep the pill expanded after the
   close completes — only keyboard focus expands it. */
.prompt-hint:hover:not([data-closing]) .ph-trigger,
.prompt-hint:has(:focus-visible):not([data-closing]) .ph-trigger,
.prompt-hint[open]:not([data-closing]) .ph-trigger {
  background: rgba(20, 20, 20, 0.7);
  border-color: rgba(255, 255, 255, 0.16);
  /* Intro path: snappier ease-out so the pill responds quickly to the
     mouse arriving. The outro on the base rule above handles the
     gentle collapse back. */
  transition:
    background 280ms var(--ease-expo),
    border-color 280ms var(--ease-expo),
    box-shadow 320ms var(--ease-expo);
}
.prompt-hint[open]:not([data-closing]) .ph-trigger {
  box-shadow: 0 0 16px rgba(228, 2, 2, 0.45);
}
.ph-trigger-icon {
  flex-shrink: 0;
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--r-pill);
  /* Solid red disc with a white glyph — the focal "active dot"
     against the dim capsule. Mirrors the day-rail.is-active node. */
  background: var(--accent);
  color: var(--text);
  transition:
    background 320ms var(--ease-expo),
    box-shadow 320ms var(--ease-expo);
}
.ph-trigger-icon svg {
  width: 14px;
  height: 14px;
  display: block;
}
/* Open: icon disc keeps its solid red but picks up a soft outer halo,
   mirroring the day-rail.is-active node's red glow. The :not(data-
   closing) guard makes sure the halo fades in lockstep with the rest
   of the pill outro, instead of holding through the close animation. */
.prompt-hint[open]:not([data-closing]) .ph-trigger-icon {
  box-shadow: 0 0 12px rgba(228, 2, 2, 0.6);
}
.ph-trigger-label {
  flex-shrink: 0;
  font-weight: 500;
  color: var(--text);
}
.ph-trigger-sub {
  display: inline-flex;
  align-items: center;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-weight: 400;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.55);
  /* Outro path — short, normal ease so the sub label retreats in
     sync with the rest of the pill. */
  transition:
    max-width 320ms var(--ease-expo),
    opacity 240ms var(--ease-expo);
}
/* Dot separator only appears once the sub is animating in. */
.ph-trigger-sub::before {
  content: "·";
  color: var(--accent);
  opacity: 0.7;
  margin: 0 8px 0 0;
}
.prompt-hint:hover:not([data-closing]) .ph-trigger-sub,
.prompt-hint:has(:focus-visible):not([data-closing]) .ph-trigger-sub,
.prompt-hint[open]:not([data-closing]) .ph-trigger-sub {
  max-width: 360px;
  opacity: 1;
  /* Intro path — snappier and a touch faster, with a small delay so
     the pill bg shift starts first. */
  transition:
    max-width 420ms var(--ease-expo) 60ms,
    opacity 280ms var(--ease-expo) 60ms;
}
.ph-content {
  margin-top: clamp(12px, 1.6vh, 16px);
  padding: clamp(16px, 2vh, 22px) clamp(18px, 2vw, 24px);
  background: rgba(20, 20, 20, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: var(--r-bento);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  /* Closed-state baseline. JS animates these via WAAPI on toggle.
     The CSS transitions are a fallback for browsers without JS, and
     box-shadow is also transitioned so the open-state red glow can't
     pop off at the close-flip if the WAAPI close ease is ever changed
     to one that doesn't already drive opacity to 0. */
  overflow: hidden;
  opacity: 0;
  transform: translateY(-6px);
  transition:
    opacity 320ms var(--ease-expo),
    transform 360ms var(--ease-expo),
    box-shadow 360ms var(--ease-expo);
}
.prompt-hint[open] .ph-content {
  opacity: 1;
  transform: translateY(0);
  box-shadow: 0 0 28px rgba(228, 2, 2, 0.20);
}
.ph-body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 14px;
  color: var(--text-light-muted);
  margin: 0 0 12px;
  line-height: 1.55;
}
.ph-prompt {
  font-family: var(--font-sans);
  font-style: italic;
  font-weight: 300;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text-light);
  margin: 0;
  background: transparent;
  padding: 0;
  border: 0;
}
.ph-prompt::before {
  content: "“";
  margin-right: 2px;
  color: var(--accent);
  font-style: normal;
}
.ph-prompt::after {
  content: "”";
  margin-left: 2px;
  color: var(--accent);
  font-style: normal;
}
@media (prefers-reduced-motion: reduce) {
  .ph-trigger-icon,
  .ph-trigger-icon::before,
  .ph-trigger-icon::after,
  .ph-content { transition: none !important; }
  .prompt-hint[open] .ph-content { transform: none; }
}

/* ── Prompt callout — "this is what I sent Claude" ────────── */
/* ── Prompt callout, restyled as a chat-app message addressed to
   Opus 4.7. Reads like a real conversation, not a generic blockquote. */
.prompt-callout {
  grid-column: 1 / span 9;
  margin: clamp(28px, 4vh, 44px) 0;
  padding: clamp(18px, 2.4vh, 26px) clamp(20px, 2.6vw, 28px) clamp(20px, 2.6vh, 28px);
  background: var(--bg-light-2);
  border: 1px solid var(--rule-light);
  border-radius: var(--r-bento);
  max-width: 56ch;
  position: relative;
}
.pc-thread {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: clamp(14px, 2vh, 18px);
  padding-bottom: clamp(12px, 1.6vh, 16px);
  border-bottom: 1px solid var(--rule-light);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-light);
  letter-spacing: -0.005em;
}
.pc-avatar {
  width: 24px;
  height: 24px;
  border-radius: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: -0.01em;
  color: #ffffff;
}
.pc-avatar--me {
  background: var(--accent);
  overflow: hidden;
}
.pc-avatar--me img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 28%;
  display: block;
}
.pc-avatar--ai {
  background: var(--color-purple);
  color: var(--color-midnight);
}
.pc-avatar--ai svg {
  width: 14px;
  height: 14px;
}
.pc-name { display: inline-block; }
.pc-name--ai { color: var(--color-purple); }
.pc-arrow {
  color: var(--text-light-muted);
  font-size: 12px;
  margin: 0 2px;
}
.pc-when {
  margin-left: auto;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-light-muted);
}
.pc-agent {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(155, 145, 246, 0.14);
  color: var(--color-purple);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  border: 1px solid rgba(155, 145, 246, 0.3);
}
.pc-bubble {
  /* The actual user message — sits as a soft bubble inside the card. */
  background: rgba(255, 255, 255, 0.04);
  border-radius: 12px;
  padding: clamp(14px, 1.8vh, 18px) clamp(16px, 1.8vw, 20px);
}
.pc-body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(15px, 1.1vw, 17px);
  line-height: 1.55;
  color: var(--text-light);
  margin: 0;
  letter-spacing: -0.005em;
  font-style: normal;
}
.pc-caption {
  display: block;
  margin: clamp(10px, 1.4vh, 14px) 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-light-muted);
}

/* ── Prompt bento — two chat-session windows side by side. Replaces the
   single footer-port callout. Honest pairing: hero atmosphere prompt
   (earlier session) next to the line that ported it into the footer. */
.prompt-bento {
  grid-column: 1 / span 9;
  margin: clamp(28px, 4vh, 44px) 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.pb-card {
  background: #000;
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 4px;
  padding: clamp(16px, 2vh, 22px) clamp(16px, 1.8vw, 22px);
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.6vh, 16px);
  position: relative;
  min-width: 0;
}
.pb-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: clamp(10px, 1.4vh, 14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.pb-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #FFC919;
  box-shadow: 0 0 6px rgba(255, 201, 25, 0.55);
  flex-shrink: 0;
}
.pb-card:nth-child(2) .pb-dot { background: #E40202; box-shadow: 0 0 6px rgba(228, 2, 2, 0.55); }
.pb-tag {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-light);
}
.pb-when {
  margin-left: auto;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-light-muted);
}
.pb-body {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(13px, 0.95vw, 15px);
  line-height: 1.6;
  color: var(--text-light);
  margin: 0;
  letter-spacing: -0.003em;
}

/* ── Token snippet (Day 1, foundations) — CLI window ── */
.token-snippet {
  --tk-bg:        #0e0e13;
  --tk-bg-chrome: #18181f;
  --tk-rule:      rgba(255, 255, 255, 0.08);
  --tk-text:      #e8e6df;
  --tk-muted:     rgba(232, 230, 223, 0.42);
  --tk-prop:      #c9c4b8;
  --tk-val:       #f4f0e6;
  --tk-num:       var(--color-purple);

  margin: clamp(28px, 3.8vh, 48px) 0;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  border: 1px solid var(--tk-rule);
  border-radius: var(--r-card);
  background: var(--tk-bg);
  overflow: hidden;
  box-shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.55);
}

.token-snippet .tk-chrome {
  display: flex;
  align-items: center;
  gap: clamp(6px, 0.8vw, 10px);
  padding: clamp(10px, 1.2vh, 14px) clamp(12px, 1.4vw, 18px);
  background: var(--tk-bg-chrome);
  border-bottom: 1px solid var(--tk-rule);
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: clamp(10.5px, 0.78vw, 12px);
  color: var(--tk-muted);
  letter-spacing: 0.02em;
}
.token-snippet .tk-dot {
  width: clamp(8px, 0.7vw, 10px);
  height: clamp(8px, 0.7vw, 10px);
  border-radius: 999px;
  flex-shrink: 0;
}
.token-snippet .tk-dot--r { background: #ff5f57; }
.token-snippet .tk-dot--y { background: #ffbd2e; }
.token-snippet .tk-dot--g { background: #28c840; }
.token-snippet .tk-path {
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 clamp(6px, 1vw, 12px);
}
.token-snippet .tk-lang {
  flex-shrink: 0;
  padding: 2px 8px;
  border: 1px solid var(--tk-rule);
  border-radius: 4px;
  font-size: clamp(9.5px, 0.7vw, 10.5px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--tk-muted);
}

.token-snippet pre {
  margin: 0;
  padding: clamp(14px, 2vh, 22px) clamp(16px, 2.2vw, 26px);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
  font-size: clamp(11.5px, 0.86vw, 13.5px);
  line-height: 1.75;
  color: var(--tk-prop);
  letter-spacing: 0;
  tab-size: 2;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.16) transparent;
}
.token-snippet pre::-webkit-scrollbar { height: 6px; }
.token-snippet pre::-webkit-scrollbar-track { background: transparent; }
.token-snippet pre::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.16); border-radius: 999px; }
.token-snippet pre code {
  font-family: inherit;
  font-size: inherit;
  background: transparent;
  padding: 0;
  white-space: pre;
  display: block;
  min-width: max-content;
}
.token-snippet .tk-c {
  color: var(--tk-muted);
  font-style: normal;
}

.token-snippet figcaption {
  padding: clamp(10px, 1.2vh, 14px) clamp(16px, 2.2vw, 26px) clamp(12px, 1.6vh, 18px);
  border-top: 1px solid var(--tk-rule);
  font-size: clamp(11.5px, 0.82vw, 12.5px);
  color: var(--tk-muted);
  line-height: 1.55;
}

@media (max-width: 540px) {
  .token-snippet pre { font-size: 11.5px; line-height: 1.7; }
  .token-snippet .tk-path { font-size: 10.5px; }
  .token-snippet .tk-lang { display: none; }
}

/* ── Cost vs Value figure — asymmetric side-by-side panels with flip tiles ── */
.cost-value {
  --cv-cost-bg:    #14141a;
  --cv-cost-text:  #f4f0e6;
  --cv-cost-muted: rgba(244, 240, 230, 0.55);
  --cv-cost-rule:  rgba(244, 240, 230, 0.14);
  --cv-value-bg:   #f4f0e6;
  --cv-value-text: #14141a;
  --cv-value-muted: rgba(20, 20, 26, 0.55);
  --cv-value-rule: rgba(20, 20, 26, 0.12);
  --cv-ease:       cubic-bezier(0.22, 1, 0.36, 1);

  margin: clamp(28px, 3.8vh, 48px) 0;
  width: 100%;
  max-width: 920px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: stretch;
  border: 1px solid rgba(20, 20, 26, 0.10);
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--cv-value-bg);
  box-shadow: 0 24px 60px -32px rgba(0, 0, 0, 0.28);
}

.cv-panel {
  display: flex;
  flex-direction: column;
  padding: clamp(28px, 3vw, 44px);
  min-width: 0;
}
.cv-panel--cost {
  background: var(--cv-cost-bg);
  color: var(--cv-cost-text);
}
.cv-panel--value {
  background: var(--cv-value-bg);
  color: var(--cv-value-text);
}

.cv-panel-label {
  margin: 0 0 clamp(18px, 2vw, 28px);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.cv-panel--cost .cv-panel-label  { color: var(--cv-cost-muted); }
.cv-panel--value .cv-panel-label { color: var(--cv-value-muted); }

.cv-metrics {
  display: flex;
  flex-direction: column;
  gap: 0;
  flex: 1;
}

.cv-metric {
  position: relative;
  display: block;
  width: 100%;
  margin: 0;
  padding: clamp(18px, 1.6vw, 24px) 0;
  background: transparent;
  border: 0;
  border-top: 1px solid currentColor;
  border-color: var(--cv-cost-rule);
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  overflow: hidden;
  min-height: clamp(116px, 10vw, 140px);
  -webkit-tap-highlight-color: transparent;
}
.cv-panel--value .cv-metric { border-top-color: var(--cv-value-rule); }
.cv-metric:first-child { border-top: 0; }
.cv-metric:focus { outline: none; }
.cv-metric:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 4px;
}

.cv-metric-front,
.cv-metric-back {
  display: flex;
  flex-direction: column;
  gap: clamp(6px, 0.6vw, 10px);
  transition: opacity 0.32s var(--cv-ease), transform 0.32s var(--cv-ease);
  will-change: opacity, transform;
}
.cv-metric-front {
  position: relative;
  opacity: 1;
  transform: translateY(0);
}
.cv-metric-back {
  position: absolute;
  inset: clamp(18px, 1.6vw, 24px) 0 clamp(18px, 1.6vw, 24px) 0;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
}

.cv-metric:hover .cv-metric-front,
.cv-metric:focus-visible .cv-metric-front,
.cv-metric.is-flipped .cv-metric-front {
  opacity: 0;
  transform: translateY(-8px);
}
.cv-metric:hover .cv-metric-back,
.cv-metric:focus-visible .cv-metric-back,
.cv-metric.is-flipped .cv-metric-back {
  opacity: 1;
  transform: translateY(0);
}

.cv-metric-num {
  display: block;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(32px, 4.2vw, 56px);
  line-height: 1.04;
  letter-spacing: -0.025em;
  font-variant-numeric: tabular-nums;
  text-wrap: balance;
  overflow-wrap: break-word;
}
.cv-metric-usd {
  font-size: 0.5em;
  font-weight: 400;
  letter-spacing: 0;
  opacity: 0.55;
  margin-left: 0.15em;
  white-space: nowrap;
}
.cv-metric-desc {
  display: block;
  font-family: var(--font-sans);
  font-size: clamp(12.5px, 0.95vw, 14px);
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0.005em;
}
.cv-panel--cost .cv-metric-desc  { color: var(--cv-cost-muted); }
.cv-panel--value .cv-metric-desc { color: var(--cv-value-muted); }

/* Divider with circular arrow — reads as transformation */
.cv-divider {
  position: relative;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    var(--cv-value-rule) 12%,
    var(--cv-value-rule) 88%,
    transparent 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
}
.cv-arrow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 36px;
  height: 36px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cv-cost-bg);
  color: var(--cv-cost-text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1;
  box-shadow: 0 0 0 6px var(--cv-value-bg);
  transition: transform 0.4s var(--cv-ease);
}
.cost-value:hover .cv-arrow { transform: translate(-50%, -50%) translateX(2px); }

.cost-value figcaption {
  grid-column: 1 / -1;
  padding: clamp(14px, 1.4vw, 20px) clamp(20px, 2vw, 28px) clamp(16px, 1.8vw, 22px);
  border-top: 1px solid var(--cv-value-rule);
  background: var(--cv-value-bg);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 400;
  color: var(--cv-value-muted);
  letter-spacing: 0.005em;
  line-height: 1.55;
}

@media (max-width: 860px) {
  .cost-value {
    grid-template-columns: 1fr;
  }
  .cv-divider {
    width: 100%;
    height: 1px;
    min-height: 0;
    background: linear-gradient(
      to right,
      transparent 0%,
      var(--cv-value-rule) 12%,
      var(--cv-value-rule) 88%,
      transparent 100%
    );
  }
  .cv-arrow {
    transform: translate(-50%, -50%) rotate(90deg);
  }
  .cost-value:hover .cv-arrow {
    transform: translate(-50%, -50%) rotate(90deg) translateX(2px);
  }
  .cv-panel { padding: clamp(22px, 5vw, 32px); }
  .cv-metric { min-height: clamp(104px, 26vw, 132px); }
  .cv-metric-num { font-size: clamp(30px, 7vw, 42px); }
}

@media (max-width: 480px) {
  .cv-panel { padding: 20px 18px; }
  .cv-panel-label { margin-bottom: 14px; }
  .cv-metric { padding: 16px 0; min-height: 104px; }
  .cv-metric-back { inset: 16px 0 16px 0; }
  .cv-metric-num { font-size: 30px; }
  .cv-metric-desc { font-size: 12.5px; }
  .cv-arrow { width: 32px; height: 32px; font-size: 14px; box-shadow: 0 0 0 5px var(--cv-value-bg); }
  .cost-value figcaption { padding: 14px 18px 16px; font-size: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .cv-metric-front,
  .cv-metric-back,
  .cv-arrow {
    transition: none;
  }
}

/* ============================================================
   LEDGER — token bar (option B) + terminal receipt (option A)
   Combined into one figure. Bar narrates the process beat,
   receipt closes with the cost punchline. Both sit in the
   same dark CLI-window aesthetic as .token-snippet so the case
   study only carries one terminal-style language, not two.
   ============================================================ */
.ledger {
  --lg-bg:        #0e0e13;
  --lg-bg-chrome: #18181f;
  --lg-rule:      rgba(255, 255, 255, 0.08);
  --lg-text:      #e8e6df;
  --lg-muted:     rgba(232, 230, 223, 0.42);
  --lg-prop:      #c9c4b8;
  --lg-val:       #f4f0e6;
  --lg-num:       var(--color-purple);
  --lg-accent:    var(--color-red);

  margin: clamp(28px, 3.8vh, 48px) 0;
  width: 100%;
  max-width: 920px;
  display: grid;
  gap: 0;
  border: 1px solid var(--lg-rule);
  border-radius: var(--r-card);
  background: var(--lg-bg);
  overflow: hidden;
  box-shadow: 0 24px 60px -28px rgba(0, 0, 0, 0.55);
}

/* ---- Token bar ---- */
.ledger-bar {
  padding: clamp(20px, 2.2vh, 28px) clamp(20px, 2.4vw, 32px) clamp(28px, 3vh, 40px);
  border-bottom: 1px solid var(--lg-rule);
  background: linear-gradient(180deg, rgba(255,255,255,0.012), transparent 60%);
}
.lb-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 16px;
  margin-bottom: clamp(20px, 2.2vh, 28px);
}
.lb-label {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: clamp(11px, 0.82vw, 12.5px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--lg-muted);
}
.lb-meter {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
}
.lb-meter-num {
  font-size: clamp(18px, 1.6vw, 22px);
  font-weight: 500;
  color: var(--lg-val);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.lb-meter-unit {
  font-size: 0.7em;
  color: var(--lg-muted);
  margin-left: 1px;
}
.lb-meter-cap {
  font-size: clamp(10.5px, 0.78vw, 12px);
  color: var(--lg-muted);
  letter-spacing: 0.04em;
}

.lb-track {
  position: relative;
  width: 100%;
  height: 6px;
  background: rgba(255,255,255,0.06);
  border-radius: 999px;
  overflow: visible;
}
.lb-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  background: linear-gradient(90deg, var(--lg-val) 0%, var(--lg-val) 75%, var(--lg-accent) 100%);
  border-radius: 999px;
  transition: width 1.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.ledger.is-visible .lb-fill { width: 100%; }
.lb-stops {
  position: absolute;
  inset: 0;
  list-style: none;
  margin: 0;
  padding: 0;
}
.lb-stop {
  position: absolute;
  top: 50%;
  left: var(--at);
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  pointer-events: none;
}
.lb-stop::before {
  content: '';
  width: 10px;
  height: 10px;
  border-radius: 999px;
  background: var(--lg-bg);
  border: 2px solid var(--lg-val);
  box-shadow: 0 0 0 3px var(--lg-bg);
  transform: translateY(0);
}
.lb-stop--end::before {
  background: var(--lg-accent);
  border-color: var(--lg-accent);
}
.lb-stop-day,
.lb-stop-label {
  position: absolute;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  white-space: nowrap;
  text-align: center;
}
.lb-stop-day {
  top: 16px;
  font-size: clamp(10px, 0.74vw, 11.5px);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lg-val);
}
.lb-stop-label {
  top: 32px;
  font-size: clamp(10px, 0.7vw, 11px);
  color: var(--lg-muted);
  letter-spacing: 0.04em;
}
.lb-stop--end .lb-stop-day { color: var(--lg-accent); }

/* ---- Receipt (re-uses token-snippet's CLI window aesthetic) ---- */
.lr-chrome {
  display: flex;
  align-items: center;
  gap: clamp(6px, 0.8vw, 10px);
  padding: clamp(10px, 1.2vh, 14px) clamp(12px, 1.4vw, 18px);
  background: var(--lg-bg-chrome);
  border-bottom: 1px solid var(--lg-rule);
  border-top: 1px solid var(--lg-rule);
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: clamp(10.5px, 0.78vw, 12px);
  color: var(--lg-muted);
  letter-spacing: 0.02em;
}
.lr-dot {
  width: clamp(8px, 0.7vw, 10px);
  height: clamp(8px, 0.7vw, 10px);
  border-radius: 999px;
  flex-shrink: 0;
}
.lr-dot--r { background: #ff5f57; }
.lr-dot--y { background: #ffbd2e; }
.lr-dot--g { background: #28c840; }
.lr-path {
  flex: 1;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding: 0 clamp(6px, 1vw, 12px);
}
.lr-tag {
  flex-shrink: 0;
  padding: 2px 8px;
  border: 1px solid var(--lg-rule);
  border-radius: 4px;
  font-size: clamp(9.5px, 0.7vw, 10.5px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lg-muted);
}

.lr-body {
  margin: 0;
  padding: clamp(16px, 2.2vh, 24px) clamp(16px, 2.2vw, 26px);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, Consolas, monospace;
  font-size: clamp(11.5px, 0.86vw, 13.5px);
  line-height: 1.85;
  color: var(--lg-prop);
  letter-spacing: 0;
  tab-size: 2;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,0.16) transparent;
}
.lr-body::-webkit-scrollbar { height: 6px; }
.lr-body::-webkit-scrollbar-track { background: transparent; }
.lr-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.16); border-radius: 999px; }
.lr-body code {
  font-family: inherit;
  font-size: inherit;
  background: transparent;
  padding: 0;
  white-space: pre;
  display: block;
  min-width: max-content;
}
.lr-c {
  color: var(--lg-muted);
  font-style: normal;
}
.lr-v { color: var(--lg-val); }
.lr-num {
  color: var(--lg-val);
  font-weight: 500;
}
.lr-arrow { color: var(--lg-accent); }
.lr-rule { color: var(--lg-rule); }
.lr-bottom {
  color: var(--lg-val);
  font-weight: 500;
  font-size: 1.05em;
}

.ledger figcaption {
  padding: clamp(14px, 1.6vh, 18px) clamp(20px, 2.4vw, 32px);
  border-top: 1px solid var(--lg-rule);
  background: var(--lg-bg-chrome);
  font-family: var(--font-sans);
  font-size: clamp(12px, 0.86vw, 13.5px);
  line-height: 1.55;
  color: var(--lg-muted);
}

@media (max-width: 720px) {
  .ledger { max-width: 100%; }
  .lb-head { flex-direction: column; align-items: flex-start; gap: 6px; }
  .lb-stop-label { display: none; }
  .lb-stop-day { font-size: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .lb-fill { transition: none; }
}


/* ── Section-breaker mockup shots ─ full-bleed inside the article */
.bleed-shot {
  margin: clamp(48px, 6vh, 80px) 0;
  border-radius: var(--r-frame);
  overflow: hidden;
  background: var(--bg-light-2);
  aspect-ratio: 19 / 10;
  cursor: zoom-in;
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform 0.6s var(--ease-back), box-shadow 0.45s var(--ease-expo);
}
.bleed-shot:hover {
  box-shadow: 0 30px 80px -24px rgba(0, 0, 0, 0.45);
}
.chapter-side-frame {
  cursor: zoom-in;
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform 0.6s var(--ease-back), box-shadow 0.45s var(--ease-expo);
}
.chapter-side-frame:hover {
  box-shadow: 0 30px 80px -24px rgba(0, 0, 0, 0.45);
}
.bleed-shot img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center center;
}
/* Full-fill bleed for the section above "What I shipped" — green/black
   industrial frame fills the article width, mobile image scrolls inside
   horizontally so it always reads at large natural size. */
.bleed-shot--scroll {
  position: relative;
  background: #0c0c0c;
  border-radius: var(--r-frame);
  overflow: hidden;
  padding: 0;
  isolation: isolate;
  aspect-ratio: 5 / 2;
}
.bleed-shot--scroll::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url('../../assets/bg-pattern.png');
  background-repeat: repeat;
  background-size: clamp(120px, 12vw, 200px);
  opacity: 0.16;
  pointer-events: none;
  z-index: 0;
}
.bleed-shot--scroll::after {
  content: "";
  position: absolute;
  inset: auto -10% -40% -10%;
  height: 80%;
  background: radial-gradient(ellipse at 50% 100%, rgba(34,197,94,0.30) 0%, rgba(34,197,94,0) 60%);
  pointer-events: none;
  z-index: 0;
}
.bleed-scroll-track {
  position: absolute;
  inset: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: clamp(20px, 3vh, 40px) clamp(20px, 3vw, 40px);
  gap: clamp(20px, 2vw, 36px);
}
.bleed-scroll-track::-webkit-scrollbar {
  height: 6px;
}
.bleed-scroll-track::-webkit-scrollbar-thumb {
  background: rgba(255,255,255,0.18);
  border-radius: 999px;
}
.bleed-shot--scroll img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  border-radius: var(--r-card);
  box-shadow: 0 24px 60px -20px rgba(0,0,0,0.6);
  object-fit: cover;
  object-position: center center;
  scroll-snap-align: center;
  flex-shrink: 0;
}
.bleed-scroll-track:has(> img:only-child) {
  /* When there's a single image, drop padding so it fills the frame edge-to-edge */
  padding: 0;
  /* Single image = nothing to scroll. Kill the horizontal scrollbar
     (was rendering as a white line at the bottom of the mockup frame
     just above Day 3's accordion). */
  overflow-x: hidden;
  scrollbar-width: none;
}
.bleed-scroll-track:has(> img:only-child)::-webkit-scrollbar {
  display: none;
}
.bleed-scroll-track:has(> img:only-child) img {
  border-radius: 0;
  box-shadow: none;
}

@media (max-width: 720px) {
  .bleed-shot--scroll { aspect-ratio: 4 / 3; }
}

/* Agent list — side-rail in Ch 8 */
.side-agents {
  background: var(--bg-light-2);
  border-radius: var(--r-bento);
  padding: clamp(20px, 2.6vh, 28px) clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--rule-light);
}
.side-agents-title {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-light-muted);
  margin: 0 0 clamp(14px, 2vh, 20px);
}
.side-agents-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(10px, 1.4vh, 14px);
}
.side-agents-list li {
  display: grid;
  gap: 4px;
  padding-bottom: clamp(10px, 1.4vh, 14px);
  border-bottom: 1px solid var(--rule-light);
}
.side-agents-list li:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.ag-name {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 13px;
  color: var(--text-light);
  letter-spacing: -0.005em;
}
.ag-name::before {
  content: "▸ ";
  color: var(--accent);
}
.ag-owns {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 12px;
  color: var(--text-light-muted);
  line-height: 1.4;
  padding-left: 14px;
}

/* prose-mark — inline highlight for agent names in body text */
.prose-mark {
  display: inline-block;
  font-weight: 500;
  background: rgba(228, 2, 2, 0.08);
  color: var(--text-light);
  padding: 1px 6px;
  border-radius: 4px;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

/* ── Agents/Skills bento — toggle borrows portfolio Contact/Resume pill pair.
   The active tab grows on a sliding pill (yellow), inactive sits muted in white.
   Sits in chapter--swiss prose rail; midnight surface, white type, brand red on
   row hover. Keep this self-contained — don't reach for cream tokens. */
.agents-skills {
  margin: clamp(36px, 5vh, 56px) 0 clamp(20px, 3vh, 28px);
  padding: clamp(20px, 2.6vh, 28px) clamp(20px, 2.4vw, 28px) clamp(24px, 3vh, 32px);
  background: var(--color-midnight);
  border: 1px solid var(--rule-light);
  border-radius: var(--r-bento);
  color: var(--color-white);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
}
.as-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(12px, 1.6vw, 20px);
  margin-bottom: clamp(16px, 2.2vh, 22px);
  padding-bottom: clamp(14px, 1.8vh, 18px);
  border-bottom: 1px solid var(--rule-light);
  flex-wrap: wrap;
}
.as-eyebrow {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-light-muted);
  margin: 0;
}
.as-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 4px;
  gap: 4px;
  background: rgba(255,255,255,0.06);
  border-radius: var(--r-pill);
  border: 1px solid var(--rule-light);
}
.as-toggle-thumb {
  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 4px;
  width: calc(50% - 4px);
  background: var(--color-yellow);
  border-radius: var(--r-pill);
  transition: transform 320ms var(--ease-expo);
  z-index: 0;
}
.as-toggle[data-active="skills"] .as-toggle-thumb { transform: translateX(100%); }
.as-toggle-btn {
  position: relative;
  z-index: 1;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 13px;
  letter-spacing: 0.01em;
  padding: 8px clamp(14px, 1.4vw, 18px);
  border: 0;
  background: transparent;
  color: var(--color-white);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color 240ms var(--ease-expo);
}
.as-toggle-btn.is-active { color: var(--color-midnight); }
.as-toggle-btn:hover:not(.is-active) { color: var(--accent); }
.as-toggle-btn:focus-visible { outline: 2px solid var(--color-yellow); outline-offset: 3px; }
.as-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2px, 0.4vh, 4px);
}
.as-list[hidden] { display: none; }
.as-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 0.42fr) minmax(0, 0.58fr);
  gap: clamp(10px, 1.2vw, 14px);
  align-items: baseline;
  padding: clamp(10px, 1.4vh, 14px) 0;
  border-bottom: 1px solid var(--rule-light);
}
.as-list li:last-child { border-bottom: 0; }
.as-name {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 14px;
  color: var(--color-white);
  letter-spacing: -0.005em;
}
.as-desc {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 13px;
  color: var(--text-light-muted);
  line-height: 1.45;
}
.as-num {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  color: var(--text-light-muted);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  min-width: 18px;
}
@media (max-width: 720px) {
  .as-head { flex-direction: column; align-items: flex-start; }
  .as-list li { grid-template-columns: auto 1fr; gap: 8px; }
  .as-list li .as-desc { grid-column: 1 / -1; padding-left: 28px; }
}

/* ── Overview project-intro: lead prose + meta sidebar ───── */
.chapter--overview {
  display: grid;
  grid-template-columns: subgrid;
  grid-column: 1 / -1;
  column-gap: var(--grid-gap);
  align-items: start;
  margin-bottom: clamp(80px, 12vh, 128px);
}
.chapter--overview > .chapter-head {
  grid-column: 1 / span 7;
  grid-row: 1;
  margin-top: 0;
}
.chapter--overview > .chapter-body {
  grid-column: 1 / span 7;
  grid-row: 2;
  display: block;
}
.chapter--overview > .chapter-body > p {
  font-size: clamp(20px, 1.8vw, 28px);
  font-weight: 300;
  line-height: 1.4;
  letter-spacing: -0.012em;
  margin-top: clamp(20px, 3vh, 32px);
  max-width: none;
}
.chapter--overview > .chapter-body > p:first-child {
  margin-top: clamp(28px, 4vh, 44px);
}
.chapter--overview > .overview-meta {
  grid-column: 9 / span 4;
  grid-row: 1 / span 2;
  margin-top: clamp(28px, 4vh, 44px);
  align-self: start;
}
.overview-meta dl {
  display: grid;
  gap: clamp(12px, 1.6vh, 18px);
  border-top: 1px solid var(--rule-light);
  padding-top: clamp(20px, 3vh, 28px);
}
.overview-meta dl > div {
  display: grid;
  grid-template-columns: 100px 1fr;
  gap: 16px;
  padding-bottom: clamp(12px, 1.6vh, 16px);
  border-bottom: 1px solid var(--rule-light);
}
.overview-meta dl > div:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}
.overview-meta dt {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-light-muted);
}
.overview-meta dd {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 13px;
  color: var(--text-light);
  line-height: 1.45;
}
.overview-meta a { color: var(--accent); }
.overview-meta a:hover { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 900px) {
  .chapter--overview { display: block; }
  .chapter--overview > .overview-meta { margin-top: clamp(28px, 4vh, 44px); }
}

/* ── Accordion (Day 0 → Day 4) ────────────────────────────── */
.chapter--accordion {
  display: block;
  grid-column: 1 / -1;
  margin-bottom: clamp(0px, 1vh, 8px);
  border-top: 1px solid var(--rule-light);
  padding-top: clamp(20px, 3vh, 36px);
}
.chapter--accordion > summary.chapter-head {
  list-style: none;
  cursor: pointer;
  margin-top: 0;
  padding-bottom: clamp(20px, 3vh, 36px);
  border-bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  user-select: none;
  transition: color 0.25s var(--ease-expo);
}
.chapter--accordion > summary.chapter-head::-webkit-details-marker { display: none; }
.chapter--accordion > summary.chapter-head:hover { color: var(--accent); }
.chapter-toggle {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  position: relative;
  display: inline-grid;
  place-items: center;
  border-radius: 999px;
  background: rgba(20,20,20,0.05);
  transition: background 0.25s var(--ease-expo), transform 0.4s var(--ease-expo);
}
.chapter-toggle::before,
.chapter-toggle::after {
  content: "";
  position: absolute;
  background: var(--text-light);
  transition: opacity 0.3s var(--ease-expo), transform 0.4s var(--ease-expo);
}
.chapter-toggle::before { width: 12px; height: 1.5px; }
.chapter-toggle::after { width: 1.5px; height: 12px; }
.chapter--accordion[open] > summary.chapter-head .chapter-toggle::after { opacity: 0; transform: rotate(90deg); }
.chapter--accordion[open] > summary.chapter-head .chapter-toggle { background: var(--accent); }
.chapter--accordion[open] > summary.chapter-head .chapter-toggle::before { background: #fff; }
.chapter--accordion > summary.chapter-head:hover .chapter-toggle { background: rgba(20,20,20,0.10); }
.chapter--accordion[open] > summary.chapter-head { padding-bottom: clamp(20px, 3vh, 32px); }

/* All accordion summaries share the same closed height. */
.chapter--accordion > summary.chapter-head {
  min-height: clamp(64px, 8vh, 88px);
}

/* Accordion body IS the grid. 12 cols, full width of the article. */
.chapter--accordion > .chapter-body {
  display: grid;
  /* minmax(0, 1fr) prevents intrinsic-size children (wide images, etc.)
     from blowing the track wider than the viewport. */
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gap);
  width: 100%;
  min-width: 0;
  padding-bottom: clamp(56px, 8vh, 96px);
  animation: accordion-fade 0.5s var(--ease-expo);
}
.chapter--accordion > .chapter-body > p,
.chapter--accordion > .chapter-body > ul,
.chapter--accordion > .chapter-body > ol,
.chapter--accordion > .chapter-body > .demo-card,
.chapter--accordion > .chapter-body > .live-frame,
.chapter--accordion > .chapter-body > .bleed-shot,
.chapter--accordion > .chapter-body > .bleed-shot--scroll {
  grid-column: 1 / -1;
  margin-top: clamp(20px, 3vh, 28px);
  margin-bottom: 0;
  max-width: none;
}
.chapter--accordion > .chapter-body > p:first-of-type {
  margin-top: clamp(28px, 4vh, 44px);
}
.chapter--accordion > .chapter-body > .prompt-callout {
  grid-column: 1 / span 9;
  margin-top: clamp(28px, 4vh, 40px);
}
.chapter--accordion > .chapter-body > .prompt-hint {
  grid-column: 1 / span 9;
  margin-top: clamp(24px, 3.4vh, 32px);
}
.chapter--swiss .chapter-prose-rail > .prompt-hint {
  grid-column: 1 / span 7;
  margin-top: clamp(20px, 3vh, 28px);
}
.chapter--swiss > .chapter-body > .prompt-hint {
  grid-column: 1 / span 9;
  margin-top: clamp(24px, 3.4vh, 32px);
}
.chapter--accordion > .chapter-body > .prompt-row {
  grid-column: 1 / -1;
  margin-top: clamp(28px, 4vh, 40px);
}

/* Side-by-side prompts. Two callouts share the row width — flexbox here
   beats grid because .prompt-callout has its own internal sizing rules
   that don't always honour grid track widths. Mobile collapses to stack. */
.prompt-row {
  display: flex;
  flex-direction: row;
  gap: clamp(14px, 1.6vw, 22px);
  align-items: stretch;
  width: 100%;
}
.prompt-row > .prompt-callout {
  flex: 1 1 0;
  min-width: 0;
  width: auto;
  max-width: none;
  margin: 0;
}
@media (max-width: 720px) {
  .prompt-row { flex-direction: column; }
}

/* Small uppercase tag above each prompt body. */
.prompt-callout .pc-tag {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  margin: 12px 0 8px;
  padding: 0;
}
.chapter--accordion > .chapter-body > .pull-quote {
  grid-column: 1 / -1;
  margin-top: clamp(40px, 6vh, 64px);
  max-width: none;
}
.chapter-body > .inputs-bento {
  grid-column: 1 / span 9;
  margin-top: clamp(28px, 4vh, 40px);
}

/* ── Inputs bento (Day 0): list of source docs/refs fed into the build.
   Layout mirrors .agents-skills — midnight surface, eyebrow header above
   a rule, three-column row (num · name · desc) with hover-tracked
   underline + colour shift. Keeps the page rhythm consistent between
   the two list-of-things bentos. */
.inputs-bento {
  margin: clamp(36px, 5vh, 56px) 0 clamp(20px, 3vh, 28px);
  padding: clamp(20px, 2.6vh, 28px) clamp(20px, 2.4vw, 28px) clamp(24px, 3vh, 32px);
  background: var(--color-midnight);
  border: 1px solid var(--rule-light);
  border-radius: var(--r-bento);
  color: var(--color-white);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02);
}
.ib-eyebrow {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-light-muted);
  margin: 0 0 clamp(16px, 2.2vh, 22px);
  padding-bottom: clamp(14px, 1.8vh, 18px);
  border-bottom: 1px solid var(--rule-light);
}
.ib-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(2px, 0.4vh, 4px);
}
.ib-list li {
  display: grid;
  grid-template-columns: auto minmax(0, 0.42fr) minmax(0, 0.58fr);
  gap: clamp(10px, 1.2vw, 14px);
  align-items: baseline;
  padding: clamp(10px, 1.4vh, 14px) 0;
  border-bottom: 1px solid var(--rule-light);
}
.ib-list li:last-child { border-bottom: 0; }
.ib-num {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  color: var(--text-light-muted);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  min-width: 18px;
}
.ib-name {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 14px;
  color: var(--color-white);
  letter-spacing: -0.005em;
  word-break: break-word;
}
.ib-desc {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 13px;
  color: var(--text-light-muted);
  line-height: 1.45;
}
@media (max-width: 720px) {
  .ib-list li { grid-template-columns: auto 1fr; gap: 8px; }
  .ib-list li .ib-desc { grid-column: 1 / -1; padding-left: 28px; }
}

@keyframes accordion-fade {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Swiss (Day 1 accordion AND Ch 8 section): chapter-body is a 12-col
   grid; paragraphs occupy cols 1-7, chapter-side anchors cols 9-12.
   Live-frame artefacts (esp. tabbed design-system iframe) break out
   to FULL width like the other live-frame embeds in the article. */
.chapter--swiss > .chapter-body > p,
.chapter--swiss > .chapter-body > ul,
.chapter--swiss > .chapter-body > ol,
.chapter--swiss > .chapter-body > .demo-card,
.chapter--swiss > .chapter-body > .prompt-callout,
.chapter--swiss > .chapter-body > .pull-quote,
.chapter--swiss > .chapter-body > .day-cost,
.chapter--swiss > .chapter-body > .agents-skills {
  grid-column: 1 / span 7;
}
.chapter--swiss > .chapter-body > .live-frame,
.chapter--swiss > .chapter-body > .live-frame--tabbed {
  grid-column: 1 / -1;
}
.chapter--swiss > .chapter-body > .chapter-side {
  grid-column: 9 / span 4;
  /* Ch 8 chapter-body grid: 9 prose items + 1 prompt-callout fill rows 1-9.
     Side spans rows 1-8 so it tracks alongside the prose run, matching
     the previous build's behaviour. */
  grid-row: 1 / span 8;
  position: sticky;
  top: clamp(28px, 4vh, 56px);
  align-self: start;
  z-index: 1;
  margin-top: clamp(28px, 4vh, 44px);
  max-height: calc(100vh - 80px);
  overflow: hidden;
}

/* Day 1 prose-rail — wraps the prose run (paragraphs + pull-quote + aside)
   so the sticky chapter-side has a containing block that ENDS before the
   design system iframe. Without this, sticky's containing block would be
   the whole chapter-body (which extends through the iframe), and the
   mockup would scroll right into the artefact. The rail is its own
   12-col sub-grid so the prose/aside split still reads as Swiss. */
.chapter--swiss > .chapter-body > .chapter-prose-rail {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gap);
  min-width: 0;
  row-gap: 0;
}
.chapter--swiss .chapter-prose-rail > p,
.chapter--swiss .chapter-prose-rail > ul,
.chapter--swiss .chapter-prose-rail > ol,
.chapter--swiss .chapter-prose-rail > .pull-quote,
.chapter--swiss .chapter-prose-rail > .token-snippet {
  grid-column: 1 / span 7;
  max-width: none;
}
.chapter--swiss .chapter-prose-rail > .chapter-side {
  grid-column: 9 / span 4;
  /* Span all rows so paragraphs flow normally beside the aside instead
     of each paragraph cell being stretched to the aside's full height. */
  grid-row: 1 / span 99;
  position: sticky;
  top: clamp(28px, 4vh, 56px);
  align-self: start;
  z-index: 1;
  margin-top: clamp(28px, 4vh, 44px);
  max-height: calc(100vh - 80px);
  overflow: hidden;
}

/* Day 2 — first paragraph is a large lead, rest flows full-width
   like the other accordions. The "slow day" gets a single editorial cue. */
.chapter--accordion.chapter--spread > .chapter-body > p:first-of-type {
  font-size: clamp(22px, 2vw, 32px);
  font-weight: 300;
  line-height: 1.32;
  letter-spacing: -0.018em;
  color: var(--text-light);
}
.chapter--accordion.chapter--spread > .chapter-body > p:nth-of-type(2) {
  margin-top: clamp(28px, 4vh, 40px);
}

@media (max-width: 900px) {
  .chapter--accordion > .chapter-body {
    display: block;
  }
  .chapter--accordion > .chapter-body > * {
    grid-column: unset !important;
    margin-top: clamp(18px, 2.5vh, 24px) !important;
    max-width: none !important;
  }
  .chapter--swiss > .chapter-body > .chapter-side,
  .chapter--swiss .chapter-prose-rail > .chapter-side {
    position: static;
    margin: clamp(28px, 4vh, 44px) 0 clamp(8px, 1vh, 16px);
    max-width: 480px;
    grid-row: unset;
    z-index: auto;
    max-height: none;
    overflow: visible;
  }
  /* Day 1 prose-rail flattens to single column on mobile */
  .chapter--swiss > .chapter-body > .chapter-prose-rail {
    display: block;
  }
  .chapter--swiss .chapter-prose-rail > p,
  .chapter--swiss .chapter-prose-rail > ul,
  .chapter--swiss .chapter-prose-rail > ol,
  .chapter--swiss .chapter-prose-rail > .pull-quote,
  .chapter--swiss .chapter-prose-rail > .token-snippet {
    grid-column: unset;
    max-width: none;
  }
  /* Ch 8 swiss (non-accordion): collapse the inner 12-col grid so prose
     no longer pins to cols 1-7 and leaves the right side empty. */
  .chapter--swiss > .chapter-body {
    display: block;
  }
  .chapter--swiss > .chapter-body > p,
  .chapter--swiss > .chapter-body > ul,
  .chapter--swiss > .chapter-body > ol,
  .chapter--swiss > .chapter-body > .demo-card,
  .chapter--swiss > .chapter-body > .live-frame,
  .chapter--swiss > .chapter-body > .prompt-callout,
  .chapter--swiss > .chapter-body > .pull-quote {
    grid-column: unset;
    max-width: none;
  }
}

/* ── Swiss section (Ch 8 non-accordion): chapter dissolves, body owns
   the 12-col grid like accordion bodies do. */
.chapter--swiss > .chapter-head {
  grid-column: 1 / -1;
  margin-top: clamp(80px, 12vh, 128px);
}
.chapter--swiss > .chapter-body {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--grid-gap);
  width: 100%;
  min-width: 0;
}
.chapter--swiss > .chapter-body > p,
.chapter--swiss > .chapter-body > ul,
.chapter--swiss > .chapter-body > ol,
.chapter--swiss .chapter-prose-rail > p,
.chapter--swiss .chapter-prose-rail > ul,
.chapter--swiss .chapter-prose-rail > ol {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(16px, 1.12vw, 19px);
  line-height: 1.62;
  color: var(--text-light);
  margin-top: clamp(20px, 3vh, 28px);
  margin-bottom: 0;
}
.chapter--swiss > .chapter-body > .pull-quote,
.chapter--swiss .chapter-prose-rail > .pull-quote {
  margin-top: clamp(48px, 7vh, 80px);
}
.chapter--swiss > .chapter-body > .live-frame {
  margin-top: clamp(40px, 6vh, 64px);
}
.chapter-side-frame {
  position: relative;
  border-radius: var(--r-frame);
  overflow: hidden;
}
.chapter-side-frame img {
  width: 100%;
  height: auto;
  display: block;
}
.chapter-side-caption {
  display: flex;
  gap: 10px;
  align-items: baseline;
  margin: clamp(14px, 2vh, 20px) 0 0;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-light-muted);
  line-height: 1.4;
}
.csc-num {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  color: var(--accent);
  font-weight: 500;
  letter-spacing: 0.06em;
}
.chapter-side-caption span:not(.csc-num) {
  text-transform: none;
  letter-spacing: 0;
}

/* Mobile: side-rail collapses inline */
@media (max-width: 900px) {
  .chapter--swiss {
    display: block;
    /* When the chapter switches from `display: contents` (lets summary
       and body participate directly in article-body's grid) to a block
       container, it needs to span the full grid track itself — otherwise
       it auto-places into a single 1/12 cell and the title wraps one
       letter per line. */
    grid-column: 1 / -1;
  }
  .chapter--swiss > .chapter-head { margin-top: clamp(80px, 12vh, 128px); }
  /* CRITICAL: this re-asserts the collapse from the earlier @900 block
     which loses the cascade because the unconditional `display: grid`
     declaration at the swiss-section block sits AFTER it in source order.
     Without this, chapter-body stays a 12-col grid on mobile and forces
     1228px page width. */
  .chapter--swiss > .chapter-body {
    display: block;
    width: 100%;
    grid-template-columns: none;
  }
  .chapter--swiss > .chapter-body > p,
  .chapter--swiss > .chapter-body > ul,
  .chapter--swiss > .chapter-body > ol,
  .chapter--swiss > .chapter-body > .demo-card,
  .chapter--swiss > .chapter-body > .live-frame,
  .chapter--swiss > .chapter-body > .live-frame--tabbed,
  .chapter--swiss > .chapter-body > .prompt-callout,
  .chapter--swiss > .chapter-body > .pull-quote,
  .chapter--swiss > .chapter-body > .day-cost,
  .chapter--swiss > .chapter-body > .chapter-prose-rail {
    grid-column: unset;
    max-width: none;
    width: auto;
  }
  .chapter--swiss > .chapter-side {
    position: static;
    margin-top: clamp(28px, 4vh, 44px);
    margin-bottom: clamp(8px, 1vh, 16px);
    grid-column: unset;
    grid-row: unset;
    max-width: 480px;
  }
}

/* Mobile collapse — single col, prose fills width */
@media (max-width: 720px) {
  .article-body {
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
  }
  .chapter-head,
  .chapter-body > p,
  .chapter-body > ul,
  .chapter-body > ol,
  .chapter-body > .pull-quote,
  .chapter-body > .demo-card,
  .article-body > .bleed-shot,
  .chapter-body > .live-frame {
    grid-column: 1 / -1;
  }
  /* Explicitly collapse the per-paragraph spread layout so the higher-specificity
     desktop rules don't leak into single-col grid space. */
  .chapter--spread .chapter-body > p,
  .chapter--spread .chapter-body > p:nth-of-type(1),
  .chapter--spread .chapter-body > p:nth-of-type(2),
  .chapter--spread .chapter-body > p:nth-of-type(3),
  .chapter--spread .chapter-body > p:nth-of-type(4),
  .chapter--spread .chapter-body > p:nth-of-type(5),
  .chapter--spread .chapter-body > p:nth-of-type(n+6) {
    grid-column: 1 / -1;
  }
  /* Lead paragraph keeps its bigger size, but the explicit columns are gone */
  .chapter--spread .chapter-body > p:nth-of-type(1) {
    font-size: clamp(18px, 4.4vw, 22px);
  }
  /* Prompt callout stops trying to span 9 cols on a 1-col grid */
  .prompt-callout {
    grid-column: 1 / -1;
    max-width: none;
    border-radius: var(--r-bento);
    margin-left: 0;
    margin-right: 0;
  }
  /* Prompt bento stacks to a single column on mobile */
  .prompt-bento {
    grid-column: 1 / -1;
    grid-template-columns: 1fr;
    gap: 12px;
  }
  /* Pull-quote loses the right-hang and reads full width on phones */
  .chapter-body > .pull-quote {
    max-width: none;
    margin-left: 0;
    text-align: left;
  }
  /* Lower the iframe floor — 560px is desktop comfort, on phones it
     feels stranded above the natural aspect-ratio height */
  .live-frame iframe,
  .live-frame .lf-iframe {
    min-height: 320px;
  }
  /* Overview chapter collapses the meta-aside under the prose */
  .chapter--overview > .chapter-head,
  .chapter--overview > .chapter-body,
  .chapter--overview > .overview-meta {
    grid-column: 1 / -1;
  }
}

/* ── Tablet portrait (541–900): titles + tabs fit-pass ───
   Bridges the gap between desktop-wide rules and ≤540 mobile.
   - Chapter titles at clamp() upper bound feel oversized in a 320–500px
     toggle row; this scales them down so "Day 1, System before pages"
     never touches the toggle.
   - Tabbed live-frame tabs were sprawling onto 2 wide rows because
     `flex: 1 1 auto + min-width:max-content` lets each grow.
   - Prompt-callout's `1 / span 9` is moot here since accordion grids
     collapse at 900, but pad it back so it doesn't feel huge. */
@media (min-width: 541px) and (max-width: 900px) {
  .chapter-title { font-size: clamp(1.5rem, 3.8vw, 2.1rem); }
  .live-frame--tabbed .lf-tabs { gap: 3px; padding: 5px; }
  .lf-tab { padding: 9px 12px; font-size: 12px; flex: 1 1 auto; }
  .live-frame--tabbed .lf-open { padding: 0 10px; }
  .prompt-callout { max-width: none; }
}

/* ── Tablet landscape / small laptop (901–1180): give chapter
   titles a touch more room before the desktop max kicks in. ── */
@media (min-width: 901px) and (max-width: 1180px) {
  .chapter-title { font-size: clamp(1.8rem, 2.8vw, 2.3rem); }
}

/* ── Tighter mobile (≤540): smaller iframe floor ─── */
@media (max-width: 540px) {
  .live-frame iframe,
  .live-frame .lf-iframe {
    min-height: 260px;
  }
  /* Chapter titles like "Day 1, System before pages" overflow at ~1.6rem
     when the accordion toggle + gap eat ~46px of the row. Step down the
     ramp here so titles wrap cleanly inside their summary. */
  .chapter-title { font-size: clamp(1.35rem, 5.6vw, 1.6rem); }
  .chapter--accordion > summary.chapter-head { gap: 12px; }
  /* Article inner padding eats real estate on phones — pare it back. */
  .article-body { padding: clamp(40px, 7vh, 80px) clamp(16px, 4vw, 28px); }
  /* Pull-quote: drop the editorial caps so prose at small width doesn't
     sit beside a thin column of italic. */
  .pull-quote p { font-size: clamp(20px, 5.4vw, 24px); }
  /* Article-end padding tighter for narrow widths */
  .article-end {
    padding: clamp(32px, 5vh, 56px) clamp(20px, 4vw, 32px);
    /* Match the how-built card's outer width — both sit on the same
       column so their edges align. how-built uses page-x + article-
       body's mobile padding-x (clamp 16-28); mirror that here. */
    margin-left: calc(var(--page-x) + clamp(16px, 4vw, 28px));
    margin-right: calc(var(--page-x) + clamp(16px, 4vw, 28px));
  }
  .end-title { font-size: clamp(1.5rem, 7vw, 2rem); }
  /* Centred copy block on phone, button under it */
  .article-end__row {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 20px;
  }
  .article-end__copy { text-align: center; }
  .magnetic-btn { gap: 12px; padding: 12px 18px; font-size: 14px; }
  .mb-arrow { width: 30px; height: 30px; }
}

/* ── Phone (≤414): final cover + accordion fit pass ─── */
@media (max-width: 414px) {
  .chapter-title { font-size: clamp(1.25rem, 5.4vw, 1.45rem); }
  .chapter-head { gap: 10px; }
  /* Day 1 sticky side-rail caption: keep it readable on the smallest
     phones where 12px uppercase felt cramped beside a wide image. */
  .chapter-side-caption { font-size: 11px; }
  /* prompt-callout interior padding tighter */
  .prompt-callout { padding: clamp(18px, 3vh, 24px) clamp(18px, 4vw, 22px); }
}

/* ── Tiny phone (≤375): final fit pass for accordion + tools ─── */
@media (max-width: 375px) {
  .chapter-title { font-size: 1.2rem; letter-spacing: -0.02em; }
  .chapter-toggle { width: 24px; height: 24px; }
  /* Tools-bar: drop one wrapping behavior so tools stay on one row */
  .tools-bar { gap: 4px; }
  .tool-wrap { width: 22px; height: 22px; }
}

/* ============================================================
   HOW IT WAS BUILT — styled like the seven-agents side-rail
   ============================================================ */
.how-built {
  grid-column: 1 / -1;
  max-width: none;
  margin: clamp(56px, 8vh, 88px) 0 0;
  padding: clamp(32px, 4.5vh, 56px) clamp(28px, 3.5vw, 56px);
  background: var(--bg-light-2);
  color: var(--text-light);
  border-radius: var(--r-frame);
  border: 1px solid var(--rule-light);
}
.how-built-title {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-light-muted);
  margin-bottom: clamp(24px, 3.5vh, 36px);
}
.how-built-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(20px, 2.4vw, 36px) clamp(20px, 2.4vw, 32px);
}
.how-built-list > div {
  display: grid;
  gap: 8px;
  align-items: baseline;
  padding-top: clamp(14px, 2vh, 18px);
  padding-bottom: 0;
  border-top: 1px solid var(--rule-light);
  border-bottom: 0;
}
.how-built-list dt {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-light-muted);
}
.how-built-list dd {
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--text-light);
}
.how-built-list a { color: var(--accent); }
.how-built-list a:hover { text-decoration: underline; text-underline-offset: 3px; }

@media (max-width: 540px) {
  .how-built-list > div { grid-template-columns: 1fr; gap: 4px; }
}

/* ============================================================
   END OF ARTICLE — short squircle, copy left + button right
   ============================================================ */
.article-end {
  position: relative;
  margin-top: clamp(24px, 4vh, 48px);
  margin-bottom: clamp(40px, 6vh, 80px);
  margin-left: calc(var(--page-x) + clamp(28px, 3vw, 56px));
  margin-right: calc(var(--page-x) + clamp(28px, 3vw, 56px));
  max-width: none;
  padding: clamp(40px, 6vh, 72px) clamp(28px, 3vw, 56px);
  /* Darker than the page bg (#171717) so the card reads as a distinct
     surface even with the WebGL ripple canvas behind it. */
  background: #050505;
  color: var(--text);
  border-radius: var(--r-frame);
  overflow: hidden;
  isolation: isolate;
  /* 1px hairline border helps the edge define against the page bg too */
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
}
.article-end #end-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  display: block;
}

.article-end__row {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(24px, 3vw, 48px);
  flex-wrap: wrap;
}
.article-end__copy {
  flex: 1 1 360px;
  min-width: 0;
}

.end-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: clamp(14px, 2vh, 22px);
}
.end-dot {
  /* End-of-article completion mark — yellow reads as 'finished' /
     positive, not 'stop' / alarm. */
  width: 6px; height: 6px;
  background: var(--color-yellow);
  border-radius: 999px;
  display: inline-block;
}
.end-num { margin-left: 4px; opacity: 0.7; font-variant-numeric: tabular-nums; }

.end-title {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(1.8rem, 3.4vw, 2.8rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--text);
  margin: 0 0 clamp(8px, 1.2vh, 14px);
  white-space: nowrap;
}
.end-script {
  font-family: var(--font-script);
  font-weight: 400;
  color: var(--accent);
  font-size: 1.22em;
  line-height: 0.85;
  margin-right: 0.02em;
  display: inline-block;
}
.end-sub {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(13px, 1vw, 15px);
  line-height: 1.45;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: 0;
}

@media (max-width: 720px) {
  .end-title { white-space: normal; }
  .article-end__row { gap: 24px; }
  /* Row flips to flex-direction: column at <=720, which makes the
     copy's `flex: 1 1 360px` basis apply to HEIGHT instead of width.
     Reset to auto so the copy block sizes to its text content. */
  .article-end__copy { flex: 0 0 auto; }
}

/* Magnetic pill button — mouse-follow via JS, color/scale via CSS */
.magnetic-btn {
  --mb-bg: #f1f1f4;
  --mb-fg: #141414;
  display: inline-flex;
  align-items: center;
  gap: 16px;
  padding: clamp(14px, 1.6vh, 18px) clamp(22px, 2.4vw, 32px);
  border-radius: 999px;
  background: var(--mb-bg);
  color: var(--mb-fg);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(15px, 1.2vw, 17px);
  letter-spacing: -0.005em;
  text-decoration: none;
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition:
    background 0.4s var(--ease-expo),
    color 0.4s var(--ease-expo),
    box-shadow 0.4s var(--ease-expo);
  will-change: transform;
  background-image: none !important;
}
.magnetic-btn:hover {
  --mb-bg: var(--accent);
  --mb-fg: #ffffff;
  /* Shadow tinted to bg, not the button colour — keeps the red CTA
     the focal point without amplifying the danger read. */
  box-shadow: 0 18px 48px -16px rgba(20, 20, 26, 0.55);
}
.magnetic-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

.mb-track {
  position: relative;
  display: inline-grid;
  overflow: hidden;
  height: 1.2em;
}
.mb-track .mb-label {
  grid-area: 1 / 1;
  display: inline-block;
  white-space: nowrap;
  transition: transform 0.45s var(--ease-expo);
  will-change: transform;
}
.mb-label--alt { transform: translateY(110%); }
.magnetic-btn:hover .mb-label              { transform: translateY(-110%); }
.magnetic-btn:hover .mb-label.mb-label--alt { transform: translateY(0); }

.mb-arrow {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  background: rgba(20,20,20,0.08);
  color: currentColor;
  transition: background 0.4s var(--ease-expo), transform 0.4s var(--ease-expo);
}
.magnetic-btn:hover .mb-arrow {
  background: rgba(255,255,255,0.18);
  transform: translateX(6px);
}

/* ── CTA variant of article-end ─────────────────────────── */
/* Red dot signals "ask" instead of the yellow "wrap-up" dot */
.end-dot--accent { background: var(--accent); }
/* Copy is taller than the original article-end (4 elements vs 2),
   so bottom-align the button with the tertiary link instead of
   floating it in the middle. Only affects wide layouts; below the
   720px wrap, the row stacks and align-items is moot. */
.article-end--cta .article-end__row { align-items: flex-end; }
/* CTA title is longer than "Thanks for reading." so let it wrap */
.article-end--cta .end-title {
  white-space: normal;
  line-height: 1.1;
  max-width: 22ch;
}
.cta-tertiary {
  margin: clamp(14px, 2vh, 20px) 0 0;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.cta-secondary {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 13px;
  color: var(--text-muted);
  letter-spacing: 0.01em;
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-color: rgba(255, 255, 255, 0.18);
  transition: color 0.25s ease, text-decoration-color 0.25s ease;
}
.cta-secondary:hover {
  color: var(--text);
  text-decoration-color: currentColor;
}
.cta-divider {
  color: var(--text-muted);
  opacity: 0.4;
  font-size: 13px;
}

/* ============================================================
   LIVE ARTIFACTS — A: iframes (browser-chrome wrapper)
   ============================================================ */
.live-frame {
  margin: clamp(40px, 6vh, 64px) 0;
}
.lf-chrome {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  background: var(--bg-cream-2);
  border: 1px solid var(--rule-cream);
  border-bottom: 0;
  border-radius: var(--r-card) var(--r-card) 0 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--text-cream-muted);
}
.lf-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  flex-shrink: 0;
}
.lf-dot--r { background: #ff5f57; }
.lf-dot--y { background: #ffbd2e; }
.lf-dot--g { background: #28c840; }
.lf-url {
  flex: 1;
  text-align: center;
  letter-spacing: 0.05em;
  color: var(--text-cream-muted);
  font-family: var(--font-mono);
  font-size: 11px;
}
.lf-open {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
  text-decoration: none;
  background-image: none !important;
  padding: 0 !important;
}
.lf-open:hover { text-decoration: underline; text-underline-offset: 2px; }

.live-frame {
  position: relative;
}
.live-frame iframe,
.live-frame .lf-iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  min-height: 480px;
  border: 1px solid var(--rule-light);
  border-radius: 0 0 var(--r-card) var(--r-card);
  background: var(--bg-light-2);
  pointer-events: none;            /* shield by default */
  transition: opacity 0.2s var(--ease-expo);
}
.live-frame.is-active iframe,
.live-frame.is-active .lf-iframe {
  pointer-events: auto;            /* activated on click */
}

/* Click-to-interact action — filled pill inside the chrome bar.
   REST: white bg + midnight text + red dot — loud, draws the click.
   HOVER (rest): bg dims slightly to off-white so the press reads.
   ACTIVE (.is-active, after click): bg quiets to a soft grey one shade
     lighter than the chrome bar so the button recedes once the user
     has engaged the iframe; dot shifts white, text stays white.
   HOVER (active): grey brightens slightly so "click to release" still
     reads as interactive.
   Two label spans (.lf-action-full / .lf-action-short) so narrow
   viewports can swap to a shorter "Interact / Release" without JS. */
.lf-action {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--color-midnight);
  white-space: nowrap;
  background: #ffffff;
  border: 0;
  padding: 5px 12px;
  margin-right: 12px;
  border-radius: var(--r-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition:
    background 0.22s var(--ease-expo),
    color 0.22s var(--ease-expo);
  background-image: none !important;
}
.lf-action::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--accent);
  flex-shrink: 0;
  transition: background 0.22s var(--ease-expo), box-shadow 0.22s var(--ease-expo);
}
.lf-action:hover { background: #d4d4d4; }
.lf-action:hover::before {
  box-shadow: 0 0 6px rgba(228, 2, 2, 0.5);
}
.lf-action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
/* Active: chrome bg is rgba(255,255,255,0.05) ≈ #0d0d0d on the page;
   #1f1f1f sits one shade lighter so the button recedes but stays
   distinct from the chrome row. */
.live-frame.is-active .lf-action {
  background: #1f1f1f;
  color: #ffffff;
}
.live-frame.is-active .lf-action::before {
  background: #ffffff;
  box-shadow: 0 0 6px rgba(255, 255, 255, 0.45);
}
.live-frame.is-active .lf-action:hover { background: #2a2a2a; }
.live-frame.is-active .lf-action:hover::before {
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.65);
}
/* Show full label by default, short label only at narrow widths. */
.lf-action-short { display: none; }
@media (max-width: 720px) {
  .lf-action { margin-right: 10px; }
  .lf-action-full { display: none; }
  .lf-action-short { display: inline; }
}
@media (max-width: 540px) {
  /* When chrome is genuinely tight, the URL eats the most space and
     reads as decoration anyway. Hide it so the action + Open + dots
     can share the row without overflow. */
  .lf-chrome > .lf-url { display: none; }
}

/* Footer-atmosphere live-frame variant — the iframe loads the isolated
   /footer-atmosphere route on the design system, which renders ONLY the
   reactive canvas atmosphere (Loop 1 sweep) on the espresso surface. No
   nav, no footer text, no other chrome. The iframe sits in normal flow
   with an explicit height — the canvas fills its viewport and the cursor
   sweep is the whole content. */
.live-frame--footer iframe,
.live-frame--footer .lf-iframe {
  display: block;
  width: 100%;
  height: clamp(360px, 48vh, 500px);
  aspect-ratio: auto;
  min-height: 0;
  border: 1px solid var(--rule-light);
  border-top: 0;
  border-radius: 0 0 var(--r-card) var(--r-card);
  background: var(--bg-light-2);
  pointer-events: none; /* shield by default — activated via .is-active */
  /* The deployed footer-atmosphere route paints the STSL midnight
     (#14141A) as its canvas — a brand colour with a slight blue/purple
     cast. Desaturating the iframe pulls it toward neutral dark-grey so
     it reads in the same family as .how-built. The red sweep overlay
     stays legible, just less vivid. */
  filter: saturate(0.32);
  transition: opacity 0.2s var(--ease-expo), filter 0.4s var(--ease-expo);
}
/* When the user activates the iframe to play with the cursor sweep,
   restore full saturation so the live demo reads at intended colour. */
.live-frame--footer.is-active iframe,
.live-frame--footer.is-active .lf-iframe {
  filter: saturate(1);
}
.live-frame--footer.is-active iframe,
.live-frame--footer.is-active .lf-iframe {
  pointer-events: auto;
}
@media (max-width: 720px) {
  .live-frame--footer iframe,
  .live-frame--footer .lf-iframe {
    height: clamp(560px, 88vh, 720px);
  }
}

/* Tabbed live-frame variant — 5 tabs swap iframe src */
.live-frame--tabbed .lf-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 6px;
  background: var(--bg-light-2);
  border: 1px solid var(--rule-light);
  border-bottom: 0;
  border-radius: var(--r-card) var(--r-card) 0 0;
  flex-wrap: wrap;
}
.lf-tab {
  flex: 1 1 auto;
  min-width: max-content;
  padding: 10px 16px;
  border: none;
  background: transparent;
  color: var(--text-light-muted);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.005em;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.22s var(--ease-expo), color 0.22s var(--ease-expo), transform 0.22s var(--ease-expo);
  white-space: nowrap;
}
.lf-tab:hover {
  color: var(--text-light);
  background: rgba(20, 20, 20, 0.05);
  transform: translateY(-1px);
}
.lf-tab.is-active {
  background: var(--bg-light);
  color: var(--text-light);
  font-weight: 500;
  box-shadow: 0 0 0 1px var(--rule-light);
}
.lf-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.live-frame--tabbed .lf-open {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0 14px;
}
.lf-chrome--tabbed {
  border-radius: 0;
  border-top: 0;
}
.live-frame--tabbed .lf-iframe {
  border-radius: 0 0 var(--r-card) var(--r-card);
}

@media (max-width: 540px) {
  .live-frame--tabbed .lf-tabs { gap: 2px; padding: 4px; }
  .lf-tab { padding: 8px 12px; font-size: 12px; flex: 1 1 30%; }
  .live-frame--tabbed .lf-open { flex-basis: auto; text-align: center; padding: 6px 0; }
  /* Phone-sized chrome action: tighter type + 44px tap target so the
     filled pill still meets WCAG 2.5.5 once it's living inline in
     the chrome bar. Padding scales down a notch to keep the pill
     proportional to the smaller chrome row. */
  .lf-action {
    font-size: 11px;
    min-height: 44px;
    padding: 6px 12px;
  }
}
.live-frame figcaption {
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--text-cream-muted);
  margin-top: 12px;
  letter-spacing: 0.005em;
}
@media (max-width: 720px) {
  .live-frame iframe { aspect-ratio: 4 / 3; }
}

/* ============================================================
   LIVE ARTIFACTS — B: vanilla gesture rebuilds (inline)
   ============================================================ */

/* B1 — underline-draw on prose links */
.article-body p a,
.article-body li a,
.article-body figcaption a {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-size: 0% 1px;
  background-repeat: no-repeat;
  transition: background-size 0.45s var(--ease-expo);
  padding-bottom: 1px;
}
.article-body p a:hover,
.article-body li a:hover,
.article-body figcaption a:hover {
  background-size: 100% 1px;
}

/* B2 — hover-scale demo card (live gesture). White-themed. */
.demo-card {
  display: block;
  margin: clamp(28px, 4vh, 44px) 0;
  padding: clamp(20px, 3vh, 32px);
  background: #ffffff;
  color: #141414;
  border-radius: clamp(12px, 1.2vw, 18px);
  text-decoration: none;
  background-image: none !important;
  transform: scale(1) translateY(0); /* explicit base for hover interpolation */
  transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
  cursor: pointer;
  will-change: transform;
  transform-origin: center center;
}
.demo-card:hover,
.demo-card:focus-visible,
.demo-card:active {
  transform: scale(1.025) translateY(-2px) !important;
  box-shadow: 0 14px 40px -12px rgba(0, 0, 0, 0.18);
}
.demo-card-label {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(20, 20, 20, 0.55);
  margin-bottom: 8px;
  display: block;
}
.demo-card-title {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(20px, 1.8vw, 24px);
  letter-spacing: -0.015em;
  color: #141414;
  margin-bottom: 6px;
  line-height: 1.2;
}
.demo-card-meta {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 13px;
  color: rgba(20, 20, 20, 0.55);
  line-height: 1.5;
  font-style: normal;
}

/* ============================================================
   LOADER — ported from main portfolio
   ============================================================ */
#loader {
  position: fixed;
  inset: 0;
  z-index: 2000;
  /* Pinned to --color-midnight so the loader matches the portfolio
     root's loader exactly. The case-study page bg is #000 for the
     article surface, but the loader screen needs to be uniform with
     the rest of the site so navigating in doesn't flash a colour
     shift. */
  background: var(--color-midnight);
  transition: opacity 0.65s ease;
}
#loader.fade-out {
  opacity: 0;
  pointer-events: none;
}
.loader-number {
  position: absolute;
  bottom: clamp(20px, 3vh, 40px);
  left: clamp(28px, 3.8vw, 68px);
  font-family: var(--font-sans);
  font-weight: var(--fw-light);
  font-size: clamp(1.6rem, 3.5vw, 2.8rem);
  color: var(--text);
  line-height: 1;
  letter-spacing: -0.04em;
  user-select: none;
}
.loader-bar-track {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: rgba(255, 255, 255, 0.07);
}
.loader-bar-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  transition: width 0.35s ease;
}

/* ============================================================
   SCROLL TO TOP — glass circular button + red progress ring
   ============================================================ */
.scroll-top {
  position: fixed;
  left: clamp(8px, 1.4vw, 18px);
  bottom: clamp(20px, 4vh, 40px);
  z-index: 41;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background:
    conic-gradient(
      var(--accent) calc(var(--scroll-progress, 0) * 1%),
      rgba(255, 255, 255, 0.10) 0
    );
  cursor: pointer;
  display: grid;
  place-items: center;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.5s var(--ease-expo), transform 0.5s var(--ease-expo);
}
.scroll-top.is-ready {
  opacity: 1;
  transform: translateY(0);
}
.scroll-top::before {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 999px;
  background: rgba(20, 20, 20, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  transition: background 0.32s var(--ease-expo);
}
.st-arrow {
  position: relative;
  z-index: 1;
  color: rgba(255, 255, 255, 0.7);
  transition: transform 0.42s var(--ease-back), color 0.32s var(--ease-expo);
}
.scroll-top:hover .st-arrow {
  transform: translateY(-3px);
  color: var(--text);
}
.scroll-top:hover::before {
  background: rgba(20, 20, 20, 0.82);
}
.scroll-top:active .st-arrow { transform: translateY(-1px); }
.scroll-top:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
@media (max-width: 900px) {
  .scroll-top { display: none; }
}

/* ============================================================
   DAY RAIL: glass scroll-tied chapter ticker on the left edge
   ============================================================ */
.day-rail {
  position: fixed;
  left: clamp(8px, 1.4vw, 18px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 40;
  pointer-events: auto;
  opacity: 0;
  transition: opacity 0.6s var(--ease-expo);
}
.day-rail.is-ready { opacity: 1; }
.day-rail-list {
  position: relative;
  display: grid;
  gap: 4px;
  padding: 10px 6px;
  list-style: none;
  margin: 0;
  background: rgba(20, 20, 20, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
}
.day-rail-list::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 14px;
  bottom: 14px;
  width: 1px;
  background: rgba(255, 255, 255, 0.18);
  transform: translateX(-50%);
  pointer-events: none;
}
.day-rail-node {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: transparent;
  color: rgba(255, 255, 255, 0.5);
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 0.32s var(--ease-back), color 0.32s var(--ease-expo), transform 0.32s var(--ease-back);
}
.day-rail-node::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.4);
  transition: background 0.32s var(--ease-expo), transform 0.32s var(--ease-back);
}
.day-rail-node .dr-num,
.day-rail-node .dr-label { display: none; }
.day-rail-node:hover {
  color: var(--text);
  transform: scale(1.08);
}
.day-rail-node:hover::before { background: var(--text); transform: scale(1.2); }
.day-rail-node:hover .dr-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  position: absolute;
  left: calc(100% + 14px);
  white-space: nowrap;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #141414;
  background: #ffffff;
  padding: 6px 12px 6px 10px;
  border-radius: 999px;
  box-shadow: 0 8px 24px -10px rgba(0, 0, 0, 0.55);
}
.day-rail-node:hover .dr-label::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 999px;
  background: var(--accent);
  flex-shrink: 0;
}
.day-rail-node.is-active::before {
  background: var(--accent);
  transform: scale(1.4);
  box-shadow: 0 0 12px rgba(228, 2, 2, 0.6);
}
.day-rail-node:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
@media (max-width: 900px) {
  .day-rail { display: none; }
}

/* ============================================================
   REVEAL — IntersectionObserver-driven entry
   ============================================================ */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.8s var(--ease-expo), transform 0.8s var(--ease-expo);
  will-change: opacity, transform;
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  html { scroll-behavior: auto; }
}

/* ============================================================
   TOOLTIP — inline term with hover-revealed definition pill.
   Currently only used inside Day 0 (.chapter--accordion) prose.
   ============================================================ */
.tip {
  position: relative;
  /* Tooltips use the brand PURPLE — educational, not alarm. Red was
     reading as danger when it sat across multiple inline tips in the
     prose. Purple is flat (no glow) per the lila-ban rule. */
  color: var(--color-purple);
  font-weight: 500;
  border-bottom: 2px dotted var(--color-purple);
  padding: 1px 4px 1px;
  margin: 0 -2px;
  border-radius: 4px;
  background-color: rgba(155, 145, 246, 0.08);
  cursor: help;
  transition:
    background-color 0.32s cubic-bezier(0.16, 1, 0.3, 1),
    border-bottom-color 0.32s cubic-bezier(0.16, 1, 0.3, 1);
}
.tip:hover,
.tip:focus,
.tip.is-active {
  background-color: rgba(155, 145, 246, 0.18);
  border-bottom-color: rgba(155, 145, 246, 0.9);
  outline: none;
}
.tip::before,
.tip::after {
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s var(--ease-expo), transform 0.25s var(--ease-expo);
  position: absolute;
  z-index: 10;
}
.tip::before {
  content: "";
  bottom: calc(100% + 4px);
  left: 50%;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-top: 6px solid var(--color-purple);
  transform: translateX(-50%) translateY(4px);
}
.tip::after {
  content: attr(data-tip);
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: max-content;
  /* Cap pill width so it stays bounded by the prose column on desktop
     and never wider than 80vw on smaller windows. The article-body has
     overflow-x: clip as a backstop so the pill never steps out of the
     body frame, even if the tip sits very close to the column edge. */
  max-width: min(280px, 80vw);
  background: var(--color-purple);
  color: var(--color-midnight);
  padding: 10px 14px;
  border-radius: 10px;
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: -0.005em;
  line-height: 1.45;
  text-transform: none;
  text-align: left;
  white-space: normal;
  /* Tinted shadow matching midnight bg, not the pill colour — per skill */
  box-shadow: 0 12px 32px -10px rgba(20, 20, 26, 0.6);
}
.tip:hover::before,
.tip:hover::after,
.tip:focus::before,
.tip:focus::after,
.tip.is-active::before,
.tip.is-active::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* Make focus ring readable on tap focus too */
.tip:focus-visible { outline: 2px solid var(--color-purple); outline-offset: 4px; border-radius: 2px; }
@media (max-width: 540px) {
  /* On phones the pill becomes a bottom-anchored toast (viewport-fixed)
     so it can NEVER clip off the side regardless of where the tip sits
     in the line. Anchored bottom-centre with a wide max so long copy
     (like the Editorial Luxury blurb) reads in 2-3 lines. */
  .tip::after {
    position: fixed;
    bottom: 20px;
    left: 16px;
    right: 16px;
    width: auto;
    max-width: none;
    font-size: 12px;
    padding: 12px 16px;
    line-height: 1.5;
    transform: translateY(8px);
    z-index: 100;
  }
  .tip:hover::after,
  .tip:focus::after,
  .tip.is-active::after {
    transform: translateY(0);
  }
  /* Hide the caret on mobile — pill is no longer centred on the trigger. */
  .tip::before { display: none; }
}

/* ============================================================
   ULTRA-WIDE COMFORT (≥1600): only cap prose where there IS a
   right-side element to break against (Overview meta sidebar,
   chapter--swiss side-rails on Day 1 and Working with Claude).
   Default accordion chapters and standalone chapters flow the
   full grid width — no big empty right-side gutter on wide screens.
   ============================================================ */
@media (min-width: 1600px) {
  /* Overview lead reads larger — keep it tighter than body prose. */
  .chapter--overview > .chapter-body > p { max-width: 48ch; }
  /* Swiss chapters have side-rails at cols 9-12, so prose is already
     constrained to 7 cols. Cap is mostly defensive on huge viewports. */
  .chapter--swiss > .chapter-body > p,
  .chapter--swiss > .chapter-body > ul,
  .chapter--swiss > .chapter-body > ol {
    max-width: 72ch;
  }
}

/* ============================================================
   RATIO BLOCK — 1:80 cost grid. 80 cells, 79 muted, 1 red.
   Editorial composition. Eyebrow + headline + grid + legend
   + deliverables list. Reveal staggered via JS-assigned --i.
   ============================================================ */
.chapter-body > .ratio-block {
  grid-column: 1 / -1;
  margin-top: clamp(56px, 8vh, 96px);
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(20px, 3vh, 36px);
  /* Local tokens. Centralised so a single tweak retunes the block. */
  --rb-cell-bg:        rgba(244,240,230,0.025);
  --rb-cell-border:    rgba(244,240,230,0.085);
  --rb-cell-border-hi: rgba(244,240,230,0.16);
  --rb-hot:            var(--color-red);
  --rb-hot-glow:       rgba(228, 2, 2, 0.45);
  --rb-ink-mute:       rgba(244,240,230,0.55);
  --rb-rule:           rgba(244,240,230,0.12);
}

/* ── Head — eyebrow + tabloid headline ────────────────────── */
.rb-head {
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.6vh, 18px);
  padding-bottom: clamp(16px, 2.2vh, 24px);
  border-bottom: 1px solid var(--rb-rule);
}
.rb-eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rb-ink-mute);
  font-weight: 500;
}
.rb-title {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: clamp(1.6rem, 3.4vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--text-light);
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 clamp(10px, 1.4vw, 18px);
}
.rb-amount {
  font-weight: 400;
  letter-spacing: -0.035em;
}
.rb-amount--strike {
  position: relative;
  color: var(--rb-ink-mute);
  font-weight: 300;
}
.rb-amount--strike::after {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  top: 52%;
  height: 1px;
  background: var(--color-red);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.1s 0.55s var(--ease-expo);
}
.ratio-block.is-visible .rb-amount--strike::after { transform: scaleX(1); }
.rb-versus {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: 0.62em;
  color: var(--rb-ink-mute);
  letter-spacing: 0;
  align-self: center;
  position: relative;
  top: -0.04em;
}

/* ── Stage — grid + connector + floating card share this box ─ */
.rb-stage {
  position: relative;
  isolation: isolate;
}

/* ── The 80-cell grid (20 × 4) ────────────────────────────── */
.rb-grid {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: clamp(3px, 0.45vw, 6px);
  aspect-ratio: 20 / 4;
  width: 100%;
  padding: clamp(8px, 1vw, 14px);
  background:
    linear-gradient(180deg, rgba(244,240,230,0.012), rgba(244,240,230,0) 70%),
    rgba(20,20,26,0.55);
  border: 1px solid var(--rb-rule);
  border-radius: 2px;
  box-shadow:
    inset 0 1px 0 rgba(244,240,230,0.04),
    0 1px 0 rgba(0,0,0,0.3);
}

/* ── Cells — muted by default. Reveal staggered via --i. ──── */
.rb-cell {
  display: block;
  background: var(--rb-cell-bg);
  border: 1px solid var(--rb-cell-border);
  border-radius: 1.5px;
  box-shadow: inset 0 1px 0 rgba(244,240,230,0.02);
  opacity: 0;
  transform: scale(0.78);
  transition:
    opacity 0.55s var(--ease-expo),
    transform 0.55s var(--ease-expo),
    border-color 0.4s ease,
    background 0.4s ease;
  /* JS sets --i to a random 0..1 number per cell for chaotic stagger */
  transition-delay: calc(var(--i, 0) * 1.1s);
}
.ratio-block.is-visible .rb-cell {
  opacity: 1;
  transform: scale(1);
}
/* Subtle nth-child grain so the muted field doesn't look mechanical */
.rb-cell:nth-child(7n+2) { background: rgba(244,240,230,0.04); }
.rb-cell:nth-child(11n+5) { border-color: var(--rb-cell-border-hi); }

/* ── The hot cell — the punchline ─────────────────────────── */
.rb-cell--hot {
  position: relative;
  background: var(--rb-hot);
  border: 1px solid var(--rb-hot);
  border-radius: 1.5px;
  cursor: pointer;
  padding: 0;
  font: inherit;
  color: inherit;
  transform-origin: center;
  box-shadow:
    0 0 0 1px rgba(228,2,2,0.55),
    0 0 12px 1px rgba(228,2,2,0.35),
    inset 0 0 0 1px rgba(255,255,255,0.08);
  z-index: 2;
  transition:
    opacity 0.7s var(--ease-back),
    transform 0.7s var(--ease-back),
    box-shadow 0.4s ease,
    background 0.3s ease;
  /* Stagger override — hot cell is the LAST to land */
  transition-delay: 1.35s;
}
.ratio-block.is-visible .rb-cell--hot {
  animation: rb-pulse 2.6s 2s ease-in-out infinite;
}
@keyframes rb-pulse {
  0%, 100% {
    box-shadow:
      0 0 0 1px rgba(228,2,2,0.55),
      0 0 10px 1px rgba(228,2,2,0.30),
      inset 0 0 0 1px rgba(255,255,255,0.08);
  }
  50% {
    box-shadow:
      0 0 0 1px rgba(228,2,2,0.85),
      0 0 22px 4px rgba(228,2,2,0.55),
      inset 0 0 0 1px rgba(255,255,255,0.14);
  }
}
.rb-cell--hot:hover,
.rb-cell--hot:focus-visible,
.ratio-block.is-active .rb-cell--hot {
  outline: none;
  transform: scale(1.18);
  background: #ff1a1a;
  z-index: 4;
}

/* ── Connector — SVG line drawn from hot cell up to the card ─
   Pinned top-right of the stage; the hot cell sits bottom-right
   of the grid; the card sits top-right above the cell. */
.rb-connector {
  position: absolute;
  bottom: 0;
  right: 0;
  width: clamp(180px, 28%, 320px);
  height: 60%;
  pointer-events: none;
  color: var(--color-red);
  opacity: 0;
  transition: opacity 0.4s ease;
  z-index: 3;
}
.rb-connector-path {
  stroke-dasharray: 380;
  stroke-dashoffset: 380;
  transition: stroke-dashoffset 0.7s var(--ease-expo);
}
.ratio-block:hover .rb-connector,
.ratio-block:focus-within .rb-connector,
.ratio-block.is-active .rb-connector { opacity: 1; }
.ratio-block:hover .rb-connector-path,
.ratio-block:focus-within .rb-connector-path,
.ratio-block.is-active .rb-connector-path { stroke-dashoffset: 0; }

/* ── Floating card — flies out on hot-cell hover/focus ────── */
.rb-card {
  position: absolute;
  bottom: calc(100% - 16%);
  right: clamp(40px, 6%, 80px);
  width: clamp(220px, 32%, 320px);
  padding: clamp(14px, 1.6vw, 20px) clamp(16px, 1.8vw, 22px);
  background: var(--text-light);
  color: var(--color-midnight);
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(0,0,0,0.4),
    0 18px 36px -12px rgba(0,0,0,0.55),
    0 2px 6px rgba(0,0,0,0.18);
  opacity: 0;
  transform: translate(12px, 16px) scale(0.94);
  transform-origin: bottom right;
  transition:
    opacity 0.45s var(--ease-back),
    transform 0.55s var(--ease-back);
  pointer-events: none;
  z-index: 5;
}
.ratio-block:hover .rb-card,
.ratio-block:focus-within .rb-card,
.ratio-block.is-active .rb-card {
  opacity: 1;
  transform: translate(0, 0) scale(1);
  pointer-events: auto;
}
.rb-card-tag {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-red);
  padding: 3px 7px;
  border: 1px solid var(--color-red);
  border-radius: 999px;
  margin-bottom: 12px;
}
.rb-card-amount {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  letter-spacing: -0.03em;
  line-height: 1;
  margin: 0 0 8px;
  color: var(--color-midnight);
}
.rb-card-usd {
  font-weight: 400;
  font-size: 0.62em;
  color: rgba(20,20,26,0.55);
  letter-spacing: -0.015em;
}
.rb-card-line {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 400;
  color: var(--color-midnight);
  margin: 0 0 8px;
  line-height: 1.4;
}
.rb-card-foot {
  font-family: var(--font-sans);
  font-size: 11.5px;
  color: rgba(20,20,26,0.55);
  margin: 0;
  line-height: 1.4;
  letter-spacing: 0.005em;
}
.rb-card-foot em {
  font-style: italic;
  color: var(--color-red);
  font-weight: 500;
}

/* ── Legend — caption directly under grid ─────────────────── */
.rb-legend {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: clamp(10px, 1.4vh, 16px) 0 0;
  font-family: var(--font-sans);
  font-size: 12.5px;
  letter-spacing: 0.01em;
  color: var(--rb-ink-mute);
  border-top: 1px solid var(--rb-rule);
}
.rb-legend-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  background: var(--color-red);
  border-radius: 1.5px;
  flex: 0 0 10px;
  box-shadow: 0 0 6px rgba(228,2,2,0.5);
}

/* ── Deliverables — dense grid below the visual block ─────── */
.rb-deliverables {
  margin-top: clamp(20px, 2.6vh, 32px);
  padding-top: clamp(18px, 2.4vh, 26px);
  border-top: 1px solid var(--rb-rule);
}
.rb-deliv-eyebrow {
  font-family: var(--font-sans);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rb-ink-mute);
  font-weight: 500;
  margin: 0 0 clamp(14px, 1.8vh, 22px);
}
.rb-deliv-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.rb-deliv-list li {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: clamp(14px, 1.8vh, 20px) clamp(12px, 1.4vw, 18px);
  border-right: 1px solid var(--rb-rule);
  border-bottom: 1px solid var(--rb-rule);
  min-height: clamp(78px, 10vh, 108px);
}
.rb-deliv-list li:nth-child(4n) { border-right: none; }
.rb-deliv-list li:nth-last-child(-n+4) { border-bottom: none; }
.rb-deliv-num {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: clamp(1.6rem, 2.6vw, 2.2rem);
  letter-spacing: -0.035em;
  color: var(--text-light);
  line-height: 1;
}
.rb-deliv-label {
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 400;
  color: var(--rb-ink-mute);
  line-height: 1.35;
  letter-spacing: 0.005em;
}

/* ── Mobile — 8 × 10 grid, tap instead of hover ───────────── */
@media (max-width: 720px) {
  .chapter-body > .ratio-block { margin-top: clamp(40px, 6vh, 64px); }
  .rb-grid {
    grid-template-columns: repeat(8, 1fr);
    grid-template-rows: repeat(10, 1fr);
    aspect-ratio: 8 / 10;
    gap: 4px;
  }
  .rb-card {
    width: min(280px, 78%);
    bottom: auto;
    top: 50%;
    left: 50%;
    right: auto;
    transform: translate(-50%, -50%) scale(0.94);
  }
  .ratio-block:hover .rb-card,
  .ratio-block:focus-within .rb-card,
  .ratio-block.is-active .rb-card {
    transform: translate(-50%, -50%) scale(1);
  }
  .rb-connector { display: none; }
  .rb-deliv-list { grid-template-columns: repeat(2, 1fr); }
  .rb-deliv-list li:nth-child(4n) { border-right: 1px solid var(--rb-rule); }
  .rb-deliv-list li:nth-child(2n) { border-right: none; }
  .rb-deliv-list li:nth-last-child(-n+4) { border-bottom: 1px solid var(--rb-rule); }
  .rb-deliv-list li:nth-last-child(-n+2) { border-bottom: none; }
  .rb-title { font-size: clamp(1.4rem, 7vw, 2rem); }
}

/* ── Reduced motion ───────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .rb-cell, .rb-cell--hot {
    transition: none !important;
    animation: none !important;
    opacity: 1;
    transform: none;
  }
  .rb-amount--strike::after { transition: none; transform: scaleX(1); }
  .rb-card, .rb-connector, .rb-connector-path { transition: none; }
}

/* ── Job 1: agents-skills slimmed for sticky right rail (cols 9-12).
   Vertical orientation, condensed rows, smaller numerals.            */
.chapter-side--agents { max-height: none; overflow: visible; }
.agents-skills--rail {
  margin: 0;
  padding: clamp(14px, 1.8vh, 18px) clamp(14px, 1.4vw, 18px) clamp(16px, 2vh, 20px);
  border-radius: clamp(12px, 1vw, 14px);
}
.agents-skills--rail .as-head {
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
  padding-bottom: 12px;
}
.agents-skills--rail .as-eyebrow { font-size: 9.5px; letter-spacing: 0.2em; }
.agents-skills--rail .as-toggle { padding: 3px; gap: 2px; }
.agents-skills--rail .as-toggle-btn { font-size: 11px; padding: 5px 12px; }
.agents-skills--rail .as-list { gap: 0; }
.agents-skills--rail .as-list li {
  grid-template-columns: 1fr;
  gap: 2px;
  padding: 8px 0;
}
.agents-skills--rail .as-name { font-size: 12.5px; }
.agents-skills--rail .as-desc { font-size: 11.5px; line-height: 1.4; }

/* ============================================================
   DAY-COST SCRUBBER — one input drives both cards. Days on the
   left (milestone list lights up as the scrubber crosses each
   day's threshold), Cost on the right (two stacked bars track
   studio vs Claude spend in real time). Auto-walks once on
   reveal, then becomes user-controllable.
   ============================================================ */
.day-cost {
  margin: clamp(40px, 6vh, 72px) 0 0;
  padding: clamp(20px, 2.4vw, 32px);
  background: linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.015));
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.06), 0 1px 0 rgba(0,0,0,0.3);
  display: flex;
  flex-direction: column;
  gap: clamp(18px, 2.2vh, 28px);
  color: #FFFFFF;
}

/* ── Header ─────────────────────────────────────────────────── */
.day-cost .dc-head { display: flex; flex-direction: column; gap: 8px; }
.day-cost .dc-eyebrow {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; font-weight: 500; letter-spacing: 0.24em;
  text-transform: uppercase; color: var(--color-yellow);
  margin: 0;
}
.day-cost .dc-headline {
  font-family: var(--font-sans); font-weight: 300;
  font-size: clamp(1.3rem, 2.2vw, 2rem);
  line-height: 1.18; letter-spacing: -0.02em;
  color: #FFFFFF; margin: 0; max-width: 32ch;
}
.day-cost .dc-rationale {
  font-family: var(--font-sans); font-weight: 300;
  font-size: 12px; line-height: 1.5;
  letter-spacing: 0.01em; font-style: italic;
  color: rgba(255,255,255,0.5);
  margin: 6px 0 0; max-width: 52ch;
}

/* ── Scrubber ───────────────────────────────────────────────── */
.day-cost .dc-scrubber {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "readout replay"
    "slider  slider"
    "marks   marks";
  align-items: center;
  gap: 10px 14px;
  padding: 14px 0 4px;
  border-top: 1px solid rgba(255,255,255,0.08);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.day-cost .dc-day-readout {
  grid-area: readout;
  display: flex; align-items: baseline; gap: 8px;
}
.day-cost .dc-day-num {
  font-family: var(--font-sans); font-weight: 300;
  font-size: clamp(28px, 3vw, 40px); line-height: 1;
  letter-spacing: -0.03em; color: var(--color-yellow);
  font-variant-numeric: tabular-nums;
}
.day-cost .dc-day-label {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.55);
}
.day-cost .dc-slider {
  grid-area: slider;
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 22px; margin: 0;
  background: transparent; cursor: pointer; outline: none;
}
.day-cost .dc-slider::-webkit-slider-runnable-track {
  height: 2px; border-radius: 1px;
  background: linear-gradient(
    to right,
    var(--accent) 0%, var(--accent) var(--dc-progress, 0%),
    rgba(255,255,255,0.18) var(--dc-progress, 0%), rgba(255,255,255,0.18) 100%
  );
}
.day-cost .dc-slider::-moz-range-track {
  height: 2px; border-radius: 1px;
  background: rgba(255,255,255,0.18);
}
.day-cost .dc-slider::-moz-range-progress {
  height: 2px; border-radius: 1px; background: var(--accent);
}
.day-cost .dc-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent);
  border: 2px solid #14141a;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18), 0 4px 10px rgba(228,2,2,0.45);
  margin-top: -6px;
  transition: transform 0.18s cubic-bezier(0.22,1,0.36,1);
}
.day-cost .dc-slider::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent);
  border: 2px solid #14141a;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18), 0 4px 10px rgba(228,2,2,0.45);
}
.day-cost .dc-slider:hover::-webkit-slider-thumb,
.day-cost .dc-slider:focus-visible::-webkit-slider-thumb { transform: scale(1.15); }
.day-cost .dc-slider:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 6px; border-radius: 2px;
}
.day-cost .dc-slider.is-autoplay { pointer-events: none; }
.day-cost .dc-day-marks {
  grid-area: marks;
  display: flex; justify-content: space-between;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 9px; letter-spacing: 0.1em;
  color: rgba(255,255,255,0.4);
}
.day-cost .dc-day-marks span { display: block; }
.day-cost .dc-replay {
  grid-area: replay;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.65);
  background: transparent;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 3px;
  padding: 6px 12px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}
.day-cost .dc-replay:hover,
.day-cost .dc-replay:focus-visible {
  color: var(--color-yellow);
  border-color: var(--color-yellow);
  outline: none;
}

/* ── Cards (two columns) ────────────────────────────────────── */
.day-cost .dc-cards {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(12px, 1.4vw, 20px);
  background: transparent;
}
.day-cost .dc-card {
  position: relative;
  padding: clamp(18px, 2vw, 24px);
  background: #000000;
  border: 1px solid rgba(255,255,255,0.14);
  /* Was 4px (token --r-sharp); aligned to --r-card so the cost + burn
     cards match the small-card radius tier used elsewhere. */
  border-radius: var(--r-card);
  display: flex; flex-direction: column; gap: 14px;
  min-height: 240px;
}
.day-cost .dc-card-eyebrow {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.5); margin: 0;
}

/* ── Days card (milestone list) ─────────────────────────────── */
.day-cost .dc-milestones {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 8px;
  flex: 1;
}
.day-cost .dc-milestones li {
  display: grid; grid-template-columns: 56px 1fr;
  gap: 12px; align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  opacity: 0.32;
  transition: opacity 0.28s cubic-bezier(0.22,1,0.36,1),
              color 0.28s cubic-bezier(0.22,1,0.36,1);
}
.day-cost .dc-milestones li:last-child { border-bottom: 0; }
.day-cost .dc-milestones li.is-past { opacity: 0.7; color: #FFFFFF; }
.day-cost .dc-milestones li.is-active {
  opacity: 1;
  color: var(--color-yellow);
}
.day-cost .dc-mile-day {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase;
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.day-cost .dc-mile-text {
  font-family: var(--font-sans); font-size: 13px; line-height: 1.45;
  color: inherit;
  font-weight: 400;
}
.day-cost .dc-card-state {
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  margin: 0; padding-top: 10px;
  border-top: 1px solid rgba(255,255,255,0.08);
  display: flex; align-items: center; gap: 8px;
}
.day-cost .dc-card-state[data-state="shipped"] {
  color: var(--color-yellow);
}
.day-cost .dc-card-state[data-state="shipped"]::before {
  content: '';
  width: 10px; height: 10px;
  background: var(--color-yellow);
  border-radius: 50%;
  display: inline-block;
}

/* ── Cost card ──────────────────────────────────────────────── */
.day-cost .dc-card--cost { gap: 28px; }
.day-cost .dc-cost-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  grid-template-areas:
    "label  amount"
    "bar    bar";
  gap: 10px 12px;
  align-items: baseline;
}
.day-cost .dc-cost-label {
  grid-area: label;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.55);
}
.day-cost .dc-cost-amount-wrap {
  grid-area: amount;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.day-cost .dc-cost-amount {
  font-family: var(--font-sans); font-weight: 400;
  font-size: clamp(20px, 1.8vw, 24px); line-height: 1.1;
  letter-spacing: -0.015em;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
  text-align: right;
  transition: color 0.28s ease;
}
.day-cost .dc-cost-naira {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 12px;
  letter-spacing: 0;
  color: rgba(255,255,255,0.45);
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
}
.day-cost .dc-cost-row:nth-child(2) .dc-cost-amount.is-live { color: var(--accent); }
.day-cost .dc-cost-row:nth-child(3) .dc-cost-amount.is-live { color: var(--color-purple); }
.day-cost .dc-bar {
  grid-area: bar;
  height: 6px; width: 100%;
  background: rgba(255,255,255,0.08);
  border-radius: 8px; overflow: hidden;
}
.day-cost .dc-bar-fill {
  height: 100%; width: 0%;
  border-radius: 8px;
  transition: width 0.12s cubic-bezier(0.22, 1, 0.36, 1);
}
.day-cost .dc-bar-fill--studio { background: var(--accent); }
.day-cost .dc-bar-fill--claude { background: var(--color-purple); }
.day-cost .dc-card-summary {
  font-family: var(--font-sans); font-size: 12px; line-height: 1.5;
  font-weight: 400;
  color: rgba(255,255,255,0.55);
  margin: auto 0 0; padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.08);
}

/* ── Burn-gauge card (race-car HUD instrument cluster) ──────── */
.day-cost .dc-card--burn { gap: 18px; }
.day-cost .dc-card--burn .dc-card-eyebrow-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
/* Engine pulse dot — pulses faster as gauge fills. --pulse-rate from JS. */
.day-cost .dc-pulse-dot {
  --pulse-rate: 1.4s;
  --pulse-color: rgba(255,255,255,0.85);
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--pulse-color);
  box-shadow: 0 0 8px var(--pulse-color);
  animation: dcEnginePulse var(--pulse-rate) cubic-bezier(0.45, 0, 0.15, 1) infinite;
  flex-shrink: 0;
}
@keyframes dcEnginePulse {
  0%, 100% { opacity: 0.35; transform: scale(0.85); }
  50%      { opacity: 1;    transform: scale(1.15); }
}
.day-cost .dc-gauge {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  flex: 1;
  justify-content: center;
  /* Subtle CRT/HUD scanline texture inside the gauge well. */
  background-image: repeating-linear-gradient(
    to bottom,
    rgba(255,255,255,0.05) 0px,
    rgba(255,255,255,0.05) 1px,
    transparent 1px,
    transparent 3px
  );
  background-position: center;
  background-size: 100% 100%;
  border-radius: 8px;
  padding: 6px 4px 0;
}
/* Outer ring — thin white-low-alpha base with a red overlay at 80–100%. */
.day-cost .dc-gauge-outer-bg {
  stroke: rgba(255,255,255,0.10);
  stroke-width: 1.5;
  stroke-linecap: round;
}
.day-cost .dc-gauge-outer-redline {
  --redline-fill: 0;
  stroke: var(--color-red);
  stroke-width: 1.8;
  stroke-linecap: round;
  /* Show only the redline zone (last 20%) when --redline-fill engaged. */
  stroke-dasharray: calc(var(--redline-fill) * 20) 100;
  stroke-dashoffset: -80;
  opacity: calc(var(--redline-fill));
  filter: drop-shadow(0 0 4px rgba(228,2,2,0.55));
  transition: stroke-dasharray 0.4s cubic-bezier(0.45, 0, 0.15, 1),
              opacity 0.4s cubic-bezier(0.45, 0, 0.15, 1);
}
.day-cost .dc-gauge-svg {
  width: 100%;
  max-width: 260px;
  height: auto;
  display: block;
  overflow: visible;
}
.day-cost .dc-gauge-bg {
  stroke: rgba(255,255,255,0.08);
  stroke-width: 6;
  stroke-linecap: round;
}
/* Single foreground arc with gradient stroke. pathLength=100 means
   stroke-dasharray "X 100" reveals X% of the arc. --gauge-fill (0..1) is
   driven from JS lerp; --gauge-glow-blur and --gauge-glow-color are also
   updated per-frame so the drop-shadow filter interpolates smoothly. */
.day-cost .dc-gauge-fg {
  --gauge-glow-blur: 3px;
  --gauge-glow-color: rgba(255, 255, 255, 0.35);
  stroke-width: 6;
  stroke-linecap: round;
  fill: none;
  /* stroke-dasharray + stroke-dashoffset are set via setAttribute() in JS
     using the measured path length (getTotalLength()). Defining them in CSS
     would override the attribute on every reflow and break the scroll-driven
     fill — leave them out. CSS only owns the transition. */
  filter: drop-shadow(0 0 var(--gauge-glow-blur) var(--gauge-glow-color));
  transition: stroke-dashoffset 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.6s cubic-bezier(0.45, 0, 0.15, 1);
  will-change: stroke-dashoffset;
}
/* Tick hierarchy: short = every 10% (subtle), long = quarter ticks (brighter). */
.day-cost .dc-gauge-ticks-short line {
  stroke: rgba(255,255,255,0.28);
  stroke-width: 1;
  stroke-linecap: round;
  transition: stroke 0.3s ease;
}
.day-cost .dc-gauge-ticks-short line.is-passed {
  stroke: rgba(255,255,255,0.7);
}
.day-cost .dc-gauge-ticks-long line {
  stroke: rgba(255,255,255,0.55);
  stroke-width: 1.4;
  stroke-linecap: round;
  transition: stroke 0.3s ease;
}
.day-cost .dc-gauge-ticks-long line.is-passed {
  stroke: var(--color-yellow);
}
.day-cost .dc-gauge-ticks-long line.is-passed.is-redline {
  stroke: var(--color-red);
}
.day-cost .dc-gauge-needle {
  --needle-glow: rgba(228, 2, 2, 0);
  stroke: var(--color-red);
  stroke-width: 2;
  stroke-linecap: round;
  transform-origin: 100px 100px;
  transform: rotate(-90deg);
  filter: drop-shadow(0 0 4px var(--needle-glow));
  transition: transform 0.9s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.6s cubic-bezier(0.45, 0, 0.15, 1);
  will-change: transform;
}
/* Sweep highlight — duplicate ghost-needle that lags behind the live needle. */
.day-cost .dc-gauge-needle-trail {
  stroke: var(--color-yellow);
  stroke-width: 6;
  stroke-linecap: round;
  opacity: 0.28;
  transform-origin: 100px 100px;
  transform: rotate(-90deg);
  /* Heavy blur for a true motion-blur trail effect. */
  filter: blur(5px);
  transition: transform 1.2s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.6s ease;
  pointer-events: none;
  will-change: transform;
}
.day-cost .dc-gauge-pivot {
  fill: #FFFFFF;
  stroke: rgba(20,20,26,0.6);
  stroke-width: 1;
  transition: fill 0.2s cubic-bezier(0.45, 0, 0.15, 1),
              r 0.2s cubic-bezier(0.45, 0, 0.15, 1);
}
/* Reset-pulse ring on the pivot. Triggered by adding .is-pulsing on .dc-gauge.
   The ring expands and fades — reads as a fresh-session "pop". */
.day-cost .dc-gauge-pulse {
  stroke: var(--color-yellow);
  stroke-width: 1.4;
  opacity: 0;
  transform-origin: 100px 100px;
  transform: scale(1);
  pointer-events: none;
}
.day-cost .dc-gauge.is-pulsing .dc-gauge-pulse {
  animation: dcPulseRing 600ms cubic-bezier(0.45, 0, 0.15, 1) forwards;
}
.day-cost .dc-gauge.is-pulsing .dc-gauge-pivot {
  animation: dcPulsePivot 600ms cubic-bezier(0.45, 0, 0.15, 1);
}
@keyframes dcPulseRing {
  0%   { opacity: 0;   transform: scale(1);   }
  20%  { opacity: 0.9; transform: scale(1.4); }
  100% { opacity: 0;   transform: scale(3.6); }
}
@keyframes dcPulsePivot {
  0%   { fill: #FFFFFF; }
  35%  { fill: var(--color-yellow); }
  100% { fill: #FFFFFF; }
}
/* "new session" label that fades in/out under the gauge during pulses. */
.day-cost .dc-gauge-pulse-label {
  font-family: var(--font-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--color-yellow);
  margin: 0;
  height: 12px;
  opacity: 0;
  transition: opacity 200ms cubic-bezier(0.45, 0, 0.15, 1);
  text-align: center;
}
.day-cost .dc-gauge-pulse-label.is-visible {
  opacity: 1;
  transition: opacity 120ms cubic-bezier(0.45, 0, 0.15, 1);
}
.day-cost .dc-gauge-readout {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-top: -4px;
}
.day-cost .dc-gauge-readout-label {
  font-family: var(--font-sans);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
}
.day-cost .dc-gauge-readout-main {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.day-cost .dc-gauge-num {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(28px, 3.2vw, 36px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: #FFFFFF;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
  transform: scale(var(--token-scale, 0));
  transform-origin: center center;
  transition: color 0.28s ease,
              transform 0.12s cubic-bezier(0.22, 1, 0.36, 1);
}
.day-cost .dc-gauge-num.is-burning  { color: var(--color-yellow); }
.day-cost .dc-gauge-num.is-exhausted { color: var(--color-red); }
/* Redline warning pill — fades in above 80% with a slow opacity pulse. */
.day-cost .dc-gauge-readout-main { position: relative; }
.day-cost .dc-redline-pill {
  font-family: var(--font-sans);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #FFFFFF;
  background: var(--color-red);
  border: 1px solid rgba(255,255,255,0.25);
  padding: 3px 7px;
  border-radius: 3px;
  /* Static HUD decoration — always visible at calm intensity. */
  --hud-static-opacity: 0.75;
  /* Absolute so the number stays centered when the pill is hidden. The pill
     hangs to the right of the readout once redline triggers. */
  position: absolute;
  left: calc(100% + 8px);
  top: 50%;
  transform: translate(0, -50%);
  opacity: 0.75;
  pointer-events: none;
  white-space: nowrap;
}
.day-cost .dc-redline-pill.is-active {
  opacity: 1;
}
@keyframes dcRedlineThrob {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1;   }
}
.day-cost .dc-gauge-label {
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.55);
  font-variant-numeric: tabular-nums;
}
.day-cost .dc-gauge-status {
  font-family: var(--font-sans);
  font-size: 12px;
  line-height: 1.5;
  font-weight: 400;
  color: rgba(255,255,255,0.55);
  margin: auto 0 0;
  padding-top: 12px;
  border-top: 1px solid rgba(255,255,255,0.08);
  transition: color 0.28s ease;
}
.day-cost .dc-gauge-status.is-burning  { color: var(--color-yellow); }
.day-cost .dc-gauge-status.is-exhausted { color: var(--color-red); }

/* ── Mobile: collapse to single column ──────────────────────── */
@media (max-width: 720px) {
  .day-cost { padding: 18px; gap: 16px; }
  .day-cost .dc-cards { grid-template-columns: 1fr; }
  .day-cost .dc-card + .dc-card { border-left: 0; border-top: 1px solid rgba(255,255,255,0.10); }
  .day-cost .dc-card { min-height: 0; }
  .day-cost .dc-scrubber {
    grid-template-columns: 1fr;
    grid-template-areas:
      "readout"
      "slider"
      "marks"
      "replay";
  }
  .day-cost .dc-replay { justify-self: start; }
  .day-cost .dc-day-marks { font-size: 8.5px; }
}

/* ── Reduced motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .day-cost .dc-bar-fill,
  .day-cost .dc-milestones li,
  .day-cost .dc-cost-amount,
  .day-cost .dc-gauge-fg,
  .day-cost .dc-gauge-needle,
  .day-cost .dc-gauge-needle-trail,
  .day-cost .dc-gauge-num,
  .day-cost .dc-gauge-outer-redline { transition: none; }
  .day-cost .dc-gauge.is-pulsing .dc-gauge-pulse,
  .day-cost .dc-gauge.is-pulsing .dc-gauge-pivot,
  .day-cost .dc-pulse-dot,
  .day-cost .dc-redline-pill.is-active { animation: none; }
}
