/* Scene styles extracted from the home page in W2. Linked from pages that received moved markup. */
:root {
  --cross: #b0433c;
  --fs-scene: clamp(2.3rem, 5.4vw, 4.4rem);
  --fs-eyebrow: clamp(0.84rem, 0.62vw + 0.68rem, 1.05rem);
  --space-section: clamp(4.5rem, 9vw, 9.5rem);
  --space-tight: clamp(2.5rem, 4.5vw, 4.5rem);
  --radius-lg: 22px;
}

/* W3 keeps the historical scene locator on each moved destination for the route/copy contract.
   The rebuilt hero owns its layout, so old scene-specific padding and colour do not leak into it. */
section.detail-hero.w3-detail-scene {
  padding: clamp(42px, 7vw, 82px) 0 clamp(48px, 8vw, 88px);
  overflow: visible;
  background: var(--bg);
  color: var(--text);
}

section.detail-hero.w3-detail-scene .sketch-title {
  font-size: clamp(1.05rem, 2.4vw, 1.35rem);
  line-height: 1.2;
}

  /* ---------- Scroll reveal (see head script for how js-armed gets added) ---------- */

  @media (prefers-reduced-motion: no-preference) {
    html.js-armed .reveal-up,
    html.js-armed .reveal-scale {
      opacity: 0;
      transition: opacity 0.8s cubic-bezier(0.2, 0.7, 0.2, 1), transform 0.8s cubic-bezier(0.2, 0.7, 0.2, 1);
    }
    html.js-armed .reveal-up { transform: translateY(26px); }
    html.js-armed .reveal-scale { transform: scale(0.94) translateY(12px); }
    html.js-armed .in-view.reveal-up,
    html.js-armed .in-view.reveal-scale { opacity: 1; transform: none; }
    html.js-armed .reveal-delay-1 { transition-delay: 0.1s; }
    html.js-armed .reveal-delay-2 { transition-delay: 0.22s; }

    @supports (animation-timeline: view()) {
      .reveal-up {
        animation: reveal-in-up linear both;
        animation-timeline: view();
        animation-range: entry 5% cover 38%;
      }
      .reveal-scale {
        animation: reveal-in-scale linear both;
        animation-timeline: view();
        animation-range: entry 5% cover 42%;
      }
      .reveal-delay-1 { animation-delay: 0.06s; }
      .reveal-delay-2 { animation-delay: 0.14s; }
    }
  }

  @keyframes reveal-in-up {
    from { opacity: 0; transform: translateY(26px); }
    to { opacity: 1; transform: none; }
  }
  @keyframes reveal-in-scale {
    from { opacity: 0; transform: scale(0.94) translateY(12px); }
    to { opacity: 1; transform: none; }
  }


  /* HORIZONTAL OVERFLOW CONTAINMENT (found in this round's proof pass, pre-existing since the
     3D compositions landed). The ladder and the sentiment crawl both sit on a perspective and
     recede in Z, and the visual overflow of those transformed boxes was extending the document
     64px past a 375 viewport, which is a real sideways scroll on a phone. overflow-x: clip
     contains the bleed WITHOUT creating a scroll container, so the sentiment scene's sticky pin
     keeps working; overflow: hidden here would have broken the pin. Nothing in either composition
     is intended to leave the frame sideways, so nothing is lost. */
  .scene-ladder-intro, .scene-sentiment { overflow-x: clip; }

  /* ---------- Generic scene scaffolding ---------- */

  .scene {
    padding: var(--space-section) 0;
  }

  .scene-inner {
    max-width: 780px;
    margin: 0 auto;
    text-align: center;
    padding: 0 24px;
  }

  .scene h2 {
    font-size: var(--fs-scene);
    line-height: 1.04;
    letter-spacing: -0.025em;
    margin: 0 0 18px;
    font-weight: 800;
  }

  .scene .support {
    font-size: clamp(1.02rem, 1.7vw, 1.2rem);
    color: var(--text-muted);
    max-width: 560px;
    margin: 18px auto 0;
  }

  /* ---------- Full-bleed screenshot scale system (item 4) ----------
     Edge-to-edge product visual, claim text sits above it. Breaks out of .scene-inner's padded
     container with the standard 100vw/-50vw trick, so it works regardless of parent width.
     Legibility rule: the crop images themselves are already tightly cropped to just the legible
     content (see build notes), and the height here is held to a floor via clamp() so the text
     never gets scaled down past comfortable reading size — at narrow widths object-fit:cover
     crops from the right rather than shrinking the whole frame, keeping the title/opening words
     and the primary action anchored on the left. At desktop widths the clamp's vw component
     lands close to the crop's natural aspect ratio, so effectively the full frame shows,
     "massive and fully legible," with none of the surrounding app chrome. */
  .full-bleed {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    overflow: hidden;
  }
  .full-bleed img {
    display: block;
    width: 100%;
    object-fit: cover;
    object-position: left top;
  }

  /* ---------- Probation dossier (v5 item 2, Mike: "the sheet to show for probation actually is
     the viewer - make up a profile picture and a name, and put them on probation and show the top
     of the skeumorphic page; paperclip, 'PROBATION' stamp and all. That's a better image for this
     - full width please").

     Replaces the full-bleed zoom of the standing modal that used to live here (a 134KB JPEG,
     deleted with it). Built entirely in CSS + inline SVG, so it stays crisp at any width and the
     legibility rule is satisfied by construction rather than by cropping a bitmap. It is the TOP
     of a paper viewer file: the sheet runs off the bottom edge of the band, cropped, so it reads
     as a page that continues. Devon Ellery is the page's established invented troll (he already
     appears in the notification list and the sentiment crawl); the avatar is a drawn illustration,
     never a photograph of anyone. Every line on the sheet is a real product behaviour. ---------- */

  .dossier-bleed {
    position: relative;
    /* the desk the file is lying on: a shade under the scene's own ground, with a pooled warm
       light behind the sheet so the paper reads as lit rather than pasted on. */
    background:
      radial-gradient(70% 90% at 50% 8%, rgba(224, 178, 118, 0.16), transparent 70%),
      #0c0b06;
    padding-top: clamp(20px, 4.5vw, 68px);
    margin-top: clamp(14px, 4vw, 54px);
  }
  .dossier {
    width: min(1560px, 94vw);
    margin: 0 auto;
  }
  .dossier-sheet {
    position: relative;
    /* paper: a warm cream wash plus a very faint horizontal fibre grain */
    background:
      repeating-linear-gradient(0deg, rgba(122, 96, 58, 0.032) 0 1px, transparent 1px 3px),
      radial-gradient(130% 100% at 50% 0%, #fdf8ee 0%, #f2e8d4 62%, #e9dcc2 100%);
    color: #2a2419;
    /* .scene-inner centres everything; a paper file is a left-aligned document. */
    text-align: left;
    border-radius: 5px 5px 0 0;
    padding: clamp(34px, 4vw, 60px) clamp(24px, 3.6vw, 64px) clamp(46px, 6vw, 92px);
    box-shadow: 0 -1px 0 rgba(255, 255, 255, 0.5) inset, 0 34px 90px rgba(0, 0, 0, 0.6);
    /* cropped by .full-bleed's overflow:hidden: this is the top of the page, not the whole page */
    margin-bottom: clamp(-46px, -3vw, -26px);
  }

  /* Paperclip, hooked over the top edge of the sheet. */
  .dossier-clip {
    position: absolute;
    /* sized and lifted so the clip's tail stops above the avatar rather than crossing the face */
    top: clamp(-36px, -2.8vw, -22px);
    left: clamp(18px, 2.6vw, 50px);
    width: clamp(42px, 3.4vw, 62px);
    height: auto;
    transform: rotate(-6deg);
    filter: drop-shadow(0 4px 6px rgba(40, 30, 12, 0.35));
  }

  .dossier-kicker {
    margin: 0 0 clamp(18px, 2.4vw, 28px);
    padding-left: clamp(62px, 8vw, 132px);
    font-size: clamp(0.66rem, 1vw, 0.78rem);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.22em;
    color: #9c8256;
  }

  .dossier-head {
    display: flex;
    align-items: center;
    gap: clamp(16px, 2vw, 28px);
    padding-bottom: clamp(20px, 2.4vw, 30px);
    border-bottom: 2px solid rgba(122, 96, 58, 0.28);
  }
  .dossier-avatar {
    flex-shrink: 0;
    width: clamp(74px, 8vw, 126px);
    height: clamp(74px, 8vw, 126px);
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(60, 44, 18, 0.28);
  }
  .dossier-avatar svg { display: block; width: 100%; height: 100%; }
  .dossier-name {
    margin: 0;
    font-size: clamp(1.7rem, 3.4vw, 3.2rem);
    line-height: 1.04;
    font-weight: 800;
    letter-spacing: -0.025em;
    color: #201b12;
  }
  .dossier-meta {
    margin: 8px 0 0;
    font-size: clamp(0.86rem, 1.15vw, 1.05rem);
    color: #6b5c42;
  }

  /* The red inked stamp: rotated, double-ruled, and roughened by an overlay of paper-coloured
     streaks and specks so it reads as pressed ink rather than a coloured box. */
  .dossier-stamp {
    position: absolute;
    top: clamp(26px, 3.4vw, 58px);
    right: clamp(18px, 3vw, 62px);
    transform: rotate(-8.5deg);
    border: 4px double #b0342a;
    border-radius: 7px;
    padding: clamp(7px, 0.9vw, 14px) clamp(14px, 1.8vw, 30px);
    color: #b0342a;
    font-size: clamp(1.15rem, 2.6vw, 2.5rem);
    font-weight: 900;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: 1;
    opacity: 0.88;
  }
  .dossier-stamp::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 7px;
    pointer-events: none;
    background:
      radial-gradient(circle at 14% 28%, rgba(250, 244, 232, 0.85) 0 2.5px, transparent 3.5px),
      radial-gradient(circle at 62% 18%, rgba(250, 244, 232, 0.7) 0 2px, transparent 3px),
      radial-gradient(circle at 84% 74%, rgba(250, 244, 232, 0.8) 0 3px, transparent 4px),
      radial-gradient(circle at 33% 86%, rgba(250, 244, 232, 0.7) 0 2px, transparent 3px),
      repeating-linear-gradient(74deg, rgba(250, 244, 232, 0) 0 4px, rgba(250, 244, 232, 0.5) 4px 5px, rgba(250, 244, 232, 0) 5px 11px);
  }

  /* Narrow screens: the stamp has to shrink into the top-right corner above the kicker, or it
     lands across the viewer's name. */
  @media (max-width: 620px) {
    .dossier-stamp {
      top: 12px;
      right: 12px;
      border-width: 3px;
      padding: 5px 11px;
      font-size: 0.88rem;
      letter-spacing: 0.1em;
    }
  }

  .dossier-rows {
    margin: clamp(22px, 2.6vw, 34px) 0 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(18px, 2.4vw, 34px) clamp(28px, 4vw, 72px);
  }
  @media (max-width: 700px) {
    .dossier-rows { grid-template-columns: 1fr; }
  }
  .dossier-row { margin: 0; }
  .dossier-row dt {
    font-size: clamp(0.64rem, 0.9vw, 0.76rem);
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: #9c8256;
    margin-bottom: 7px;
  }
  .dossier-row dd {
    margin: 0;
    font-size: clamp(1rem, 1.45vw, 1.35rem);
    line-height: 1.35;
    font-weight: 600;
    color: #2a2419;
  }
  .dossier-chip {
    display: inline-block;
    padding: 5px 16px;
    border-radius: 999px;
    background: rgba(176, 52, 42, 0.12);
    border: 1px solid rgba(176, 52, 42, 0.45);
    color: #96291f;
    font-weight: 800;
    letter-spacing: 0.02em;
  }
  .dossier-note {
    margin: clamp(20px, 2.4vw, 32px) 0 0;
    padding-top: clamp(16px, 2vw, 24px);
    border-top: 1px solid rgba(122, 96, 58, 0.24);
    font-size: clamp(0.92rem, 1.25vw, 1.15rem);
    line-height: 1.5;
    color: #6b5c42;
    max-width: 62ch;
  }

  /* ---------- Rule-writing composition (item 3): stylized, not a screenshot. A rule input
     styled like the app's own text field, with the typed rule text and its Hold action attached
     to it — composed to read instantly as "I tell it what to catch, in my own words." Colours are
     hardcoded rather than the light/dark-flipping variables, to match this always-dark scene, the
     same treatment .safety-stat-number etc. use in the Creator Safety banner. Replaces the old
     .full-bleed-classifier screenshot treatment. The card's own wrapper (.rule-composer /
     .rule-composer-inner) was dropped in v5 item 3: this content is now panel one of the
     three-panel teaching journey and takes its box from .teach-panel instead. The label, input,
     caret and action-button styles below are unchanged and still in use. ---------- */
  .rule-composer-label {
    margin: 0 0 10px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #d99a6c;
  }
  .rule-input {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    min-height: 52px;
    padding: 12px 16px;
    border-radius: var(--radius-md);
    background: #1c1a12;
    border: 1px solid rgba(224, 194, 150, 0.22);
  }
  .rule-input-text {
    font-size: 1rem;
    font-weight: 600;
    color: #f5f1e8;
    line-height: 1.4;
  }
  .rule-caret {
    display: inline-block;
    width: 2px;
    height: 1.15em;
    background: #e0a458;
    margin-left: 2px;
    flex-shrink: 0;
  }
  .rule-action-row {
    display: flex;
    justify-content: flex-end;
    margin-top: 16px;
  }
  .rule-action-btn {
    display: inline-block;
    padding: 9px 22px;
    border-radius: 999px;
    background: #e0a458;
    color: #201406;
    font-size: 0.88rem;
    font-weight: 800;
    letter-spacing: 0.01em;
  }
  @media (max-width: 480px) {
    .rule-action-row { justify-content: stretch; }
    .rule-action-btn { width: 100%; text-align: center; }
  }

  /* ---------- Teaching journey (v5 item 3, Mike: "there should be three right side by side - use
     the width of the page. So, If a comment matches - that current one goes first. Next would be a
     classifier feedback with a 'hold' / 'publsh' ... and the third would be another one - so we show
     almost a journey and how you teach the robot.")

     Three panels reading left to right as: you tell it, you correct it, it gets it right for you.
     Panel one is the original rule-writing card, content unchanged, now sitting in the trio's box
     instead of its own. Panels two and three are stylized product moments, not screenshots: an
     invented viewer, an invented comment, and the real mechanics (a verdict you can correct, and a
     later comment the classifier catches against the rule you wrote). Breaks out of the 780px
     .scene-inner to the width of the page; stacks to a single column on phones, where the
     connective arrows rotate to point down the stack. The trio is this scene's commanding-scale
     element, replacing the single card. ---------- */
  .teach-journey {
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 0 clamp(16px, 3vw, 46px);
    margin-top: clamp(26px, 3vw, 40px);
  }
  .teach-grid {
    --tgap: clamp(18px, 2vw, 34px);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--tgap);
    max-width: 1560px;
    margin: 0 auto;
  }
  @media (max-width: 940px) {
    .teach-grid { grid-template-columns: 1fr; max-width: 520px; --tgap: 34px; }
  }
  .teach-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    background: rgba(245, 241, 232, 0.05);
    border: 1px solid rgba(224, 194, 150, 0.16);
    border-radius: var(--radius-lg);
    padding: clamp(20px, 1.8vw, 28px);
    text-align: left;
    box-shadow: var(--shadow-1);
  }
  /* Connective chevron sitting in the gutter between panels. Decorative. */
  .teach-panel-arrow::after {
    content: "";
    position: absolute;
    top: 50%;
    right: calc(-0.5 * var(--tgap) - 5px);
    width: 11px;
    height: 11px;
    border-top: 2px solid rgba(224, 194, 150, 0.55);
    border-right: 2px solid rgba(224, 194, 150, 0.55);
    transform: translateY(-50%) rotate(45deg);
  }
  @media (max-width: 940px) {
    .teach-panel-arrow::after {
      top: auto;
      bottom: calc(-0.5 * var(--tgap) - 5px);
      right: 50%;
      transform: translateX(50%) rotate(135deg);
    }
  }
  .teach-step {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 16px;
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: #d99a6c;
  }
  .teach-step-num {
    flex-shrink: 0;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    background: #e0a458;
    color: #201406;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.68rem;
    font-weight: 900;
    letter-spacing: 0;
  }
  .teach-comment { display: flex; gap: 11px; align-items: flex-start; }
  .teach-avatar {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #c0a87e;
    color: #241a08;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.74rem;
    font-weight: 800;
  }
  .teach-comment-name { margin: 0 0 4px; font-size: 0.79rem; font-weight: 700; color: #cfc9ba; }
  .teach-comment-text { margin: 0; font-size: 1rem; line-height: 1.45; color: #f5f1e8; }
  .teach-verdict {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    align-self: flex-start;
    margin-top: 16px;
    padding: 6px 14px;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 800;
    background: rgba(224, 164, 88, 0.15);
    border: 1px solid rgba(224, 164, 88, 0.5);
    color: #e8b877;
  }
  .teach-ask { margin: 15px 0 10px; font-size: 0.85rem; color: #b8b3a4; }
  .teach-btn-row { display: flex; gap: 9px; }
  .teach-btn {
    flex: 1;
    text-align: center;
    padding: 10px 14px;
    border-radius: 999px;
    font-size: 0.86rem;
    font-weight: 800;
    border: 1px solid rgba(224, 194, 150, 0.32);
    color: #e8e2d4;
  }
  .teach-btn-chosen { background: #e0a458; border-color: #e0a458; color: #201406; }
  .teach-rule-echo {
    margin-top: 16px;
    padding: 11px 13px;
    border-left: 2px solid #e0a458;
    background: rgba(224, 164, 88, 0.07);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: 0.83rem;
    line-height: 1.45;
    color: #cfc9ba;
  }
  .teach-note { margin: 14px 0 0; font-size: 0.85rem; line-height: 1.45; color: #b8b3a4; }
  /* pushes the closing line of each panel to the bottom so the three boxes read as a matched set */
  .teach-spacer { flex: 1; min-height: 4px; }

  /* ---------- Rules gallery (v5 item 4, Mike: "underneath A robot you actually teach perhaps are
     the rules. So, customisable rules you can add. Very IFTTT style. But the screenshots/images
     shown here need to be mockups, stylised.")

     One coherent panel, not four loose cards, so the scene still reads as trio-then-panel rather
     than a pile of boxes. Every row is IF <plain words> THEN <action chip>, all invented, all
     drawn in the product's own visual language rather than captured from the app. This illustration
     stays with the reversible Notify me / Probation / Hold actions; Delete exists separately and
     runs only when the creator explicitly configures a rule to use it. ---------- */
  .rules-gallery {
    /* narrower than the trio above it on purpose: at full 1560px the dotted leaders stretch so far
       that the IF and the THEN stop reading as one rule. */
    max-width: 1180px;
    margin: 0 auto;
    background: rgba(245, 241, 232, 0.04);
    border: 1px solid rgba(224, 194, 150, 0.16);
    border-radius: var(--radius-lg);
    padding: clamp(20px, 2vw, 32px) clamp(20px, 2.2vw, 36px) clamp(18px, 2vw, 28px);
    text-align: left;
    box-shadow: var(--shadow-1);
  }
  .rules-gallery-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding-bottom: clamp(12px, 1.4vw, 18px);
    border-bottom: 1px solid rgba(224, 194, 150, 0.16);
  }
  .rules-gallery-title {
    margin: 0;
    font-size: 0.72rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: #d99a6c;
  }
  .rules-gallery-add {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 15px;
    border-radius: 999px;
    border: 1px dashed rgba(224, 194, 150, 0.42);
    font-size: 0.78rem;
    font-weight: 800;
    color: #cfc9ba;
    white-space: nowrap;
  }
  .rule-line {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 18px;
    padding: clamp(14px, 1.5vw, 21px) 0;
    border-bottom: 1px dashed rgba(224, 194, 150, 0.15);
  }
  .rule-line:last-of-type { border-bottom: none; }
  .rule-cond {
    margin: 0;
    font-size: clamp(0.98rem, 1.25vw, 1.2rem);
    line-height: 1.4;
    font-weight: 600;
    color: #f5f1e8;
  }
  .rule-if, .rule-then {
    font-size: 0.7rem;
    font-weight: 900;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: #8f8a7b;
    margin-right: 10px;
  }
  .rule-if { color: #d99a6c; }
  .rule-lead {
    height: 0;
    min-width: 24px;
    border-bottom: 1px dotted rgba(224, 194, 150, 0.3);
  }
  .rule-act { margin: 0; display: flex; align-items: center; white-space: nowrap; }
  .rule-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 17px;
    border-radius: 999px;
    font-size: 0.86rem;
    font-weight: 800;
    letter-spacing: 0.01em;
  }
  .rule-chip svg { width: 14px; height: 14px; flex-shrink: 0; }
  .rule-chip-hold { background: rgba(224, 164, 88, 0.16); border: 1px solid rgba(224, 164, 88, 0.55); color: #e8b877; }
  .rule-chip-probation { background: rgba(194, 90, 74, 0.18); border: 1px solid rgba(194, 90, 74, 0.62); color: #e5947f; }
  .rule-chip-notify { background: rgba(245, 241, 232, 0.07); border: 1px solid rgba(224, 194, 150, 0.38); color: #e8e2d4; }
  .rules-gallery-foot {
    margin: clamp(14px, 1.6vw, 20px) 0 0;
    padding-top: clamp(12px, 1.4vw, 18px);
    border-top: 1px solid rgba(224, 194, 150, 0.16);
    font-size: 0.84rem;
    line-height: 1.45;
    color: #b8b3a4;
  }
  @media (max-width: 720px) {
    .rule-line { grid-template-columns: 1fr; gap: 11px; }
    .rule-lead { display: none; }
    .rule-act { justify-content: flex-start; }
  }


  /* ---------- Fixed-dark scenes (theme-independent, Apple-style rhythm beat) ---------- */

  .scene-fixed-dark {
    background: #121109;
    color: #f5f1e8;
  }
  .scene-fixed-dark .eyebrow { color: #d99a6c; }
  .scene-fixed-dark .support { color: #b8b3a4; }

  /* Top padding only, tightened (empty-space sweep, item 1b): closes the gap in from the Creator
     Safety banner above. The ladder-pin/ladder-stage/ladder-graphic themselves are untouched. */
  .scene-ladder-intro { padding-top: 0; padding-bottom: 0; }

  /* v5 empty-frame sweep: the ladder's own container was the 780px .scene-inner every text scene
     uses, so at wide viewports the rungs hit their clamp ceilings early and the 100dvh sticky
     stage was left roughly 60% dark. Widening the container here (the .support paragraph keeps
     its own 560px cap, the full-bleed breaks out regardless) lets the rung sizes below grow into
     a genuinely commanding block without the nowrap words overflowing. */
  /* v7: widened again to make room for the sticky explainer column beside the ladder without
     squeezing the rungs, which are white-space:nowrap and sized off the viewport. At every width
     tested the longest rung ("Good standing") still clears the visual column with room over. */
  .scene-ladder-intro .scene-inner { max-width: min(1560px, 94vw); }

  /* ---------- The troll-vs-bad-day explainer beside the ladder (v7, founder ruling mid-round) ----
     Mike, verbatim: "We need a 'How we spot trolls and haters' (better language) above the
     standing section (or to the side of it and it's there permanently while the scroll scrolls the
     standing ladder if that makes sense. Think apple store again. We can say, we start with a
     state of the art classifier algorithm trained on over 50,000 YouTube comments on Mike's own
     channel - and then YOU train it privately on yours. ... it learns from each of your
     commenters' past behaviour, and their attitudes so one bad day doesn't turn into a hard and
     fast rule."

     Apple product-page pattern: the copy column is its own sticky 100dvh box in the left grid
     track, so it holds still, vertically centred and level with the ladder, for the whole 200vh
     the rungs take to scrub. It is a SIBLING of .ladder-pin rather than a child of the sticky
     stage, which is what lets it fall back to a plain block ABOVE the ladder on phones, exactly
     as the ruling asks, with no risk of overflowing a short viewport inside the pin.

     This ruling also settles the previously-open sparseness of the ladder pin: those frames were
     sparse because the stage held one graphic and nothing else. Now they hold this.

     The rung art, its scale and the scrub keyframes are untouched. ---------- */
  .ladder-layout { display: block; }
  .ladder-explainer {
    text-align: left;
    max-width: 560px;
    margin: 0 auto clamp(26px, 4vw, 40px);
  }
  .ladder-explainer-title {
    margin: 0 0 clamp(18px, 2.4vw, 26px);
    /* Grows further at desktop than the first draft did: beside 128px rungs a 33px title read as
       a footnote, and the taller column also fills the stage properly (empty-frame audit). */
    font-size: clamp(1.45rem, 1.7vw, 2.6rem);
    line-height: 1.14;
    letter-spacing: -0.022em;
    font-weight: 800;
    color: #f5f1e8;
  }
  .ladder-point { margin: 0 0 clamp(16px, 2vw, 22px); }
  .ladder-point:last-child { margin-bottom: 0; }
  .ladder-point::before {
    content: "";
    display: block;
    width: 26px;
    height: 3px;
    border-radius: 2px;
    background: #e0a458;
    margin-bottom: 11px;
  }
  .ladder-point p {
    margin: 0;
    font-size: clamp(0.97rem, 0.62vw, 1.22rem);
    line-height: 1.5;
    color: #b8b3a4;
  }
  .ladder-point p b {
    display: block;
    font-size: clamp(1.04rem, 0.68vw, 1.34rem);
    font-weight: 800;
    letter-spacing: -0.01em;
    color: #f5f1e8;
    margin-bottom: 3px;
  }

  @media (min-width: 901px) {
    .ladder-layout {
      display: grid;
      grid-template-columns: minmax(270px, 350px) 1fr;
      gap: clamp(34px, 4vw, 68px);
      align-items: start;
      text-align: left;
    }
    .ladder-explainer { margin: 0; max-width: none; }
  }

  /* ---------- Standing-ladder graphic: four words flying back into the dark, in perspective.
     Trusted is closest/brightest/warmest; Banned is farthest/darkest/coldest/heaviest. Pure CSS
     (perspective + translateZ + rotateX) — no image, no JS. The scroll-in settle it gets is the
     same .reveal-scale system used everywhere else, so it fully respects prefers-reduced-motion
     via the existing rules above. ---------- */

  .ladder-graphic {
    position: relative;
    isolation: isolate;
    perspective: 1300px;
    perspective-origin: 50% 8%;
    padding: 14px 0 22px;
    margin: 0 auto;
  }

  /* Entry-void fix (Mike: "WTF is with all this space? What's it selling? Emptiness?"): this
     glow is the stage lighting behind the ladder — sized to read as an intentional lit set even
     in the first frame the pin is visible, well before the rungs have earned their full scale. */
  .ladder-graphic::before {
    content: "";
    position: absolute;
    inset: -70% -30%;
    background: radial-gradient(58% 62% at 50% 32%, rgba(217, 154, 108, 0.34), transparent 74%);
    filter: blur(60px);
    z-index: -1;
  }

  .rung-stage {
    transform-style: preserve-3d;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* v5 empty-frame sweep: the vertical rhythm now tracks viewport height harder, so a tall
       desktop stage is filled by the ladder rather than by dark. */
    gap: clamp(14px, 7vh, 58px);
  }

  .rung {
    margin: 0;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.02;
    white-space: nowrap;
  }

  /* Sizes step down Trusted -> Banned but the floor is raised deliberately: every rung stays
     legible at a glance (Mike: "it's like an eye test currently" on the old 1.3rem floor).
     Banned never drops below ~63% of Trusted's rendered size once perspective recession is
     factored in, and nothing renders under 2rem even at phone width. */
  .rung-1 {
    font-size: clamp(3.1rem, 7.6vw, 8rem);
    color: #a9e6bd;
    transform: rotateX(14deg) translateZ(0px);
    opacity: 1;
    text-shadow: 0 0 34px rgba(169, 230, 189, 0.35);
  }
  .rung-2 {
    font-size: clamp(2.8rem, 6.7vw, 7rem);
    font-weight: 750;
    color: #f2ead8;
    transform: rotateX(14deg) translateZ(-50px);
    opacity: 0.94;
  }
  .rung-3 {
    font-size: clamp(2.6rem, 5.9vw, 6.2rem);
    font-weight: 800;
    color: #e0a458;
    transform: rotateX(14deg) translateZ(-100px);
    opacity: 0.88;
    filter: blur(0.3px);
  }
  .rung-4 {
    font-size: clamp(2.4rem, 5.2vw, 5.7rem);
    font-weight: 900;
    color: #b0453a;
    transform: rotateX(14deg) translateZ(-150px);
    opacity: 0.82;
    filter: blur(0.4px);
  }

  @media (max-width: 480px) {
    .ladder-graphic { perspective: 1100px; }
    .rung-3, .rung-4 { filter: none; }
  }

  /* ---------- Ladder scroll-pin (v2, Mike's brief: "as you scroll the page seemingly stops
     scrolling and the ladder scrolls down to banned and then you can continue scrolling").
     .ladder-pin is a tall (320vh) scroll container; .ladder-stage sticks to the viewport inside
     it. As you scroll through the extra height, focus travels Trusted -> Good standing ->
     Probation -> Banned, landing at ~92% of the dwell so it's settled a beat before the sticky
     releases (the classic release-jump bug). Three tiers, same shape as the reveal system above:
     native scroll-driven CSS where supported; a small IntersectionObserver+scroll JS fallback
     (js-armed, see head script) where it isn't; and, always, under prefers-reduced-motion,
     neither applies — .ladder-pin/.ladder-stage stay plain unstyled <div>s (normal height, not
     sticky) and every rung sits at its already-visible resting style, i.e. this exact block
     degrades to the pre-v2 static graphic. ---------- */

  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      .ladder-pin {
        height: 200vh;
        view-timeline-name: --ladder-scrub;
        view-timeline-axis: block;
      }
      .ladder-stage {
        position: sticky;
        top: 0;
        height: 100vh;
        height: 100dvh;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: clamp(20px, 6vh, 52px);
      }
      .rung-stage {
        animation: ladder-stage-scrub linear both;
        animation-timeline: --ladder-scrub;
        animation-range: entry 100% exit 0%;
      }
      .rung-1 {
        animation: ladder-rung-1-scrub linear both;
        animation-timeline: --ladder-scrub;
        animation-range: entry 100% exit 0%;
      }
      .rung-2 {
        animation: ladder-rung-2-scrub linear both;
        animation-timeline: --ladder-scrub;
        animation-range: entry 100% exit 0%;
      }
      .rung-3 {
        animation: ladder-rung-3-scrub linear both;
        animation-timeline: --ladder-scrub;
        animation-range: entry 100% exit 0%;
      }
      .rung-4 {
        animation: ladder-rung-4-scrub linear both;
        animation-timeline: --ladder-scrub;
        animation-range: entry 100% exit 0%;
      }
      /* Explainer sticks for the whole dwell, its own 100dvh box so it centres on exactly the same
         line the ladder stage does. Only where the pin is actually tall. */
      @media (min-width: 901px) {
        .ladder-explainer {
          position: sticky;
          top: 0;
          height: 100vh;
          height: 100dvh;
          display: flex;
          flex-direction: column;
          /* Distributed rather than clustered: the three points spread down the left of the stage,
             level with the four rungs, which is both the Apple pattern proper and what lifts these
             frames out of the empty-frame audit. gap is the floor so a short viewport still packs
             them sensibly. */
          justify-content: space-between;
          gap: clamp(16px, 2.4vh, 40px);
          padding: clamp(36px, 8vh, 120px) 0;
        }
      }
    }
  }

  /* JS-fallback tier: identical geometry, driven by the small scroll handler near the end of
     <body> instead of a native timeline. Only active when js-armed is set. */
  html.js-armed .ladder-pin { height: 200vh; }
  html.js-armed .ladder-stage {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: clamp(20px, 6vh, 52px);
  }
  @media (min-width: 901px) {
    html.js-armed .ladder-explainer {
      position: sticky;
      top: 0;
      height: 100vh;
      height: 100dvh;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      gap: clamp(16px, 2.4vh, 40px);
      padding: clamp(36px, 8vh, 120px) 0;
    }
  }

  @keyframes ladder-stage-scrub {
    0%   { transform: translateY(4%); }
    33%  { transform: translateY(-3%); }
    66%  { transform: translateY(-9%); }
    92%  { transform: translateY(-14%); }
    100% { transform: translateY(-14%); }
  }
  /* Zoom-on-focus (Mike): each rung's resting size stays as set above; its scrub moment brings
     it up to full prominence with a ~1.18-1.2x scale rather than relying on size alone. */
  @keyframes ladder-rung-1-scrub {
    0%   { opacity: 1;    filter: blur(0) brightness(1.18); transform: rotateX(14deg) translateZ(0px) scale(1.2); }
    28%  { opacity: 0.55; filter: blur(0.5px) brightness(0.72); transform: rotateX(14deg) translateZ(0px) scale(0.95); }
    100% { opacity: 0.52; filter: blur(0.5px) brightness(0.7);  transform: rotateX(14deg) translateZ(0px) scale(0.95); }
  }
  @keyframes ladder-rung-2-scrub {
    0%   { opacity: 0.55; filter: blur(0.5px) brightness(0.72); transform: rotateX(14deg) translateZ(-50px) scale(0.95); }
    16%  { opacity: 0.55; filter: blur(0.5px) brightness(0.72); transform: rotateX(14deg) translateZ(-50px) scale(0.95); }
    33%  { opacity: 1;    filter: blur(0) brightness(1.18); transform: rotateX(14deg) translateZ(-50px) scale(1.2); }
    55%  { opacity: 0.52; filter: blur(0.5px) brightness(0.68); transform: rotateX(14deg) translateZ(-50px) scale(0.95); }
    100% { opacity: 0.5;  filter: blur(0.5px) brightness(0.66); transform: rotateX(14deg) translateZ(-50px) scale(0.95); }
  }
  @keyframes ladder-rung-3-scrub {
    0%   { opacity: 0.5;  filter: blur(0.6px) brightness(0.62); transform: rotateX(14deg) translateZ(-100px) scale(0.94); }
    46%  { opacity: 0.5;  filter: blur(0.6px) brightness(0.62); transform: rotateX(14deg) translateZ(-100px) scale(0.94); }
    66%  { opacity: 1;    filter: blur(0) brightness(1.16); transform: rotateX(14deg) translateZ(-100px) scale(1.18); }
    85%  { opacity: 0.48; filter: blur(0.6px) brightness(0.6);  transform: rotateX(14deg) translateZ(-100px) scale(0.94); }
    100% { opacity: 0.46; filter: blur(0.6px) brightness(0.58); transform: rotateX(14deg) translateZ(-100px) scale(0.94); }
  }
  @keyframes ladder-rung-4-scrub {
    0%   { opacity: 0.46; filter: blur(0.7px) brightness(0.56); transform: rotateX(14deg) translateZ(-150px) scale(0.93); }
    70%  { opacity: 0.46; filter: blur(0.7px) brightness(0.56); transform: rotateX(14deg) translateZ(-150px) scale(0.93); }
    92%  { opacity: 1;    filter: blur(0) brightness(1.16); transform: rotateX(14deg) translateZ(-150px) scale(1.18); }
    100% { opacity: 1;    filter: blur(0) brightness(1.16); transform: rotateX(14deg) translateZ(-150px) scale(1.18); }
  }

  /* ---------- Sentiment scene: a "star wars crawl" of viewer sentiment receding on the Z axis,
     same perspective/preserve-3d toolkit as the standing ladder above. Six invented viewers,
     nearest/warmest/most-positive first: focus builds down the list as you scroll through the
     pin (unlike the ladder's spotlight, rows STAY lit once revealed — a list building up, not a
     beam moving past). Same three-tier pattern: native view-timeline / JS IntersectionObserver
     fallback / static under reduced-motion or no support, where every row and bar simply sits at
     its final, fully-legible state with nothing pinned. ---------- */

  /* v5 item 5: the one cluster the whole scene composes into. Height is auto and the gaps are
     fixed, so the composition is identical whatever the viewport's aspect ratio; the sticky stage
     only ever centres it. Nothing here may be sized in vh against the stage. */
  .sentiment-cluster {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(9px, 1.7vh, 20px);
  }
  .sentiment-cluster .eyebrow { margin: 0; }
  .sentiment-cluster h2 { margin: 0; }
  .sentiment-cluster .support { margin: 0 auto; }

  .sentiment-crawl {
    position: relative;
    isolation: isolate;
    perspective: 1200px;
    perspective-origin: 50% 20%;
    width: 100%;
    max-width: 700px;
    margin: 0 auto;
    padding: 6px 0;
  }
  .sentiment-crawl::before {
    /* Entry-void fix (item 1, same treatment as the ladder): a bigger, brighter stage glow so
       the pin reads as a lit set from the first frame, not a void with faint text in it. Item 2
       compresses the pin height/pacing further on top of this. */
    content: "";
    position: absolute;
    inset: -65% -25%;
    background: radial-gradient(58% 60% at 50% 26%, rgba(217, 154, 108, 0.3), transparent 74%);
    filter: blur(58px);
    z-index: -1;
  }
  .sentiment-rows {
    transform-style: preserve-3d;
    display: flex;
    flex-direction: column;
    gap: clamp(8px, 2.3vh, 20px);
  }
  .sentiment-row {
    display: grid;
    grid-template-columns: minmax(110px, auto) 1fr auto;
    align-items: center;
    gap: 12px;
    font-weight: 700;
  }
  .sr-name {
    font-size: clamp(0.88rem, 1.6vw, 1.05rem);
    color: #f2ead8;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Ink pass (marketing analysis item 6): the bars were the flagged 52-56% ink on this scene, so
     the composition read as pale stripes on a dark ground at a glance. Track is taller and less
     transparent, the fills are brighter and the labels come up with them, which lifts the whole
     stage without touching the layout or the data. */
  .sr-bar-track {
    position: relative;
    height: 11px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.17);
    overflow: hidden;
  }
  .sr-bar {
    position: absolute;
    top: 0; left: 0; height: 100%;
    width: 100%;
    border-radius: 999px;
    transform-origin: left center;
  }
  .sr-bar-pos { background: linear-gradient(90deg, #7fd3a3, #c6f2d6); }
  .sr-bar-neg { background: linear-gradient(90deg, #d05c4d, #f4ab99); }
  .sr-label {
    font-size: clamp(0.68rem, 1.3vw, 0.8rem);
    font-weight: 700;
    color: #ded7c6;
    white-space: nowrap;
  }
  .sr-label-pos { color: #c6f2d6; }
  .sr-label-neg { color: #f4ab99; }

  /* THE `.sentiment-example` PANEL IS GONE (phase-2 follow-on, Amendment 4C).
     Roughly ninety lines of colour literals — `#121109`, `#f5f1e8`, `#d99a6c`, `rgba(224, 194, 150,
     0.18)` — drew a deliberately dark, theme-deaf panel that stood in for a product screen on the
     four sentiment pages. Three of them became catalogue scenes in phase 2 and the last, sponsor
     mentions, became the `sponsor-receipts` scene in this follow-on, so the block had no user left.
     A picture of the product that cannot follow the reader's theme is the thing this lane removed
     from the site; keeping the last of it warm for a future caller would have been keeping the
     habit. */

  /* Base resting transform per row (always applied; the scrub tiers below only add opacity/
     filter/scale on top of it). Rows recede: closer + bigger presence for stronger sentiment. */
  /* Recede opacities lifted with the bar ink (item 6): the rows still recede, but the furthest
     one is no longer down at 0.85 on a near-black ground, where it was giving up contrast the
     scene could not spare. */
  .sr-1 { transform: rotateX(9deg) translateZ(0px); }
  .sr-2 { transform: rotateX(9deg) translateZ(-40px); opacity: 0.97; }
  .sr-3 { transform: rotateX(9deg) translateZ(-80px); opacity: 0.95; }
  .sr-4 { transform: rotateX(9deg) translateZ(-120px); opacity: 0.94; }
  .sr-5 { transform: rotateX(9deg) translateZ(-160px); opacity: 0.92; }
  .sr-6 { transform: rotateX(9deg) translateZ(-200px); opacity: 0.91; }
  /* Base resting bar fill (always applied — the scrub tiers animate FROM 0 up to this). */
  .sr-bar { transform: scaleX(var(--mag)); }

  @media (max-width: 480px) {
    .sentiment-crawl { perspective: 900px; }
    .sentiment-row { grid-template-columns: minmax(84px, auto) 1fr auto; gap: 8px; }
  }

  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      .sentiment-pin {
        height: 150vh;
        view-timeline-name: --sentiment-scrub;
        view-timeline-axis: block;
      }
      .sentiment-stage {
        position: sticky;
        top: 0;
        height: 100vh;
        height: 100dvh;
        display: flex;
        flex-direction: column;
        align-items: center;
        /* Was justify-content: center (empty-space sweep, item 1d): a short content block
           centered in a full 100dvh sticky stage put roughly as much blank space above the
           eyebrow as below it, which read as dead air the moment the pin engaged. Pinning to the
           top with a modest padding instead moves that slack to the far side (below the crawl),
           which is a settle buffer after content rather than a void before it. */
        /* v5 item 5: centred, with the cluster's own auto height doing the composing. The old
           flex-start + top padding pushed everything up and left the slack below the bars, which
           is exactly where the trend chart used to be missing from. */
        justify-content: center;
        padding: clamp(10px, 2.5vh, 30px) 0;
      }
      .sr-1 { animation: sr-reveal-1 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-2 { animation: sr-reveal-2 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-3 { animation: sr-reveal-3 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-4 { animation: sr-reveal-4 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-5 { animation: sr-reveal-5 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-6 { animation: sr-reveal-6 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-1 .sr-bar, .sr-2 .sr-bar, .sr-3 .sr-bar, .sr-4 .sr-bar, .sr-5 .sr-bar, .sr-6 .sr-bar { transform: scaleX(0); }
      .sr-1 .sr-bar { animation: sr-bar-1 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-2 .sr-bar { animation: sr-bar-2 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-3 .sr-bar { animation: sr-bar-3 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-4 .sr-bar { animation: sr-bar-4 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-5 .sr-bar { animation: sr-bar-5 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
      .sr-6 .sr-bar { animation: sr-bar-6 linear both; animation-timeline: --sentiment-scrub; animation-range: entry 100% exit 0%; }
    }
  }

  html.js-armed .sentiment-pin { height: 150vh; }
  html.js-armed .sentiment-stage {
    position: sticky;
    top: 0;
    height: 100vh;
    height: 100dvh;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* Matches the native-support rule above (v5 item 5). */
    justify-content: center;
    padding: clamp(10px, 2.5vh, 30px) 0;
  }

  @keyframes sr-reveal-1 {
    0%   { opacity: 1; filter: blur(0) brightness(1.08); transform: rotateX(9deg) translateZ(0px) scale(1); }
    100% { opacity: 1; filter: blur(0) brightness(1.08); transform: rotateX(9deg) translateZ(0px) scale(1); }
  }
  @keyframes sr-reveal-2 {
    0%   { opacity: 0.35; filter: blur(0.6px) brightness(0.6); transform: rotateX(9deg) translateZ(-40px) scale(0.92); }
    14%  { opacity: 0.35; filter: blur(0.6px) brightness(0.6); transform: rotateX(9deg) translateZ(-40px) scale(0.92); }
    19%  { opacity: 1;    filter: blur(0) brightness(1.08);   transform: rotateX(9deg) translateZ(-40px) scale(1); }
    100% { opacity: 1;    filter: blur(0) brightness(1.08);   transform: rotateX(9deg) translateZ(-40px) scale(1); }
  }
  @keyframes sr-reveal-3 {
    0%   { opacity: 0.32; filter: blur(0.6px) brightness(0.58); transform: rotateX(9deg) translateZ(-80px) scale(0.9); }
    32%  { opacity: 0.32; filter: blur(0.6px) brightness(0.58); transform: rotateX(9deg) translateZ(-80px) scale(0.9); }
    37%  { opacity: 1;    filter: blur(0) brightness(1.06);    transform: rotateX(9deg) translateZ(-80px) scale(1); }
    100% { opacity: 1;    filter: blur(0) brightness(1.06);    transform: rotateX(9deg) translateZ(-80px) scale(1); }
  }
  @keyframes sr-reveal-4 {
    0%   { opacity: 0.3;  filter: blur(0.7px) brightness(0.56); transform: rotateX(9deg) translateZ(-120px) scale(0.9); }
    50%  { opacity: 0.3;  filter: blur(0.7px) brightness(0.56); transform: rotateX(9deg) translateZ(-120px) scale(0.9); }
    55%  { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-120px) scale(1); }
    100% { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-120px) scale(1); }
  }
  @keyframes sr-reveal-5 {
    0%   { opacity: 0.28; filter: blur(0.7px) brightness(0.54); transform: rotateX(9deg) translateZ(-160px) scale(0.88); }
    68%  { opacity: 0.28; filter: blur(0.7px) brightness(0.54); transform: rotateX(9deg) translateZ(-160px) scale(0.88); }
    73%  { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-160px) scale(1); }
    100% { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-160px) scale(1); }
  }
  @keyframes sr-reveal-6 {
    0%   { opacity: 0.26; filter: blur(0.8px) brightness(0.52); transform: rotateX(9deg) translateZ(-200px) scale(0.88); }
    86%  { opacity: 0.26; filter: blur(0.8px) brightness(0.52); transform: rotateX(9deg) translateZ(-200px) scale(0.88); }
    91%  { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-200px) scale(1); }
    100% { opacity: 1;    filter: blur(0) brightness(1.05);    transform: rotateX(9deg) translateZ(-200px) scale(1); }
  }
  @keyframes sr-bar-1 { 0% { transform: scaleX(var(--mag)); } 100% { transform: scaleX(var(--mag)); } }
  @keyframes sr-bar-2 { 0%,14% { transform: scaleX(0); } 19%,100% { transform: scaleX(var(--mag)); } }
  @keyframes sr-bar-3 { 0%,32% { transform: scaleX(0); } 37%,100% { transform: scaleX(var(--mag)); } }
  @keyframes sr-bar-4 { 0%,50% { transform: scaleX(0); } 55%,100% { transform: scaleX(var(--mag)); } }
  @keyframes sr-bar-5 { 0%,68% { transform: scaleX(0); } 73%,100% { transform: scaleX(var(--mag)); } }
  @keyframes sr-bar-6 { 0%,86% { transform: scaleX(0); } 91%,100% { transform: scaleX(var(--mag)); } }

  /* Sentiment-over-time trend chart (rebuilt, item 2): display-scale now — bigger canvas, a soft
     warm area fill under the line, week ticks along the baseline, and an end-dot labelled
     "Positive" instead of a bare line fading into nothing. Sits directly under the pin with no
     extra margin (the old 28px gap is the dead band Mike flagged; killed here). Base state is
     fully drawn (dashoffset 0) so reduced-motion / no-support always shows the complete chart.
     Both enhanced tiers reuse the SAME reveal-scale/js-armed machinery already on the page. */
  .sentiment-trend {
    /* matched to .sentiment-crawl's width so bars and chart read as one stacked composition, and
       so the whole cluster still fits inside a 720px-tall pinned stage (v5 item 5) */
    width: 100%;
    max-width: 700px;
    margin: 0 auto;
    text-align: center;
  }
  .sentiment-trend-svg { width: 100%; height: auto; display: block; }
  .trend-zero { stroke: rgba(255, 255, 255, 0.14); stroke-width: 1; }
  .trend-ticks line { stroke: rgba(255, 255, 255, 0.22); stroke-width: 1; }
  .sentiment-trend-area {
    stroke: none;
    fill: url(#trendFill);
  }
  .sentiment-trend-line {
    fill: none;
    stroke: #e0a458;
    stroke-width: 3.5;
    stroke-linecap: round;
    stroke-dasharray: 820;
    stroke-dashoffset: 0;
  }
  .trend-end-dot {
    fill: #f2ead8;
    stroke: #e0a458;
    stroke-width: 3;
  }
  .trend-end-label {
    fill: #f2ead8;
    font-size: 22px;
    font-weight: 700;
    font-family: var(--font-sans);
  }
  .trend-caption {
    margin: 12px 0 0;
    font-size: 0.95rem;
    color: #b8b3a4;
  }
  @media (prefers-reduced-motion: no-preference) {
    @supports (animation-timeline: view()) {
      .sentiment-trend-line {
        stroke-dashoffset: 820;
        animation: trend-draw linear both;
        /* was `view()`: once the chart moved inside the sticky stage its own box stops travelling
           through the scrollport, so a view() timeline stalls part-drawn. Riding the pin's scrub
           instead means the line finishes drawing before the pin releases, every time. */
        animation-timeline: --sentiment-scrub;
        animation-range: entry 100% exit 0%;
      }
    }
  }
  @keyframes trend-draw {
    0%   { stroke-dashoffset: 820; }
    30%  { stroke-dashoffset: 820; }
    88%  { stroke-dashoffset: 0; }
    100% { stroke-dashoffset: 0; }
  }
  html.js-armed .sentiment-trend-line { stroke-dashoffset: 820; transition: stroke-dashoffset 1.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
  html.js-armed .sentiment-trend.in-view .sentiment-trend-line { stroke-dashoffset: 0; }

  /* ---------- The money scene (item 13) ----------
     Was a coda at the bottom of the sentiment scene plus a thin CTA band under it, which set the
     page's biggest commercial promise in its smallest headline type and put the proof in a
     different scene from the claim. Now one scene: promise, mechanism, receipts, close. Fixed-dark
     because the receipts card below was drawn against that ground, and because the dark run out of
     sentiment should not break for one band and resume. ---------- */
  .scene-money .money-framing {
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
  }
  .scene-money .money-close {
    max-width: 640px;
    margin: clamp(20px, 2.6vw, 30px) auto clamp(18px, 2.2vw, 26px);
  }

  /* ---------- Sponsor receipts strip (founder ruling, mid-round) ----------
     Mike, verbatim: "'Make more money with your sponsor ad integrations' (basically, justifying
     rates due to sentiment analysis - I ordered! It's great! I loved your sponsored segment!)".

     Now the evidence half of the money scene above (item 13), directly under the mechanism it
     proves. Six chips since item 11: four positive, one neutral, one mild negative. ---------- */
  .sponsor-receipts {
    max-width: 860px;
    margin: clamp(24px, 3.2vw, 40px) auto 0;
    padding: clamp(20px, 2.6vw, 28px) clamp(20px, 2.6vw, 30px);
    border-radius: var(--radius-lg);
    border: 1px solid rgba(224, 194, 150, 0.18);
    background: rgba(245, 241, 232, 0.045);
    text-align: left;
  }
  .sponsor-receipts-claim {
    margin: 0 0 10px;
    font-size: clamp(1.15rem, 2.1vw, 1.6rem);
    line-height: 1.18;
    letter-spacing: -0.02em;
    font-weight: 800;
    color: #f5f1e8;
  }
  .sponsor-receipts-body {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.55;
    color: #b8b3a4;
  }
  .sponsor-quotes {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    margin-top: 18px;
  }
  @media (max-width: 720px) {
    .sponsor-quotes { grid-template-columns: 1fr; }
  }
  .sponsor-quote {
    display: block;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    background: rgba(8, 7, 4, 0.34);
    border: 1px solid rgba(224, 194, 150, 0.14);
    font-size: 0.85rem;
    line-height: 1.4;
    color: #e8e2d4;
  }
  .sponsor-quote b {
    display: block;
    margin-bottom: 5px;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #6fbf8f;
  }

  /* ---------- Community-builder scene: side-by-side comparison ---------- */

  .scene-community { background: var(--bg-soft); }

  .compare-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    text-align: left;
  }
  @media (max-width: 720px) {
    .compare-grid { grid-template-columns: 1fr; }
  }

  .compare-panel {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-1);
    overflow: hidden;
  }
  .compare-label {
    margin: 0;
    padding: 12px 16px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
  }

  /* Stylized recreation of YouTube's own comments panel — deliberately flat/neutral (no brand
     colours borrowed from our own palette) since it is illustrating a THIRD PARTY's interface,
     not ours. No logo, no wordmark; invented viewer name. */
  .yt-mock { padding: 16px; background: #ffffff; color: #0f0f0f; }
  .yt-mock-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
  .yt-mock-avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: #606060; color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 0.9rem; flex-shrink: 0;
  }
  .yt-mock-name { margin: 0; font-size: 0.88rem; font-weight: 600; }
  .yt-mock-sub { margin: 2px 0 0; font-size: 0.76rem; color: #606060; }
  .yt-mock-row {
    display: flex; justify-content: space-between; gap: 10px;
    padding: 9px 0; border-top: 1px solid #eee;
  }
  .yt-mock-text { margin: 0; font-size: 0.82rem; color: #0f0f0f; }
  .yt-mock-time { font-size: 0.74rem; color: #606060; white-space: nowrap; }
  .yt-mock-more { margin: 10px 0 0; font-size: 0.76rem; color: #909090; font-style: italic; }

  /* Our own Viewers page, same visual language as the rest of the product (warm cream card,
     green avatar circle, brand-brown accents) — matches the real app screenshots elsewhere on
     this page, just built as markup rather than a captured image (see the comment above the
     community section for why). */
  .tlt-mock { padding: 16px; background: var(--bg-soft); color: var(--text); }
  .tlt-mock-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
  .tlt-mock-avatar {
    width: 36px; height: 36px; border-radius: 50%;
    background: #3d6b52; color: #f3ead9;
    display: flex; align-items: center; justify-content: center;
    font-weight: 700; font-size: 0.9rem; flex-shrink: 0;
  }
  .tlt-mock-name { margin: 0; font-size: 0.88rem; font-weight: 700; color: var(--text); }
  .tlt-mock-sub { margin: 2px 0 0; font-size: 0.76rem; color: var(--brand-brown); font-weight: 600; }
  /* The owner's ruling: the panel must not SAY the other eighteen comments are still here, it
     must SHOW them. So this is a real viewport over all 23 rows, not a teaser with a summary
     line at the bottom, and the reader scrolls it with a wheel, a trackpad or a thumb. The bar
     on the right edge was never decoration: it is this element's own scrollbar, and it read as
     a static stripe only because six rows overflowed 232px by a couple of pixels, so the thumb
     filled the track. With 23 rows it becomes what it always was. Height is unchanged, so the
     two panels sit exactly as they did.
     `overscroll-behavior: contain` is the important one: reaching the bottom of the list must
     not hand the momentum back to the page and fling the reader past the scene. */
  .tlt-mock-scroll {
    max-height: 232px;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--brand-brown) transparent;
  }
  /* A scrollable region a keyboard cannot reach is a scrollable region some readers do not have
     (WCAG 2.1.1), so the list takes focus and wears the page's own focus ring to say so. */
  .tlt-mock-scroll:focus-visible {
    outline: 2px solid var(--cta);
    outline-offset: 2px;
    border-radius: 4px;
  }
  .tlt-mock-scroll::-webkit-scrollbar { width: 6px; }
  .tlt-mock-scroll::-webkit-scrollbar-thumb { background: var(--brand-brown); border-radius: 999px; }
  .tlt-mock-scroll::-webkit-scrollbar-track { background: transparent; }
  .tlt-mock-row {
    display: flex; justify-content: space-between; gap: 10px;
    padding: 9px 0; border-top: 1px solid var(--border);
  }
  .tlt-mock-text { margin: 0; font-size: 0.82rem; color: var(--text); }
  .tlt-mock-time { font-size: 0.74rem; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; }

  .compare-caption {
    margin: 22px 0 0;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text);
  }

  /* ---------- Magnifier callout (item 5, Mike's sketch): the YouTube panel's own "+ 20 more"
     line, lifted into a large floating chip. Fixed light styling (not page-theme-aware) because
     it's a magnified fragment of the YouTube-styled panel above it, same as .yt-mock itself.
     This is the comparison section's one commanding-scale element; the panels/caption stay
     exactly as they were ("I LOVE THIS"). ---------- */
  .compare-panel-wrap {
    position: relative;
  }
  .magnifier-callout {
    position: absolute;
    right: 6%;
    bottom: -13%;
    max-width: 72%;
    z-index: 4;
    background: #ffffff;
    border: 1px solid #e2e2e2;
    border-radius: var(--radius-md);
    box-shadow: 0 4px 10px rgba(20, 18, 14, 0.14), 0 22px 46px rgba(20, 18, 14, 0.24);
    padding: 14px 22px;
    font-size: clamp(1.5rem, 3.6vw, 2.3rem);
    font-style: italic;
    line-height: 1.15;
    color: #909090;
    transform: rotate(-1deg);
    pointer-events: none;
  }
  .magnifier-notch {
    position: absolute;
    top: -8px;
    left: 34px;
    width: 16px;
    height: 16px;
    background: #ffffff;
    border-left: 1px solid #e2e2e2;
    border-top: 1px solid #e2e2e2;
    transform: rotate(45deg);
  }
  @media (max-width: 560px) {
    .magnifier-callout {
      position: static;
      max-width: none;
      width: 100%;
      margin-top: 16px;
      transform: none;
      font-size: clamp(1.3rem, 6.4vw, 1.7rem);
    }
    .magnifier-notch { display: none; }
  }

  /* ---------- Feature band: compact "and there's more" grid ---------- */

  .scene-feature-band { background: var(--bg-soft); }
  /* Four tiles now (two moved up into the Creator Safety block above), so a clean 2x2 reads
     better than a 3-col grid with an orphaned fourth tile. */
  .feature-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
    margin-top: 30px;
  }
  @media (max-width: 560px) {
    .feature-grid { grid-template-columns: 1fr; }
  }
  .feature-tile {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: 20px 22px;
    text-align: left;
  }
  .feature-claim {
    margin: 0 0 8px;
    font-size: 1.02rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    color: var(--text);
  }
  .feature-detail {
    margin: 0;
    font-size: 0.88rem;
    color: var(--text-muted);
    line-height: 1.45;
  }

  /* ---------- Objection band (item 6): compact, fear left / answer right ---------- */
  /* ---------- Objection band, REDESIGNED (v7, founder differentiation ruling) ----------
     Mike: "the frequently asked questions kind of fact kind of thing towards the bottom of the
     page. Looks a bit like theirs as well. It needs to look better and not like theirs."

     The old form was a soft-cream slab carrying four full-width two-column Q/A rows separated by
     hairlines, which is the default shape every SaaS FAQ section in this category converges on.
     Content is unchanged (the merged trust row, the held-comment row, the time row, the data row).
     The FORM is now ours: four numbered index cards on the dossier's own paper stock, laid on the
     page's fixed-dark ground, each with the question inked at the top over a red rule in the same
     ink as the PROBATION stamp. It reads as four cards pulled out of the same paper file the
     ladder scene opens, which is a grammar this page already owns and nobody else can borrow. ---- */
  .scene-objections {
    background: #14120d;
    color: #f5f1e8;
    padding: clamp(3rem, 6vw, 5.5rem) 0;
  }
  .objections-head {
    max-width: 780px;
    margin: 0 auto clamp(28px, 3.6vw, 46px);
    text-align: center;
  }
  .objections-head .eyebrow { color: #d99a6c; }
  .objections-head h2 {
    margin: 0;
    font-size: clamp(1.9rem, 4.2vw, 3.4rem);
    line-height: 1.06;
    letter-spacing: -0.025em;
    font-weight: 800;
    color: #f5f1e8;
  }
  .objection-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(14px, 1.8vw, 20px);
  }
  @media (max-width: 760px) {
    .objection-grid { grid-template-columns: 1fr; }
    .objection-card { background: linear-gradient(178deg, #f7f1e4 0%, #efe6d0 100%); }
    .objection-answer { color: #111111; font-weight: 600; }
  }
  .objection-card {
    position: relative;
    padding: clamp(22px, 2.6vw, 30px);
    border-radius: 3px;
    background: linear-gradient(178deg, #f3ead6 0%, #e9dec4 100%);
    color: #2a2418;
    text-align: left;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.55), 0 12px 30px rgba(0, 0, 0, 0.42);
  }
  /* Numbered like a filed card, in the stamp's ink. Also the "finite set" cue: four, and you can
     see all four. */
  .objection-card::before {
    content: attr(data-n);
    display: block;
    margin-bottom: 12px;
    font-size: 0.72rem;
    font-weight: 900;
    letter-spacing: 0.16em;
    color: #b23a2c;
  }
  .objection-fear {
    margin: 0 0 15px;
    padding-bottom: 15px;
    border-bottom: 2px solid rgba(178, 58, 44, 0.38);
    font-size: clamp(1.05rem, 1.8vw, 1.32rem);
    font-weight: 800;
    line-height: 1.24;
    letter-spacing: -0.015em;
    color: #241f14;
  }
  .objection-answer {
    margin: 0;
    font-size: 0.97rem;
    font-weight: 500;
    line-height: 1.58;
    color: #524834;
  }


  .versus-card-us .versus-list li svg { color: var(--tick); }/* ---------- Pricing — LIVE (founder sign-off, this round) ----------
     The PRICING-START/END comment pair stays in the markup as a landmark, but the deploy step no
     longer strips what is between them: the numbers are blessed and this section ships. Four real
     tiers now (Free Plan / Solo / Creator / Studio at $0 / $19 / $49 / $139), a monthly-annual
     toggle where annual is two months free, and a signup button on every card including the free
     one, because under the CTA revolution the ask is identical whichever tier the reader has
     decided they are. Every number here is mirrored byte-for-byte on /b. ---------- */
  .scene-pricing { padding: clamp(3.5rem, 7vw, 7rem) 0; }
  .scene-pricing h2 { margin-top: 10px; }

  /* Billing toggle. DISPLAY ONLY: billing is not live, so both states are a price label and every
     button underneath is the same signup link. Annual is the "pay for ten" price, shown as its own
     figure rather than as a percentage, because a creator wants to know what leaves the bank. */
  .pricing-toggle {
    display: inline-flex;
    gap: 4px;
    margin: clamp(22px, 3vw, 32px) auto 0;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-soft);
  }
  .pricing-toggle-wrap { text-align: center; }
  .pricing-toggle-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 18px;
    border: none;
    border-radius: 999px;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.18s ease, color 0.18s ease;
  }
  .pricing-toggle-btn[aria-pressed="true"] {
    background: var(--bg-elevated);
    color: var(--text);
    box-shadow: var(--shadow-1);
  }
  .pricing-toggle-save {
    padding: 3px 8px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--tick) 16%, transparent);
    color: var(--tick);
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    white-space: nowrap;
  }
  /* At 320 the toggle was the last thing on either page still pushing past the frame, because the
     annual pill sits inside the button. Below 380 the pair tightens and the pill drops a size. */
  @media (max-width: 380px) {
    .pricing-toggle { gap: 2px; padding: 3px; }
    .pricing-toggle-btn { padding: 8px 11px; font-size: 0.82rem; gap: 6px; }
    .pricing-toggle-save { padding: 2px 6px; font-size: 0.64rem; }
  }

  .scene-pricing > .wrap { max-width: 1440px; }
  .pricing-grid {
    display: grid;
    grid-template-columns: minmax(160px, 0.7fr) minmax(0, 3fr);
    gap: 20px;
    margin-top: 32px;
    align-items: start;
  }
  .pricing-paid-group { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: stretch; }
  .pricing-grid > .pricing-card-custom { grid-column: 2; }
  @media (min-width: 88rem) {
    .pricing-grid { grid-template-columns: minmax(160px, 0.75fr) minmax(0, 3.3fr) minmax(180px, 0.85fr); align-items: center; }
    .pricing-grid > .pricing-card-custom { grid-column: auto; }
  }
  @media (max-width: 70rem) {
    .pricing-grid { grid-template-columns: 1fr; }
    .pricing-grid > .pricing-card-free { max-width: 360px; }
    .pricing-grid > .pricing-card-custom { grid-column: auto; }
  }
  @media (max-width: 52rem) {
    .pricing-grid { max-width: 520px; margin-inline: auto; }
    .pricing-paid-group { grid-template-columns: 1fr; gap: 28px; }
    .pricing-grid > .pricing-card-free { max-width: none; }
  }
  .pricing-card {
    position: relative;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 26px 22px 24px;
    text-align: left;
    display: flex;
    flex-direction: column;
  }
  /* AMENDMENT 9: the free card used to carry an accent border and an accent-filled "Free
     forever" badge, which made the cheapest door the loudest thing in the row. It now looks like
     the paid cards and wears its crew line in a muted badge, so Creator's anchor is the only
     accent in the grid. Clear and obvious, never promoted. */
  .pricing-card-free { border-color: var(--border); }
  .pricing-badge-quiet {
    background: var(--bg-soft);
    color: var(--text-muted);
    border: 1px solid var(--border);
    text-transform: none;
    letter-spacing: 0.02em;
    font-weight: 700;
  }
  .pricing-currency {
    margin: 12px 0 0;
    font-size: 0.8rem;
    color: var(--text-muted);
  }
  .pricing-card-popular {
    border-color: var(--cta);
    box-shadow: var(--shadow-1);
  }
  .pricing-badge {
    position: absolute;
    top: -13px;
    left: 22px;
    margin: 0;
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--cta);
    color: var(--accent-contrast);
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }
  .pricing-tier {
    margin: 0 0 6px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--brand-brown);
  }
  .pricing-price {
    margin: 0 0 4px;
    font-size: 2.3rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--text);
  }
  .pricing-price span {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-muted);
  }
  /* Reserved line under the price so the four cards keep their bullets on the same baseline
     whichever billing period is showing, and nothing jumps when the toggle flips. */
  .pricing-price-sub {
    margin: 0 0 14px;
    min-height: 1.25em;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-muted);
  }
  .pricing-line {
    margin: 0 0 18px;
    color: var(--text-muted);
    font-size: 0.9rem;
    line-height: 1.45;
  }
  .pricing-features {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 9px;
  }
  .pricing-features li {
    font-size: 0.88rem;
    color: var(--text);
    padding-left: 22px;
    position: relative;
    line-height: 1.4;
  }
  .pricing-features li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.45em;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--brand-brown) 60%, transparent);
  }
  /* The one bullet every card shares, which is the whole pricing philosophy in five words. */
  .pricing-features li.pricing-feature-all { font-weight: 700; }
  .pricing-features li.pricing-feature-all::before { background: var(--tick); }
  .cadence-flagship {
    color: var(--brand-brown);
    text-shadow: 0 0 0.8em color-mix(in srgb, var(--brand-brown) 32%, transparent);
  }

  /* A button on every card (marketing analysis item 3). All four go to the same place, because
     the signup is the same signup whichever tier the reader thinks they are. */
  .pricing-cta {
    margin-top: 22px;
    display: grid;
    grid-template-rows: minmax(50px, auto) minmax(48px, auto) minmax(50px, auto);
    align-items: start;
  }
  .btn-tier {
    display: block;
    width: 100%;
    padding: 12px 16px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
    color: var(--text);
    text-align: center;
    text-decoration: none;
    font-size: 0.94rem;
    font-weight: 700;
    min-height: 48px;
    grid-row: 2;
    transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
  }
  .btn-tier:hover { border-color: var(--brand-brown); transform: translateY(-1px); }
  .btn-tier-primary {
    background: var(--cta);
    border-color: var(--cta);
    color: var(--accent-contrast);
  }
  /* ---------- The features matrix (v7 item C) ----------
     Mike, verbatim: "when I build the features matrix to basically take the piss out of the
     competition with their graduated tiers. I want to see a giant grid of green ticks. Free tier,
     means free tier. But it's limited based on comment ingestion... I want the free tier to have
     access to everything just not very much so to speak. And slower polling rates (to protect the
     usage of the paid accounts). But it means I'm looking after the small youtuber community!"

     So: fourteen capability rows by four tier columns, and every one of the fifty-six cells is a
     tick. The joke is entirely in the shape of the thing, and the caption says the quiet part in
     his register without naming anyone. Underneath, the three rows where the tiers genuinely do
     differ, which are all usage: AI checks, polling cadence, backfill depth. Numbers are pending
     his sign-off, same as the cards above.

     Scrolls horizontally inside its own container on phones rather than shrinking to unreadable;
     the capability column stays pinned to the left edge while you swipe the tiers. ---------- */
  .matrix-head {
    max-width: 780px;
    margin: clamp(46px, 6vw, 80px) auto clamp(20px, 2.6vw, 30px);
    text-align: center;
  }
  /* Founder ruling, mid-round: the matrix is a citizen of the page, not a pricing footnote. It
     now leads the section, and its heading runs at the same scene scale as any other scene's h2
     so the eye reads it as a heading in its own right. */
  .matrix-head h3 {
    margin: 10px 0 0;
    font-size: var(--fs-scene);
    line-height: 1.06;
    letter-spacing: -0.028em;
    font-weight: 800;
  }
  .matrix-subhead {
    margin: 12px 0 0;
    color: var(--text-muted);
    line-height: 1.5;
  }
  .matrix-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    background: var(--bg-elevated);
  }
  .matrix {
    width: 100%;
    min-width: 780px;
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.9rem;
  }
  .matrix th, .matrix td {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    text-align: center;
    vertical-align: middle;
  }
  .matrix tr:last-child td { border-bottom: none; }
  .matrix thead th {
    position: sticky;
    top: 0;
    background: var(--bg-soft);
    font-size: 0.78rem;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text);
    padding-top: 15px;
    padding-bottom: 15px;
  }
  .matrix th.matrix-cap, .matrix td.matrix-cap {
    position: sticky;
    left: 0;
    z-index: 2;
    text-align: left;
    background: var(--bg-elevated);
    font-weight: 600;
    color: var(--text);
    min-width: 250px;
    box-shadow: 1px 0 0 var(--border);
  }
  .matrix thead th.matrix-cap { background: var(--bg-soft); z-index: 3; }
  .matrix-tick { width: 20px; height: 20px; color: var(--tick); display: inline-block; vertical-align: middle; }.matrix-free { color: var(--brand-brown); }.matrix-usage td { font-weight: 700; color: var(--text); }
  .matrix-usage td.matrix-cap { font-weight: 600; }
  /* The top tier's cell in a usage row, so the eye can find the end of each dial at a glance. */
  .matrix-usage td.matrix-top { color: var(--brand-brown); }
  /* ITEM 54 (Mike, from the live screenshot): "it should go the length of the table." The
     62ch max-width pinned this to roughly the first column's width, so it wrapped as a narrow
     block under the table's left edge while the table ran on past it. It now spans the table
     container. Both footnotes (the credit asterisk and, behind the cap fence, the archive
     dagger) use this class, so they line up with each other and with the grid. */
  .matrix-credit-note {
    margin: 12px 0 0;
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--text-muted);
    text-align: left;
  }
  .matrix-credit-note + .matrix-credit-note { margin-top: 6px; }
  /* THE PLANNED-ALLOWANCES QUALIFIER and its companion (19 Aug 2026, ruled in two passes the same
     evening). It was a footnote under the table for as long as the table was the only thing it
     governed. The cards took the same ruling hours later, so it is hoisted ABOVE the table, which
     is the only position that precedes both: the cards sit below the table on this page, and a
     label underneath the thing it labels only works once.
     Footnote size would undersell it, so it runs at the pricing section's small-prose size, at
     full weight and colour. A licence for figures nothing enforces yet, set in muted small print,
     is a trick. Left-aligned to the eyebrow above it and to the table's own edge below.
     NO reveal class on either line, deliberately, and it is the only copy in this section without
     one: everything else here fades in on scroll, and a legal qualifier must not be capable of
     being invisible while the numbers it governs are on screen.
     The words of both lines are ruled and have no latitude; how loudly they are said is the one
     thing about them anybody may still change. */
  .matrix-qualifier {
    margin: 0 0 4px;
    font-size: 0.86rem;
    line-height: 1.5;
    font-weight: 700;
    color: var(--text);
    text-align: left;
  }
  .matrix-qualifier-today {
    margin: 0 0 14px;
    font-size: 0.86rem;
    line-height: 1.5;
    font-weight: 600;
    color: var(--text-muted);
    text-align: left;
  }

  /* ITEM 42: the includes list that replaced sixteen identical tick rows. Two columns on
     desktop so sixteen entries read as one generous block rather than a long scroll, one
     column on phones. The tick glyph is the table's own symbol, so no new asset. */
  .includes-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px 26px;
    max-width: 900px;
    margin: clamp(20px, 2.6vw, 30px) auto clamp(24px, 3vw, 34px);
    padding: 0;
    list-style: none;
    text-align: left;
  }
  @media (max-width: 720px) { .includes-list { grid-template-columns: 1fr; } }
  .includes-list li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    font-size: 0.95rem;
    line-height: 1.4;
    font-weight: 600;
    color: var(--text);
  }
  .includes-list .matrix-tick {
    width: 17px;
    height: 17px;
    flex: 0 0 17px;
    margin-top: 2px;
    color: var(--tick);
  }
  .includes-split {
    margin: 0 0 10px;
    font-size: 0.74rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    text-align: left;
  }
  .matrix-hint {
    margin: 10px 0 0;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--brand-brown);
    text-align: left;
  }
  @media (min-width: 860px) { .matrix-hint { display: none; } }
  @media (max-width: 859px) {
    .matrix-scroll { overflow: visible; }
    .matrix { min-width: 0; }
    .matrix thead { display: none; }
    .matrix tbody, .matrix tr { display: block; }
    .matrix tr { border-bottom: 1px solid var(--border); }
    .matrix tr:last-child { border-bottom: none; }
    .matrix th.matrix-cap {
      position: static;
      display: block;
      min-width: 0;
      padding: 13px 14px;
      border-bottom: 0;
      box-shadow: none;
    }
    .matrix-usage td {
      display: flex;
      justify-content: space-between;
      gap: 16px;
      padding: 9px 14px;
      text-align: right;
    }
    .matrix-usage td::before {
      content: attr(data-plan);
      color: var(--text-muted);
      font-weight: 600;
      text-align: left;
    }
    .matrix-feature {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto auto;
      align-items: center;
      gap: 10px;
      padding-right: 14px;
    }
    .matrix-feature th.matrix-cap { grid-column: 1; }
    .matrix-feature td { display: none; border-bottom: 0; padding: 0; }
    .matrix-feature td:first-of-type { display: block; grid-column: 2; }
    .matrix-feature::after {
      content: "All plans";
      grid-column: 3;
      color: var(--text);
      font-size: 0.82rem;
      font-weight: 700;
    }
  }
/* CUSTOM card. Sits at the end of the plan row and spans the full grid width at desktop, so it
     reads as the last card rather than as a fifth cramped column, and stacks in place on phones.
     Dashed edge because it is the one card that is not a price you can pick. */
  .pricing-card-custom {
    border-style: dashed;
    border-color: var(--brand-brown);
    background: transparent;
  }
  .pricing-price-words { font-size: 1.7rem; }
  .pricing-card-note { grid-row: 3; margin: 10px 0 0; font-size: 0.78rem; color: var(--text-muted); text-align: center; }
  .pricing-card-note a { color: inherit; }
  /* THE FREE CARD'S ASTERISK FOOTNOTE (founder ruling, 28 Aug 2026: "an asterisk with small
     print - not hidden but visible"). Same fine-print size and colour as its base class, because
     it IS the page's fine print; left-aligned and with its leading line loosened because this one
     is a sentence that wraps, and centred ragged text over four lines is harder to read than the
     one-line note the base class was written for.

     DELIBERATELY NOT SMALLER, NOT FAINTER, AND NOT HIDDEN. It carries the condition on the claim
     directly above it, so anything that made it harder to read than the claim would be the
     product burying the qualification. `--text-muted` against `--bg-elevated` is the same
     contrast every other note on this page is held to. */
  .pricing-card-note-fine { text-align: left; line-height: 1.45; margin-top: 0; }
  .pricing-card-note-before { grid-row: 1; align-self: end; margin-bottom: 10px; }

  .pricing-cap-block {
    display: grid;
    gap: 12px;
    margin: clamp(20px, 2.6vw, 30px) 0 0;
  }
  .matrix-bigger { max-width: 720px; margin: 0 auto; text-align: center; font-size: 0.86rem; font-weight: 700; color: var(--brand-brown); }
  /* The cap-behaviour promise, which is the single most differentiating sentence in this section:
     the allowance is on the AI reading, never on the protection. Given a bordered plate of its own
     directly under the grid so it cannot be mistaken for small print. */
  .pricing-cap-note {
    max-width: 720px;
    margin: 0 auto;
    padding: 20px 24px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--tick);
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    text-align: left;
    font-size: clamp(0.98rem, 1.5vw, 1.08rem);
    line-height: 1.55;
    color: var(--text);
  }.pricing-footnote {
    max-width: 720px;
    margin: clamp(20px, 2.6vw, 30px) auto 0;
    text-align: center;
    font-size: 0.84rem;
    line-height: 1.55;
    color: var(--text-muted);
  }

  /* ---------- No-AI-slop statement scene ---------- */

  /* Dead-band fix (empty-space audit, item 1): this scene is deliberately image-free (Mike:
     "no product shot, just the claim"), so with the generic .scene padding it read as two short
     lines of text lost in a lot of dark nothing before and after. Tighter padding brings the
     neighbouring scenes in closer, and the claim itself is scaled up to be the commanding-scale
     element the page law asks every scene to carry. */
  .scene-statement {
    padding: clamp(3rem, 6vw, 6rem) 0;
  }
  .scene-statement h2 {
    font-size: clamp(2.75rem, 7.6vw, 5.6rem);
  }

  /* Item 1a: the display-scale zero, ported from /b and merged into this scene as its visual.
     It replaces the old second paragraph ("Our built-in machine learning classifier...") outright,
     which was the last vendor-voiced sentence in the scene: the number makes the same point as a
     fact about the product rather than a claim about our engineering. The gradient runs on the
     page's own tokens rather than /b's fixed cream-to-tan, because this scene is theme-aware and
     a near-white top stop would vanish on the light ground. */
  .statement-zero {
    margin: clamp(20px, 3.2vw, 38px) 0 8px;
    font-size: clamp(6.5rem, 22vw, 15rem);
    font-weight: 900;
    line-height: 0.82;
    letter-spacing: -0.06em;
    background: linear-gradient(180deg, var(--text) 0%, var(--brand-brown) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
  .statement-zero-label {
    max-width: 560px;
    margin: 0 auto;
    font-size: clamp(1rem, 2vw, 1.28rem);
    font-weight: 700;
    line-height: 1.35;
    color: var(--text);
  }


  /* ---------- Features bridge (v5 item 1, Mike: "between creator safety and the ladder is still
     a big empty space... we segue from creator safety to a standing ladder; that's a tough segue.
     We need more - this is what the litter tray does for you. A section with lots of important
     (sales) information. Features.")

     The band that used to be that void. Stays fixed-dark so the whole "defence" movement (banner
     -> features -> ladder -> classifier) reads as one continuous dark stretch rather than
     flashing a light slab between two darks. The GRID is this scene's commanding-scale element:
     nine cards at .wrap width (1120px, wider than the 780px .scene-inner the neighbouring copy
     uses), three across on desktop, so it lands as one big dense block of information rather
     than a thin list. Every claim is a real shipped capability; the deeper scenes below still do
     the storytelling, this is the overview that makes the segue work. ---------- */

  .scene-features-bridge {
    /* Bottom padding is deliberately much smaller than the top: the scene below is the same
       fixed-dark ground, so anything here is pure void between the grid and the ladder's sticky
       stage. .scene-ladder-intro drops its top padding to 0 to match. */
    padding: var(--space-tight) 0 clamp(1.4rem, 2.4vw, 2.4rem);
  }
  .features-bridge-head {
    max-width: 780px;
    margin: 0 auto 34px;
    text-align: center;
    padding: 0 24px;
  }
  .features-bridge-head h2 {
    /* item G: 3rem -> 3.8rem at desktop, keeping its usual half-step below the full scene token
       so the nine-card grid below it stays the scene's commanding element. */
    font-size: clamp(2.05rem, 4.6vw, 3.8rem);
    line-height: 1.05;
    letter-spacing: -0.025em;
    margin: 0;
    font-weight: 800;
  }
  .features-bridge-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
  }
  @media (max-width: 900px) {
    .features-bridge-grid { grid-template-columns: repeat(2, 1fr); }
  }
  @media (max-width: 560px) {
    .features-bridge-grid { grid-template-columns: 1fr; gap: 12px; }
  }
  .features-bridge-card {
    background: rgba(245, 241, 232, 0.045);
    border: 1px solid rgba(224, 194, 150, 0.16);
    border-radius: var(--radius-md);
    padding: 22px 22px 24px;
    text-align: left;
  }
  /* Small warm rule above each claim: gives the nine-card block internal rhythm so it reads as a
     designed grid instead of a wall of paragraphs. Decorative only. */
  .features-bridge-card::before {
    content: "";
    display: block;
    width: 26px;
    height: 3px;
    border-radius: 2px;
    background: #e0a458;
    margin-bottom: 14px;
  }
  .features-bridge-claim {
    margin: 0 0 8px;
    font-size: 1.06rem;
    line-height: 1.25;
    font-weight: 800;
    letter-spacing: -0.012em;
    color: #f5f1e8;
  }
  .features-bridge-detail {
    /* margin-bottom:auto bottom-aligns the mockup below (item B) so all three mockups in a grid
       row sit on the same line however long the copy above them runs. */
    margin: 0 0 auto;
    font-size: 0.93rem;
    line-height: 1.5;
    color: #b8b3a4;
  }

  /* ---------- Bridge-card mockups (v7 item B, Mike: "What The Litter Tray does for you - each box
     needs a snippet or graphic to show how it does the thing. It can be a mockup.")

     Nine small product-language snippets, one per card, each showing the thing being DONE rather
     than described. Built from markup and inline SVG in the product's own visual vocabulary (the
     same chips, pills, standing colours and bell the deep scenes use), never a screenshot. All
     data invented; Devon Ellery is the page's running invented troll. Capability-honest: every
     snippet depicts something the product actually does. These small examples stay inside the
     reversible Notify / Probation / Hold set; Delete is an explicitly configured rule action.

     Deliberately small. The GRID is still this scene's commanding-scale element, so no single
     snippet is allowed to become a hero. ---------- */
  .features-bridge-card { display: flex; flex-direction: column; }
  .fb-mock {
    margin: 16px 0 0;
    padding: 10px 12px;
    border-radius: 10px;
    background: rgba(8, 7, 4, 0.34);
    border: 1px solid rgba(224, 194, 150, 0.14);
    font-size: 0.76rem;
    line-height: 1.3;
    color: #cfc9ba;
    display: flex;
    align-items: center;
    gap: 9px;
  }
  .fb-mock-col { flex-direction: column; align-items: stretch; gap: 7px; }
  .fb-row { display: flex; align-items: center; gap: 7px; min-width: 0; }
  .fb-strong { font-weight: 700; color: #f5f1e8; }
  .fb-dim { color: #8f8a7b; }
  .fb-ico { width: 14px; height: 14px; flex-shrink: 0; color: #e0a458; }

  .fb-av {
    width: 24px; height: 24px; flex-shrink: 0;
    border-radius: 50%;
    background: #4a4034;
    color: #e8e2d4;
    font-size: 0.6rem; font-weight: 800; letter-spacing: 0.02em;
    display: inline-flex; align-items: center; justify-content: center;
  }
  /* Redacted comment body: the point of a held comment is that you have not read it yet. */
  .fb-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
  .fb-lines i { display: block; height: 6px; border-radius: 3px; background: rgba(245, 241, 232, 0.2); }
  .fb-lines i:last-child { width: 58%; }

  .fb-pill {
    flex-shrink: 0;
    padding: 3px 8px;
    border-radius: 999px;
    font-size: 0.64rem; font-weight: 800;
    letter-spacing: 0.03em; text-transform: uppercase;
    white-space: nowrap;
  }
  .fb-pill-warn { background: rgba(224, 164, 88, 0.16); border: 1px solid rgba(224, 164, 88, 0.55); color: #e8b877; }
  .fb-pill-notify { background: rgba(245, 241, 232, 0.07); border: 1px solid rgba(224, 194, 150, 0.38); color: #e8e2d4; }

  /* Four-rung micro ladder: the standing colours of the full ladder scene, at card scale. */
  .fb-ladder { flex-direction: column; align-items: stretch; gap: 5px; }
  .fb-rung {
    display: flex; align-items: center; gap: 8px;
    font-size: 0.72rem;
    padding-left: 8px;
    border-left: 3px solid currentColor;
    line-height: 1.35;
  }
  .fb-rung-1 { color: #6fbf8f; }
  .fb-rung-2 { color: #a8b39a; }
  .fb-rung-3 { color: #e0a458; }
  .fb-rung-4 { color: #c25a4a; }
  .fb-rung span { color: #cfc9ba; }
  .fb-rung-now span { color: #f5f1e8; font-weight: 700; }
  .fb-rung-now::after {
    content: "now";
    margin-left: auto;
    font-size: 0.58rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
    color: currentColor;
  }

  .fb-track { display: block; height: 5px; border-radius: 3px; background: rgba(245, 241, 232, 0.12); overflow: hidden; }
  .fb-track i { display: block; height: 100%; border-radius: 3px; background: #e0a458; }

  .fb-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.72rem;
    color: #f5f1e8;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .fb-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
  .fb-dot-alert { background: #c25a4a; }

  .fb-num {
    font-size: 1.5rem; font-weight: 900; line-height: 1;
    letter-spacing: -0.02em; color: #f5f1e8;
  }

  .fb-bell { position: relative; flex-shrink: 0; width: 22px; height: 22px; color: #e0a458; }
  .fb-bell svg { width: 100%; height: 100%; display: block; }
  .fb-badge {
    position: absolute; top: -5px; right: -7px;
    min-width: 15px; height: 15px; padding: 0 3px;
    border-radius: 999px;
    background: #c25a4a; color: #fff;
    font-size: 0.58rem; font-weight: 800; line-height: 15px; text-align: center;
  }

  .fb-kw {
    flex-shrink: 0;
    font-size: 0.6rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase;
    color: #d99a6c;
  }

  .fb-spark { width: 100%; height: 34px; display: block; flex: 1; }
  .fb-spark path { fill: none; stroke: #6fbf8f; stroke-width: 2.4; stroke-linecap: round; }
  .fb-spark circle { fill: #6fbf8f; }

  /* Reply glyph with a slash through it: the one thing it will never do. */
  .fb-noreply { position: relative; width: 22px; height: 22px; flex-shrink: 0; color: #8f8a7b; }
  .fb-noreply svg { width: 100%; height: 100%; display: block; }
  .fb-noreply::after {
    content: "";
    position: absolute; left: -1px; top: 50%; width: 24px; height: 2px;
    background: #c25a4a; border-radius: 2px;
    transform: rotate(-42deg);
  }

  /* ---------- The three modes (v7 item E) ----------
     Mike, verbatim: "We have Shadow mode (so you can see how the system works without it doing
     anyhting), approval mode (it's up to you to approve and train the classifier) and automatic
     mode..." and "In fact those modes need to be in a H1 heading right - multiple modes but in
     sales/marketing speak."

     The headline runs at --fs-hero, the same token the page's actual <h1> uses, so this reads as
     a second front door rather than another scene heading. The element stays an <h2> because the
     document keeps exactly one <h1> (the hero).

     Placed between the classifier scene and the audit trail on purpose: the reader has just been
     shown a robot that reads their comments and learns, which is exactly the moment the question
     "hang on, what can it actually DO?" arrives. It answers that question structurally, and the
     audit trail then closes it by showing everything written down. It also breaks the long
     fixed-dark run (banner, features, ladder, classifier) with a soft-ground slab, so the section
     carries the weight the brief asks of it.

     Capability honesty: shadow really does nothing at all, approval means no action without a
     click AND every verdict is training data, automatic still runs under the daily caps and the
     global pause. The caps/pause truth is one quiet line under the grid, not a machinery
     paragraph. ---------- */
  .scene-modes {
    background: var(--bg-soft);
    padding: var(--space-tight) 0;
  }
  .modes-head {
    max-width: 940px;
    margin: 0 auto;
    text-align: center;
    padding: 0 24px;
  }
  .modes-head h2 {
    font-size: var(--fs-hero);
    line-height: 1.02;
    letter-spacing: -0.03em;
    font-weight: 800;
    margin: 0 0 18px;
  }
  .modes-head .support { margin-top: 0; }
  .modes-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
    margin-top: clamp(30px, 4vw, 52px);
  }
  @media (max-width: 900px) {
    .modes-grid { grid-template-columns: 1fr; max-width: 520px; margin-left: auto; margin-right: auto; }
  }
  .mode-card {
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 26px 24px 24px;
    text-align: left;
    display: flex;
    flex-direction: column;
    box-shadow: var(--shadow-1);
  }
  /* The gear ladder: three bars, more of them lit on each card. Reads as one rising dial across
     the row without needing a caption to explain it. */
  .mode-meter {
    display: flex;
    align-items: flex-end;
    gap: 5px;
    height: 28px;
    margin-bottom: 18px;
  }
  .mode-meter i {
    display: block;
    width: 17px;
    border-radius: 3px;
    background: var(--border);
  }
  .mode-meter i:nth-child(1) { height: 40%; }
  .mode-meter i:nth-child(2) { height: 70%; }
  .mode-meter i:nth-child(3) { height: 100%; }
  .mode-meter i.on { background: var(--brand-brown); }
  .mode-step {
    margin: 0 0 8px;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
  }
  .mode-name {
    margin: 0 0 12px;
    font-size: clamp(1.3rem, 2.1vw, 1.85rem);
    line-height: 1.12;
    letter-spacing: -0.02em;
    font-weight: 800;
    color: var(--text);
  }
  .mode-body {
    margin: 0 0 auto;
    font-size: 0.97rem;
    line-height: 1.5;
    color: var(--text-muted);
  }
  .mode-tag {
    align-self: flex-start;
    margin-top: 20px;
    padding: 5px 11px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: var(--bg-soft);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--text-muted);
  }
  .modes-note {
    max-width: 720px;
    margin: clamp(22px, 3vw, 34px) auto 0;
    text-align: center;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--text-muted);
  }

  /* ---------- CTA cadence (v7 item I) ----------
     Studying the category pages: every one of them puts exactly ONE button in the hero (never a
     primary plus a "learn more"), and then re-offers it at the emotional peaks and at the close.
     Ours appeared once, at the hero, and then the page simply ended at the footer.

     Now: hero (unchanged), one mid-page offer at the trust peak (right after the three modes,
     which is the moment the "can I trust this near my audience" question has just been answered),
     and the closing band. The hero and the closer say the same three words on purpose, which is
     the bookend pattern; the middle one is worded differently so the page reads as confident
     rather than nagging. ---------- */
  .cta-inline {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin: clamp(26px, 3.4vw, 40px) 0 0;
  }
  .cta-inline .cta-note { margin: 0; }

  /* ---------- CTA REVOLUTION (this round) ----------
     Founder ruling, verbatim: "There's no real 'Please sir, can I join?' - join away. No human man
     in the loop needed." The ask stopped being an email to a person and became a signup, so the
     page now re-offers it at the two exits the marketing analysis identified: after the teaching
     scene (the reader convinced by the defence) and after the sponsor receipts (the reader
     convinced by the money). Deliberately short — headline, one line, the button — so it never
     reads as a scene of its own and never leaves a thin frame behind it.

     CONTRACT W4 §5 removed BOTH of those asks from the markup: the .cta-band scene after the
     teaching scene, and the bare .cta-inline button after the sponsor receipts. These .cta-band
     rules are therefore UNUSED IN THIS FILE, and they are kept on purpose rather than left behind
     by accident: the deletion is flagged for Mike's morning ratification and he may put the band
     back, in which case its styling should already be here waiting. .cta-inline is still in use,
     on the modes keystone's button and note. If the ratification confirms the deletion, sweep the
     .cta-band rules then. (landing/b.html carries its own copy of this stylesheet and still uses
     .cta-band, so nothing there depends on this block either way.) ---------- */
  .cta-band {
    background: var(--bg-soft);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    padding: clamp(2.2rem, 4vw, 3.4rem) 0;
    text-align: center;
  }
  .cta-band-inner {
    max-width: 760px;
    margin: 0 auto;
    padding: 0 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
  }
  .cta-band h3 {
    margin: 0;
    font-size: clamp(1.5rem, 3.2vw, 2.4rem);
    line-height: 1.1;
    letter-spacing: -0.025em;
    font-weight: 800;
  }
  .cta-band p {
    margin: 0;
    max-width: 640px;
    font-size: clamp(0.98rem, 1.5vw, 1.1rem);
    line-height: 1.5;
    color: var(--text-muted);
  }
  .cta-band .btn-primary { margin-top: 6px; }
  .cta-band .cta-note { margin: 0; }
  /* Ground modifier: band one lands between a fixed-dark scene and the soft modes slab, so it
     takes the page ground and the page reads dark, cream, soft rather than soft against soft. */
  .cta-band-plain { background: var(--bg); }

  /* ---------- The never-deletes keystone (item 10) ----------
     This replaces "The risk, reversed" entirely. That band named four promises the modes grid
     directly above it had already told in full, which item 41 caught as the page saying the same
     thing twice; its free-forever card also carried the funded-by story that ruling 5 killed. What
     stands in its place is the one claim no competitor spend can copy: not an absence of power
     (the product can remove, and that is muscle worth selling) but an absence of AUTONOMY, which
     is the thing a creator is actually frightened of. Display treatment rather than a card.
     Occupies the band's slot inside the modes scene, under the same hairline, and inherits the
     band's signup button, so the trust movement stays one slab. Type scale sits deliberately
     below .statement-zero: that is a glyph and this is a sentence that has to stay readable at
     phone width. ---------- */
  .keystone {
    max-width: 1040px;
    margin: clamp(30px, 4vw, 48px) auto 0;
    padding: clamp(26px, 3.2vw, 38px) 24px 0;
    border-top: 1px solid var(--border);
    text-align: center;
  }
  .keystone-line {
    margin: 0 auto;
    max-width: 20ch;
    font-size: clamp(2rem, 6vw, 4.4rem);
    font-weight: 900;
    line-height: 0.98;
    letter-spacing: -0.045em;
    background: linear-gradient(180deg, var(--text) 0%, var(--brand-brown) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }
  .keystone-support {
    max-width: 640px;
    margin: clamp(18px, 2.4vw, 26px) auto 0;
    font-size: clamp(1rem, 2vw, 1.18rem);
    font-weight: 600;
    line-height: 1.5;
    color: var(--text);
  }

  /* Bottom padding only, tightened (empty-space sweep, item 1c): closes the gap out of "Every
     action, on the record" into the ban-evasion/evidence-archive tiles below. Top padding is
     untouched. */
  /* v6 (Mike, on the live page at wide desktop, "fix the spacing again"): between the audit
     trail's subhead and the two claim cards below it sat 148px of nothing, almost exactly one
     card's height, so the cards read as an orphaned band instead of the end of that composition.
     Halved on both sides of the boundary (see .scene-safety-highlights below), which lands the
     pair at roughly 56px apart at wide desktop: an intra-composition gap, not a section break. */
  /* Top padding halved too (v6 boundary sweep at 2560): the rules gallery above ends on a dark
     panel and this scene opened on --space-section of empty cream before the bell. Kept at the
     tight token rather than smaller, because the bell hangs 78px above the notification card and
     needs room to clear the boundary. */
  .scene-audit-trail { padding-top: var(--space-tight); padding-bottom: clamp(1rem, 1.8vw, 1.75rem); }

  /* ---------- v5 empty-frame sweep, second pass: boundary padding.
     Full-page screenshot sweep at 1920x1080 (half-viewport steps) found the worst voids left on
     the page were plain scene-to-scene boundaries where --space-section stacked on both sides,
     ~250 to ~330px of nothing between two short blocks. These sections all sit either side of a
     "thin" block (a four-tile grid, a single card, a four-row table), so the full section token
     was proportionally far too much. Content is untouched in every case; this is padding only,
     and the founder card, the comparison panels and the pricing block are not modified. ---------- */
  .scene-classifier { padding-bottom: var(--space-tight); }
  .scene-community { padding-bottom: var(--space-tight); }
  .scene-founder { padding: var(--space-tight) 0; }
  .scene-feature-band { padding: var(--space-tight) 0; }
  .scene-objections { padding-top: clamp(2.5rem, 4.5vw, 4.5rem); }

  /* Top padding only, tightened (empty-space sweep, item 1d): this was the "massive chunk of
     empty space above the SENTIMENT eyebrow" — .scene-sentiment had no rule of its own, so it
     fell back to the full --space-section token stacked on top of the sentiment-stage's own
     centering (see .sentiment-stage below). Bottom padding (into "Community") is untouched. */
  /* Bottom padding tightened too (v5 item 5): with the cluster centred, the last thing on screen
     as the pin releases is the stage's own lower half, so a full --space-section on top of that
     read as a void on the way out of the scene. */
  /* Tightened again (v6, Mike on the live page at ~2000px: "fix the spacing again"). Both sides
     of this scene are runway around a sticky stage, and at wide desktop --space-tight on top of
     the stage's own slack was still reading as a void on the way in and on the way out. The scene
     above it and the scene below it are both content-dense, so the boundary can be small. */
  .scene-sentiment { padding-top: clamp(1rem, 1.8vw, 1.75rem); padding-bottom: clamp(1rem, 1.8vw, 1.75rem); }
  /* v5 item 5: the pinned cluster has to fit a 720px-tall stage, so this scene's headline is
     capped against viewport height as well as width. */
  /* item G: bumped with the rest of the scene headings, but the vh term stays in the min() because
     this one has to fit inside a 720px-tall sticky stage alongside six rows and a chart. */
  .scene-sentiment h2 { font-size: clamp(1.8rem, min(4vw, 4.8vh), 3.4rem); }

  /* Crossfading last word of the sentiment headline (founder ruling, mid-round). The three words
     share one grid cell, so the span is always as wide as "sponsors." and the stem above it never
     reflows as they swap. Base state deliberately shows the FIRST word with no animation involved,
     so a browser that ignores the animation, or a reader who has asked for less motion, still gets
     a complete, readable sentence. */
  .sentiment-cycle {
    display: inline-grid;
    vertical-align: baseline;
  }
  .sentiment-cycle > i {
    grid-area: 1 / 1;
    font-style: normal;
    /* Left-aligned inside the fixed-width cell: the headline is centred, so centring the words in
       the cell too would put a visible extra gap after "your" on every word shorter than
       "sponsors.". Normal word spacing matters more here than a perfectly centred line. */
    text-align: left;
  }
  .sentiment-cycle > i + i { opacity: 0; }
  @media (prefers-reduced-motion: no-preference) {
    .sentiment-cycle > i {
      opacity: 0;
      animation: sentiment-word-cycle 15s linear infinite;
    }
    .sentiment-cycle > i:nth-child(2) { animation-delay: 5s; }
    .sentiment-cycle > i:nth-child(3) { animation-delay: 10s; }
  }
  /* Static full form (marketing analysis item 6). Where the cycle runs, the headline ends on one
     word at a time and the other two are simply waiting their turn. Where it does NOT run — a
     reader who has asked for less motion, reader mode, a crawler taking the rendered text — the
     old fallback left the sentence ending on "channel." and the other two subjects were never
     claimed at all. Now the cycling span is replaced by the whole list in that case, so the claim
     is complete however the page is read. Only one of the two is ever in the flow. */
  .sentiment-static { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .sentiment-cycle { display: none; }
    .sentiment-static { display: inline; }
  }
  @keyframes sentiment-word-cycle {
    0% { opacity: 0; }
    4% { opacity: 1; }
    29% { opacity: 1; }
    33.333% { opacity: 0; }
    100% { opacity: 0; }
  }

  /* ---------- v6, the entry and exit voids Mike circled at ~2000px ("an almost entirely empty
     frame... only the dimmed SENTIMENT headline entering at the very bottom", and the same again
     on the way out under the trend caption).

     The cause was arithmetic, not runway: the cluster composes to a fixed ~718px whatever the
     viewport, so a 1400px-tall sticky stage was half dark by construction, and every entry and
     exit frame inherited that slack on one side. Above ~1000px of viewport height the composition
     now grows with the stage instead: wider crawl and trend, bigger row and cluster gaps, a
     larger headline. At 1400px tall the cluster goes from 718px to roughly 870px, which takes the
     dwell frame past the ink threshold and shrinks both boundary gaps by the same amount.

     Gated on viewport HEIGHT, not width, on purpose: the 720px-tall short-viewport case from the
     final proof pass (1600x720) must keep the small composition, and it never enters this block.
     Nothing here is sized as a fraction of the stage, so the v5 rule that the pin must never
     stretch the composition still holds. ---------- */
  @media (min-height: 1000px) {
    /* v7 empty-frame audit, measured and reverted: opening these caps to 52/50px made the frame
       measure WORSE, not better, because the extra room lands between the six sentiment rows and
       every one of those pixels is a blank scanline. The original ceilings stay. */
    .sentiment-cluster { gap: clamp(14px, 2.2vh, 34px); }
    .sentiment-rows { gap: clamp(14px, 2.6vh, 34px); }
    .sentiment-crawl { max-width: 860px; }
    .sentiment-trend { max-width: 860px; }
    .scene-sentiment h2 { font-size: clamp(2.4rem, min(4vw, 4.8vh), 4.2rem); }
    .scene-sentiment .support { max-width: 640px; }
  }
  /* ---------- Creator-safety highlights (ban evasion + evidence archive, pulled up from the
     general feature band per Mike's ruling that they sit under the Creator Safety banner) ---------- */

  .scene-safety-highlights {
    /* Top padding halved (v6, same void as .scene-audit-trail's bottom padding above): these two
       cards are the last beat of "Every action, on the record", so they close up against it. The
       bottom padding is untouched, because below them is a genuine half-of-the-page boundary into
       the "Your comments are valuable" banner. */
    padding: clamp(1rem, 1.8vw, 1.75rem) 0 clamp(2.5rem, 5vw, 4.5rem);
  }
  .feature-grid-2 {
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
  }

  /* ---------- Notifications composition (item 3): stylized, not a screenshot. The bell is the
     hero element at commanding scale (the app's own bell language), layered over a zoomed,
     cropped list of invented notification rows that bleed off the frame's left/right edges. ---------- */
  .notif-composition {
    position: relative;
    isolation: isolate;
    max-width: 640px;
    margin: 0 auto;
  }
  /* "Zoomed crop, bleeding off the frame edges" (Mike's sketch): a fixed-height window shorter
     than the four rows' natural stack, shifted up so the first row is cut off entering at the
     top and the last is cut off leaving at the bottom, the way a real notification feed looks
     mid-scroll. Text itself stays fully legible left-to-right; only the top/bottom rows crop. */
  .notif-list-crop {
    position: relative;
    overflow: hidden;
    height: 300px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
    box-shadow: var(--shadow-1);
  }
  .notif-rows-inner {
    position: absolute;
    top: -34px;
    left: 0;
    right: 0;
  }
  .notif-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 22px;
    border-top: 1px solid var(--border);
    background: var(--bg-elevated);
  }
  .notif-row:first-child { border-top: none; }
  .notif-dot {
    flex-shrink: 0;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    margin-top: 7px;
  }
  .notif-dot-warn { background: #e0a458; }
  .notif-dot-good { background: #6fbf8f; }
  .notif-dot-alert { background: #c25a4a; }
  .notif-dot-muted { background: var(--text-muted); opacity: 0.5; }
  .notif-row-body {
    min-width: 0;
    flex: 1;
    display: flex;
    justify-content: space-between;
    gap: 12px;
    align-items: baseline;
  }
  .notif-row-text {
    margin: 0;
    font-size: 0.92rem;
    color: var(--text);
    line-height: 1.42;
  }
  .notif-row-text strong { font-weight: 700; }
  .notif-row-time {
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
    flex-shrink: 0;
  }
  @media (max-width: 560px) {
    .notif-row-body { flex-direction: column; gap: 2px; }
  }

  .notif-bell-wrap {
    /* Raised and slightly rescaled (item 4): at the old top:-32px/116px it hung 84px down into
       the card and covered the second line of the wrapped "Sponsor mention" row beneath it. Now
       it clears every row's text, still overlapping only the first row's already-intentional
       cropped/gradient top edge. */
    position: absolute;
    top: -78px;
    right: -10px;
    width: 96px;
    height: 96px;
    z-index: 2;
    filter: drop-shadow(0 14px 26px rgba(20, 18, 14, 0.28));
  }
  @media (max-width: 560px) {
    .notif-bell-wrap { width: 68px; height: 68px; top: -46px; right: -4px; }
  }
  .notif-bell {
    width: 100%;
    height: 100%;
    color: var(--brand-brown);
  }
  .notif-bell-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 32px;
    height: 32px;
    padding: 0 7px;
    border-radius: 999px;
    background: #c23b30;
    color: #fff;
    font-size: 0.92rem;
    font-weight: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 3px solid var(--bg);
  }
  @media (max-width: 560px) {
    .notif-bell-badge { min-width: 22px; height: 22px; font-size: 0.68rem; border-width: 2px; }
  }

  /* ---------- "Your comments are valuable" banner (v6, Mike: "'Your comments are valuable - do
     more with your Comment Section' or similar - with a few ideas. Put this on the landing page.")

     The warmth half's banner, and the deliberate twin of the CREATOR SAFETY banner that opens the
     defence half: same fixed-dark ground, same eyebrow-then-uppercase-display-h2 grammar, and the
     idea chips land in exactly the slot its sibling gives the safety stats. The headline clamp is
     a little smaller only because this headline is four words rather than two. Everything the
     banner umbrellas (sentiment, the video-ideas board, the community comparison) sits below
     it. ---------- */

  /* item G: pulled up toward its sibling banner's scale (2.6/7vw/4.8rem); it stays a shade under
     because "Your comments are valuable" is a longer line than "Creator safety". */
  .scene-upside-banner h2 { font-size: clamp(2.25rem, 6vw, 4.5rem); }
  /* Bottom padding only, tightened (v6 boundary sweep): the sentiment scene below is the same
     fixed-dark ground and opens with a sticky stage, so anything here is added directly to that
     stage's own entry slack. Same reasoning as .scene-features-bridge on the defence side. */
  .scene-upside-banner { padding-bottom: clamp(1rem, 1.8vw, 1.75rem); }

  .upside-ideas {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    max-width: 760px;
    margin: 32px auto 0;
  }
  .upside-idea {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 11px 18px;
    border-radius: 999px;
    background: rgba(245, 241, 232, 0.05);
    border: 1px solid rgba(224, 194, 150, 0.22);
    font-size: 0.96rem;
    font-weight: 600;
    line-height: 1.3;
    color: #f0ebe0;
    text-align: left;
  }
  /* The same warm accent the features-bridge cards carry as a rule, here at chip scale. */
  .upside-idea::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #e0a458;
    flex-shrink: 0;
  }
  @media (max-width: 560px) {
    .upside-ideas { gap: 8px; margin-top: 26px; }
    .upside-idea { font-size: 0.9rem; padding: 10px 15px; }
  }

  /* ---------- Video ideas board (v6, Mike: "Need a new feature: Video Ideas and suggestions for
     your channel (based from comments). It's positive and clean. Also, it works on the landing
     page too.")

     The positive inversion of the moderation story: the same pass over the same comments that
     catches the ugly ones also catches the requests. Composed in the product's own card language
     using the theme tokens (so it reads in light and dark) rather than as a screenshot, and the
     spread of cards is the scene's commanding-scale element. The middle card comes forward and
     carries the Save / Dismiss pair, so the triage reads at a glance; the left card is already
     saved, which gives the board a worked-through feel instead of a showroom one.

     Capability honesty: this depicts collecting a request, quoting it, saving it and dismissing
     it, and nothing further. No drafted scripts, no writing of any kind, no trend or ranking
     analysis. The quotes are verbatim because the real feature quotes real comments and never
     paraphrases, so the mockup has to match that. Every viewer, comment and video title below is
     invented. ---------- */

  /* Both boundaries deliberately small (v6 boundary sweep): above is the sentiment stage's exit
     slack, below is the community band's own entry padding, and this scene is dense enough to
     carry the change of ground on its own. */
  .scene-ideas { padding: clamp(1.75rem, 3vw, 3.25rem) 0; }
  .scene-ideas .scene-inner { max-width: 1120px; }

  /* Community entry (v6, Mike's fourth spot: the band used to open on a viewport of nothing with
     the headline dimmed at the very bottom edge). Padding only; the panels, the magnifier callout
     and the caption are untouched. */
  .scene-community { padding-top: clamp(2rem, 3.4vw, 3.5rem); }

  .ideas-board {
    position: relative;
    max-width: 1060px;
    margin: clamp(30px, 4vw, 48px) auto 0;
    padding: clamp(18px, 2.2vw, 26px) clamp(16px, 2vw, 26px) clamp(20px, 2.4vw, 28px);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background:
      radial-gradient(120% 120% at 50% 0%, rgba(224, 164, 88, 0.14), transparent 64%),
      var(--bg-soft);
    text-align: left;
  }
  .ideas-board-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 0 4px 13px;
    border-bottom: 1px solid var(--border);
    margin-bottom: clamp(18px, 2.4vw, 28px);
  }
  .ideas-board-title {
    margin: 0;
    font-size: 1rem;
    font-weight: 800;
    letter-spacing: -0.01em;
  }
  .ideas-board-count {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-muted);
    white-space: nowrap;
  }

  .ideas-spread {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(14px, 1.8vw, 22px);
    align-items: start;
  }
  @media (max-width: 900px) {
    .ideas-spread { grid-template-columns: 1fr; max-width: 520px; margin: 0 auto; }
  }

  .idea-card {
    --idea-shadow: 0 1px 1px rgba(20, 18, 14, 0.04), 0 10px 26px rgba(20, 18, 14, 0.09);
    --idea-shadow-front: 0 2px 2px rgba(20, 18, 14, 0.05), 0 20px 46px rgba(20, 18, 14, 0.17);
    display: flex;
    flex-direction: column;
    gap: 13px;
    padding: clamp(16px, 1.7vw, 22px);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    box-shadow: var(--idea-shadow);
  }
  /* Item H: component-local dark values follow the same two-place idiom as the root palette. */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .idea-card {
      --idea-shadow: 0 1px 1px rgba(0, 0, 0, 0.35), 0 10px 26px rgba(0, 0, 0, 0.42);
      --idea-shadow-front: 0 2px 2px rgba(0, 0, 0, 0.4), 0 20px 46px rgba(0, 0, 0, 0.55);
    }
  }
  :root[data-theme="dark"] .idea-card {
    --idea-shadow: 0 1px 1px rgba(0, 0, 0, 0.35), 0 10px 26px rgba(0, 0, 0, 0.42);
    --idea-shadow-front: 0 2px 2px rgba(0, 0, 0, 0.4), 0 20px 46px rgba(0, 0, 0, 0.55);
  }
  /* The spread proper: the outer two sit back and tilt away, the middle one lifts. Only above the
     stacking breakpoint, where the three cards are actually side by side. */
  @media (min-width: 901px) {
    .idea-card-a { transform: rotate(-1.1deg) translateY(12px); }
    .idea-card-c { transform: rotate(1.1deg) translateY(12px); }
    .idea-card-front {
      transform: translateY(-8px) scale(1.035);
      z-index: 2;
      border-color: rgba(224, 164, 88, 0.6);
      box-shadow: var(--idea-shadow-front);
    }
  }

  .idea-who { display: flex; align-items: center; gap: 10px; }
  .idea-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    background: rgba(122, 75, 42, 0.12);
    color: var(--brand-brown);
    border: 1px solid var(--border);
    flex-shrink: 0;
  }
  .idea-name { margin: 0; font-size: 0.86rem; font-weight: 700; line-height: 1.25; }
  .idea-when { margin: 0; font-size: 0.74rem; color: var(--text-muted); line-height: 1.3; }
  .idea-quote {
    margin: 0;
    font-size: clamp(1rem, 1.35vw, 1.12rem);
    line-height: 1.45;
    color: var(--text);
  }
  .idea-src {
    margin: 0;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    font-size: 0.76rem;
    color: var(--text-muted);
  }
  .idea-actions { display: flex; gap: 9px; }
  .idea-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 8px 17px;
    border-radius: 999px;
    font-size: 0.83rem;
    font-weight: 700;
    border: 1px solid var(--border);
    color: var(--text-muted);
    background: transparent;
  }
  .idea-btn-save { background: #e0a458; border-color: #e0a458; color: #201406; }
  .idea-state {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-size: 0.81rem;
    font-weight: 700;
    color: #3d7a58;
  }
  @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .idea-state { color: #6fbf8f; } }
  :root[data-theme="dark"] .idea-state { color: #6fbf8f; }
  .idea-state svg { width: 15px; height: 15px; flex-shrink: 0; }

  .ideas-board-foot {
    margin: clamp(16px, 2vw, 22px) 4px 0;
    font-size: 0.8rem;
    color: var(--text-muted);
  }
  .ideas-caption {
    max-width: 640px;
    margin: clamp(20px, 2.6vw, 30px) auto 0;
    font-size: 0.95rem;
    color: var(--text-muted);
  }


  @media (max-width: 560px) {
    .scene-inner { padding-left: 20px; padding-right: 20px; }
  }
  #grid { scroll-margin-top: 90px; }
  #pricing { scroll-margin-top: 90px; }

main.page.page-with-scenes { padding: 0 0 48px; }
main.page.page-with-scenes .page-inner { padding-top: 52px; padding-bottom: 12px; }

/* Training deck hero. The landing composition borrows the live deck's left-to-tray and
   right-to-keep gesture, but remains decorative: the real controls are still in the product.

   These rules are SCENE rules — the deck became a catalogue scene in the phase-2 follow-on — and
   from Amendment 5 (item 27) the colour sweep in `scripts/tests/product-scenes.test.ts` knows it:
   its `SCENE_SELECTOR` matches `.training-demo-*`, and this block is held to the same rule as
   every other scene rule. Nothing here may name a colour. `.training-demo-card`'s drop shadow was
   the one literal left on the site inside a `product-sketch`; it is `--shadow-deck`, declared in
   `landing/site.css` beside `--shadow-1` in all five theme blocks, so the deck's cards follow the
   reader's theme like everything else does. */
.training-demo-window {
  border-color: color-mix(in srgb, var(--brand-brown) 34%, var(--border));
}
.training-demo-progress {
  margin-left: auto;
  color: var(--text-muted);
  font-size: 0.6875rem;
  font-weight: 720;
  white-space: nowrap;
}
.training-demo-body {
  padding: clamp(16px, 3vw, 24px);
  background:
    radial-gradient(circle at 50% 38%, color-mix(in srgb, var(--brand-brown) 10%, transparent), transparent 48%),
    var(--bg-elevated);
}
.training-demo-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 7px;
}
.training-demo-heading .sketch-title { margin: 0; }
.training-demo-heading > span {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-size: 0.6875rem;
  font-weight: 760;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.training-demo-board {
  position: relative;
  min-height: 318px;
  padding-bottom: 48px;
}
.training-demo-stage {
  position: absolute;
  inset: 0 0 44px;
  opacity: 1;
}
.training-demo-card {
  position: absolute;
  top: 14px;
  left: 50%;
  width: min(82%, 330px);
  min-height: 222px;
  padding: clamp(15px, 2.5vw, 19px);
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 18%, var(--border));
  border-radius: 16px;
  background: var(--bg-elevated);
  box-shadow: var(--shadow-deck);
  will-change: transform, opacity;
}
.training-demo-card-a {
  z-index: 3;
  transform: translate(-50%, 0) scale(1);
  opacity: 1;
}
.training-demo-card-b {
  z-index: 2;
  transform: translate(-50%, 11px) scale(0.96);
  opacity: 0.76;
}
.training-demo-card-c {
  z-index: 1;
  transform: translate(-50%, 22px) scale(0.92);
  opacity: 0.5;
}
.training-demo-author {
  display: flex;
  align-items: center;
  gap: 10px;
}
.training-demo-avatar {
  display: inline-flex;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 28%, var(--border));
  border-radius: 50%;
  background: color-mix(in srgb, var(--brand-brown) 12%, var(--bg-elevated));
  color: var(--brand-brown);
  font-size: 0.6875rem;
  font-weight: 850;
  letter-spacing: 0.04em;
}
.training-demo-author strong,
.training-demo-author small { display: block; }
.training-demo-author strong {
  font-size: 0.8rem;
  line-height: 1.25;
}
.training-demo-author small {
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 0.6875rem;
  line-height: 1.2;
}
.training-demo-comment {
  margin: 18px 0 16px;
  color: var(--text);
  font-size: clamp(0.91rem, 1.6vw, 1.02rem);
  font-weight: 650;
  line-height: 1.46;
}
.training-demo-verdict {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 8px;
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.training-demo-verdict span {
  padding: 3px 7px;
  border: 1px solid color-mix(in srgb, var(--brand-brown) 42%, var(--border));
  border-radius: 999px;
  background: color-mix(in srgb, var(--brand-brown) 8%, var(--bg-elevated));
  color: var(--brand-brown);
  font-size: 0.6875rem;
  font-weight: 800;
  line-height: 1.25;
}
.training-demo-verdict strong {
  color: var(--text-muted);
  font-size: 0.69rem;
  line-height: 1.35;
}
.training-demo-decision {
  position: absolute;
  top: 76px;
  z-index: 2;
  padding: 7px 10px;
  border: 2px solid currentColor;
  border-radius: 7px;
  background: color-mix(in srgb, var(--bg-elevated) 88%, transparent);
  font-size: 0.72rem;
  font-weight: 900;
  letter-spacing: 0.045em;
  line-height: 1;
  text-transform: uppercase;
  opacity: 0;
  will-change: transform, opacity;
}
.training-demo-decision-bin {
  right: 15px;
  color: var(--cross);
  transform: rotate(-7deg) scale(0.84);
}
.training-demo-decision-keep {
  left: 15px;
  color: var(--tick);
  transform: rotate(7deg) scale(0.84);
}
.training-demo-outcomes {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.training-demo-outcomes > span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-height: 34px;
  padding: 6px 10px;
  border: 1px solid currentColor;
  border-radius: 999px;
  background: var(--bg-elevated);
  font-size: 0.8125rem;
  font-weight: 820;
  line-height: 1.2;
  opacity: 1;
  transform: scale(1);
  will-change: transform, opacity;
}
.training-demo-outcomes b { font-size: 1.05rem; line-height: 0.8; }

/* THE TWO OUTCOME LABELS, IN A CLASS RATHER THAN AN ATTRIBUTE (phase-2 follow-on, Amendment 4C).
 *
 * These three declarations were written as `style="color: var(--text) !important; opacity: 1
 * !important; font-size: 0.8rem;"` on the two spans in `landing/features/teachable-ai/index.html`
 * — the last inline styles inside a `product-sketch` on the site, and the reason phase 2's
 * inline-style sweep covered placements rather than the whole tree. The deck is a catalogue scene
 * now, so it cannot carry a `style` attribute at all: the declarations move here.
 *
 * They are `!important` because they have to out-rank the outcome animations below, which fade both
 * labels in and out; an author `!important` beats a running animation, which is exactly why the
 * inline version was written that way. Doing this retires the red/green pair and its dark-mode
 * literal `#e88b84`, both of which the inline `color` had already been overriding since it was
 * added — dead rules that still read as though they decided something. */
.training-demo-outcome-ink {
  color: var(--text) !important;
  opacity: 1 !important;
  font-size: 0.8rem;
}

@media (prefers-reduced-motion: no-preference) {
  .training-demo-stage { animation: training-demo-reset 18s ease-in-out infinite paused; }
  .training-demo-card-a { animation: training-card-left 18s cubic-bezier(0.22, 0.75, 0.26, 1) infinite paused; }
  .training-demo-card-b { animation: training-card-right 18s cubic-bezier(0.22, 0.75, 0.26, 1) infinite paused; }
  .training-demo-card-c { animation: training-card-rise 18s cubic-bezier(0.22, 0.75, 0.26, 1) infinite paused; }
  .training-demo-decision-bin { animation: training-decision-bin 18s ease-in-out infinite paused; }
  .training-demo-decision-keep { animation: training-decision-keep 18s ease-in-out infinite paused; }
  .training-demo-outcome-bin { animation: training-outcome-bin 18s ease-in-out infinite paused; }
  .training-demo-outcome-keep { animation: training-outcome-keep 18s ease-in-out infinite paused; }
  .training-deck-demo.is-playing .training-demo-stage,
  .training-deck-demo.is-playing .training-demo-card,
  .training-deck-demo.is-playing .training-demo-decision,
  .training-deck-demo.is-playing .training-demo-outcomes > span { animation-play-state: running; }
}

@keyframes training-demo-reset {
  0%, 84% { opacity: 1; }
  90%, 96% { opacity: 0; }
  100% { opacity: 1; }
}
@keyframes training-card-left {
  0%, 18% { transform: translate(-50%, 0) rotate(0) scale(1); opacity: 1; }
  22% { transform: translate(calc(-50% - 8%), -3px) rotate(-3deg) scale(1); opacity: 1; }
  30%, 96% { transform: translate(calc(-50% - 82%), -14px) rotate(-13deg) scale(0.98); opacity: 0; }
  100% { transform: translate(-50%, 0) rotate(0) scale(1); opacity: 1; }
}
@keyframes training-card-right {
  0%, 18% { transform: translate(-50%, 11px) rotate(0) scale(0.96); opacity: 0.76; }
  30%, 49% { transform: translate(-50%, 0) rotate(0) scale(1); opacity: 1; }
  53% { transform: translate(calc(-50% + 8%), -3px) rotate(3deg) scale(1); opacity: 1; }
  61%, 96% { transform: translate(calc(-50% + 82%), -14px) rotate(13deg) scale(0.98); opacity: 0; }
  100% { transform: translate(-50%, 11px) rotate(0) scale(0.96); opacity: 0.76; }
}
@keyframes training-card-rise {
  0%, 18% { transform: translate(-50%, 22px) scale(0.92); opacity: 0.5; }
  30%, 49% { transform: translate(-50%, 11px) scale(0.96); opacity: 0.76; }
  61%, 96% { transform: translate(-50%, 0) scale(1); opacity: 1; }
  100% { transform: translate(-50%, 22px) scale(0.92); opacity: 0.5; }
}
@keyframes training-decision-bin {
  0%, 19% { transform: rotate(-7deg) scale(0.84); opacity: 0; }
  23%, 29% { transform: rotate(-7deg) scale(1); opacity: 1; }
  31%, 100% { transform: rotate(-7deg) scale(1); opacity: 0; }
}
@keyframes training-decision-keep {
  0%, 50% { transform: rotate(7deg) scale(0.84); opacity: 0; }
  54%, 60% { transform: rotate(7deg) scale(1); opacity: 1; }
  62%, 100% { transform: rotate(7deg) scale(1); opacity: 0; }
}
@keyframes training-outcome-bin {
  0%, 17%, 32%, 100% { transform: scale(0.98); opacity: 1; }
  22%, 29% { transform: scale(1.04); opacity: 1; }
}
@keyframes training-outcome-keep {
  0%, 48%, 63%, 100% { transform: scale(0.98); opacity: 1; }
  53%, 60% { transform: scale(1.04); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .training-demo-card-a {
    transform: translate(calc(-50% - 10%), -4px) rotate(-5deg) scale(0.99);
    opacity: 0.96;
  }
  .training-demo-card-b { transform: translate(calc(-50% + 5%), 10px) scale(0.96); opacity: 0.82; }
  .training-demo-decision-bin { transform: rotate(-7deg) scale(1); opacity: 1; }
  .training-demo-outcome-bin { transform: scale(1.04); opacity: 1; }
}

@media (max-width: 520px) {
  .training-demo-progress { font-size: 0.6875rem; }
  .training-demo-body { padding: 14px; }
  .training-demo-heading > span { display: none; }
  .training-demo-board { min-height: 300px; }
  .training-demo-card {
    width: min(84%, 290px);
    min-height: 216px;
    padding: 15px;
  }
  .training-demo-comment { margin: 15px 0 13px; font-size: 0.9rem; }
  .training-demo-outcomes > span { padding: 6px 9px; font-size: 0.75rem; }
}

/* Public layout sprint: hierarchy is local to plan choice, not a shared six-row subgrid. */
.pricing-paid-group > .pricing-card { height: 100%; min-width: 0; box-sizing: border-box; }
.pricing-paid-group .pricing-cta { margin-top: auto; padding-top: 24px; }
.pricing-grid > .pricing-card { padding: 20px 16px; }
.pricing-card .pricing-tier { scroll-margin-top: 100px; }
.pricing-grid .pricing-badge { position: static; align-self: flex-start; margin-bottom: 10px; }
.pricing-card-free .pricing-price { font-size: 2rem; }
.pricing-card-free .pricing-card-note { margin-bottom: 12px; }
.pricing-card-custom .pricing-features { font-size: .875rem; }
.plan-includes { margin: 24px 0; }
.plan-includes .includes-list { margin-block: 20px 0; }

/* Decorative thumbs match the decision direction without replacing its text label. */
.training-demo-thumb { display: inline-block; width: 1.1em; height: 1.1em; margin-inline: .2em; vertical-align: -.15em; background: currentColor; clip-path: polygon(0 40%, 25% 40%, 25% 95%, 0 95%, 0 40%, 32% 40%, 58% 0, 72% 5%, 67% 40%, 100% 40%, 100% 60%, 85% 95%, 32% 95%, 32% 40%); }
.training-demo-thumb-up { color: var(--tick); }
.training-demo-thumb-down { color: var(--cross); transform: rotate(180deg); }

/* Plans visual acceptance repair: one compact heading and stable paid price rows. */
main.plans-page .page-inner { max-width: none; padding-block: 28px 0; text-align: center; }
.plans-page .page-inner h1 { margin: 0; }
.plans-page .scene-pricing { padding-block: 16px 48px; }
.plans-page .pricing-toggle { margin-top: 0; }
.plans-page .pricing-grid { margin-top: 28px; }
.plans-page .pricing-paid-group > .pricing-card { padding-top: 38px; }
.plans-page .pricing-paid-group .pricing-badge { position: absolute; top: -13px; left: 16px; margin: 0; }
.plans-page .pricing-price { display: flex; align-items: baseline; gap: 4px; line-height: 1.15; }
.plans-page .pricing-price .price-amount { font-size: 2.75rem; font-weight: 800; color: var(--text); letter-spacing: -.03em; }
.plans-page .pricing-price .price-period { font-size: 1rem; font-weight: 600; color: var(--text-muted); }
.plans-page .pricing-paid-group .pricing-price-sub { min-height: 2.5em; line-height: 1.25; }
.plans-page .pricing-card-free .price-amount { font-size: 2.25rem; }
.plans-page .pricing-card-free .pricing-cta { margin-top: 18px; }
.plans-page .pricing-band-note { margin: 16px 0 24px; scroll-margin-top: 100px; }
.plans-page .matrix-head { margin-top: 24px; }

/* Free has one action, so it must not inherit paid-card CTA spacer rows. */
.plans-page .pricing-card-free { min-height: 0; height: auto; }
.plans-page .pricing-card-free .pricing-cta { display: block; min-height: 0; padding: 0; }
.plans-page .pricing-card-free .btn-tier { grid-row: auto; box-sizing: border-box; }
@media (min-width: 52.01rem) and (max-width: 70rem) {
  .plans-page .pricing-grid > .pricing-card-free { max-width: none; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 28px; row-gap: 8px; }
  .plans-page .pricing-card-free > .pricing-tier,
  .plans-page .pricing-card-free > .pricing-price,
  .plans-page .pricing-card-free > .pricing-line,
  .plans-page .pricing-card-free > .pricing-card-note { grid-column: 1; margin: 0; text-align: left; }
  .plans-page .pricing-card-free > .pricing-tier { grid-row: 1; }
  .plans-page .pricing-card-free > .pricing-price { grid-row: 2; }
  .plans-page .pricing-card-free > .pricing-line { grid-row: 3; }
  .plans-page .pricing-card-free > .pricing-card-note { grid-row: 4; }
  .plans-page .pricing-card-free > .pricing-features { grid-column: 2; grid-row: 1 / 4; }
  .plans-page .pricing-card-free > .pricing-cta { grid-column: 2; grid-row: 4; margin: 0; }
}
