/* Ship With Claude funnel styles. Palette = the shipped handbook's own tokens
   (kit/Start Here.html): dark ground, orange accent. Brand consistency is the point.

   2026-09-01 PROPORTIONAL REWRITE, his approved plan: the old per-size breakpoint tiers kept
   fixing one window and breaking another (every zoom level found a new hole). Now the layout is
   PROPORTIONAL - the two landing columns are shares of the screen, the steps live in a bounded
   panel with the same visual weight as the video, all type scales fluidly with the viewport, and
   the video's width is back-solved from the height its 16:9 body actually has. Structural
   breakpoints only: stack below 980px width, phone tweaks, and the gate's side-by-side fields on
   short windows. HIS wording is verbatim in config/routes.mjs; nothing here may reword it.

   Motion: transform/opacity only; hidden states come only from keyframes (fill-mode both), so
   the reduced-motion kill-switch leaves everything fully visible. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');

:root {
  --bg: #10151d;
  --panel: #1b2531;
  --panel-2: #232f3f;
  --edge: #2a3646;
  --ink: #f0f4f8;
  --muted: #97a3b2;
  --accent: #e0764a;
  --accent-hi: #ea8a61;
  --accent-ink: #10151d;
  --good: #6fbf87;
  --warn: #e08a8a;   /* validation only - readable on the dark ground, not alarming */
  --maxw: 720px;
  --radius: 14px;
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
/* THE KILL-SWITCH. Every animation and transition in this file is disarmed here. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; animation: none !important; }
}
body {
  margin: 0;
  font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.6;
  font-size: 17px;
  min-height: 100dvh;
  display: flex; flex-direction: column;
}
/* Layered ambient light: a warm glow up top, a cool counter-glow low right. */
body::before {
  content: ""; position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(900px 420px at 50% -8%, rgba(224, 118, 74, 0.13), transparent 65%),
    radial-gradient(720px 480px at 88% 105%, rgba(84, 110, 168, 0.12), transparent 70%),
    linear-gradient(180deg, rgba(240, 244, 248, 0.025), transparent 30%);
}
main { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: clamp(6px, 1.2vh, 14px) 20px clamp(10px, 2.2vh, 24px); flex: 1 0 auto; }
main.wide { max-width: min(1700px, 94vw); display: flex; flex-direction: column; justify-content: center; }
h1 {
  /* balance: the two lines split evenly instead of one long line and one short orphan */
  text-wrap: balance;
  font-size: clamp(1.55rem, 1.6vw + 0.55rem, 2.45rem);
  line-height: 1.16; margin: clamp(8px, 1.4vh, 18px) 0 clamp(5px, 0.9vh, 12px);
  letter-spacing: -0.022em; font-weight: 800;
  color: var(--ink);
  background: linear-gradient(180deg, #ffffff 55%, #c7d2de 130%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
h2 { font-size: 1.25rem; line-height: 1.3; margin: 0 0 0.7em; letter-spacing: -0.01em; font-weight: 700; color: var(--ink); }
p { margin: 0.65em 0; }
.muted { color: var(--muted); }
.small { font-size: 0.86rem; }
a { color: var(--accent); }
strong { color: var(--ink); }

/* Emphasis, disciplined: ONE emphasis color, wrapped around his verbatim words at build time. */
.hl { color: var(--accent); -webkit-text-fill-color: var(--accent); }
.hl-ink { color: var(--ink); font-weight: 600; -webkit-text-fill-color: var(--ink); }
/* Line breaks land between phrases, never inside one - reading logic, not container width. */
.nowrap { white-space: nowrap; }
/* HIS four headline lines. Inline everywhere by default, so desktop wrapping is UNCHANGED;
   the phone rule further down is the only thing that turns them into fixed lines. */
.h-ln { display: inline; }

/* Hero: HIS headline and sub, centered, exactly like the draft. */
.hero { text-align: center; padding-top: clamp(2px, 0.8vh, 10px); }
.hero h1 { max-width: 1150px; margin-left: auto; margin-right: auto; }
.hero .sub {
  font-size: clamp(0.94rem, 0.5vw + 0.62rem, 1.14rem);
  color: var(--muted); line-height: 1.55;
  max-width: 1040px; margin: 0 auto;
}
.hero-glow {
  position: absolute; inset: 0 0 auto 0; height: 420px; pointer-events: none; z-index: -1;
  background: radial-gradient(560px 260px at 50% 0%, rgba(224, 118, 74, 0.10), transparent 70%);
  animation: glowBreathe 9s ease-in-out infinite;
}
@keyframes glowBreathe {
  0%, 100% { opacity: 0.75; }
  50% { opacity: 1; }
}

/* Top bar */
.topbar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: clamp(7px, 1.2vh, 12px) 20px; border-bottom: 1px solid rgba(42, 54, 70, 0.75);
  position: relative; flex: 0 0 auto;
  background: rgba(16, 21, 29, 0.6);
}
.topbar .brand { font-weight: 700; text-decoration: none; color: var(--ink); font-size: 0.95rem; letter-spacing: -0.01em; }
.topbar .skip { font-size: 0.85rem; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
.topbar .skip:hover { color: var(--ink); }

/* Buttons */
.btn {
  display: inline-block; border: 0; cursor: pointer; text-decoration: none; text-align: center;
  background: linear-gradient(180deg, var(--accent-hi), var(--accent));
  color: var(--accent-ink);
  font-family: inherit; font-size: 1rem; font-weight: 700; letter-spacing: -0.01em;
  padding: 15px 22px; border-radius: 12px;
  width: 100%; max-width: 440px;
  box-shadow: 0 6px 24px rgba(224, 118, 74, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.25);
  transition: filter 180ms ease, transform 180ms ease, box-shadow 180ms ease;
}
.btn:hover { filter: brightness(1.06); transform: translateY(-2px); box-shadow: 0 12px 32px rgba(224, 118, 74, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.25); }
.btn:active { transform: translateY(1px); box-shadow: 0 3px 12px rgba(224, 118, 74, 0.2); }
.btn:focus-visible { outline: 3px solid var(--accent-hi); outline-offset: 3px; }
.btn:disabled { opacity: 0.6; cursor: default; transform: none; }
.btn.secondary {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  color: var(--ink); border: 1px solid var(--edge); font-weight: 600;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}
.btn.secondary:hover { filter: brightness(1.12); box-shadow: 0 10px 26px rgba(0, 0, 0, 0.35); }
.btn-note { display: block; margin-top: 8px; }

/* Cards */
.card { background: var(--panel); border: 1px solid var(--edge); border-radius: var(--radius); padding: 22px 22px; margin: 22px 0; }

/* ---- The opt-in gate (fluid: scales with viewport height, no fixed tiers) ----------------- */
.gate-card {
  max-width: 440px; margin: clamp(12px, 2.2vh, 26px) auto 0;
  padding: clamp(16px, 2.4vh, 26px) 24px;
  background: linear-gradient(180deg, var(--panel), rgba(27, 37, 49, 0.6));
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
}
.field-label {
  display: block; font-size: 0.86rem; font-weight: 600; color: var(--muted);
  margin: clamp(8px, 1.4vh, 14px) 0 5px; letter-spacing: 0.01em;
}
.gate-fields .gate-field:first-child .field-label { margin-top: 0; }
.gate-card input {
  display: block; width: 100%;
  font-size: 1rem; font-family: inherit; line-height: 1.45;
  padding: clamp(10px, 1.6vh, 14px) 14px;
  border: 1.5px solid var(--edge); border-radius: 12px;
  background: var(--bg); color: var(--ink);
  -webkit-appearance: none; appearance: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.gate-card input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(224, 118, 74, 0.15);
}
.gate-card input::placeholder { color: var(--muted); }
.gate-card input[aria-invalid="true"] { border-color: var(--warn); }
/* The button spans the card's full field width, edge to edge like the inputs above it. */
.gate-card .btn { margin-top: clamp(12px, 1.8vh, 18px); max-width: none; padding: clamp(12px, 1.8vh, 15px) 22px; }
.consent-note { margin: clamp(8px, 1.5vh, 14px) 0 0; text-align: center; line-height: 1.5; }
.consent-note a { color: var(--muted); }

/* Validation. Shown under the field it is about, cleared the moment the input becomes valid. */
.field-err { color: var(--warn); font-size: 0.86rem; margin: 6px 0 2px; }
/* The typo nudge. Deliberately NOT styled as an error: nothing is wrong yet, we are offering a
   correction they can take in one tap. Muted text, the fix itself in the accent colour. */
.field-hint { color: var(--muted); font-size: 0.86rem; margin: 6px 0 2px; }
.linklike {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
}
.linklike:hover { opacity: 0.85; }
.linklike:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* ---- The landing: proportional split, two solid objects, no void -------------------------- */
/* The split's total width is capped by the HEIGHT the video's 16:9 body can afford
   (video track = 6/11 of the split), so the composition centers and shrinks as one unit on
   short windows instead of leaving holes. Floor of 860px: below the height that supports it,
   a little scroll beats a microscopic video. */
.split {
  --vsl-budget: calc((100dvh - 450px) * 16 / 9);
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(36px, 3.5vw, 80px);
  align-items: stretch;
  width: min(100%, max(840px, calc(var(--vsl-budget) * 11 / 6 + clamp(36px, 3.5vw, 80px))));
  margin: clamp(8px, 1.8vh, 26px) auto 0;
}

/* The steps panel: the same frame language as the video, so the left side is a bounded object
   with real visual mass instead of loose text floating on darkness. */
.steps-frame {
  height: 100%; padding: 1px; border-radius: 15px;
  background: linear-gradient(160deg, rgba(224, 118, 74, 0.4), rgba(42, 54, 70, 0.7) 45%, rgba(84, 110, 168, 0.25));
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}
.steps-panel {
  height: 100%; border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel), #161e29);
  padding: clamp(16px, 2vh, 30px) clamp(18px, 1.8vw, 38px);
  display: flex; flex-direction: column;
}
.steps-intro { font-weight: 600; margin: 0 0 clamp(4px, 0.8vh, 10px); color: var(--ink); font-size: clamp(1rem, 0.45vw + 0.72rem, 1.24rem); }
/* Numbered on his instruction: the copy states a step count, so the markers count. (It said
   "7 step process" here while the list read 8, then 10 - a count copied into a comment goes stale
   silently, so this one no longer names the number.)
   The list stretches to fill the panel, steps spaced evenly - the panel is always full. */
/* 15 steps in four phases (2026-09-17). Each phase is a labelled group with a hairline above it,
   so 15 lines read as four short lists rather than one long one. The numbering continues across
   the groups: each <ol> carries `counter-reset: s <first-1>` inline from build.mjs. */
.phase + .phase { margin-top: clamp(8px, 1.3vh, 14px); padding-top: clamp(8px, 1.3vh, 14px); border-top: 1px solid rgba(42, 54, 70, 0.8); }
.phase-label {
  margin: 0 0 clamp(2px, 0.4vh, 6px); font-size: 0.74rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent);
}
.steps-plain { list-style: none; padding: 0; margin: 0; }
.steps-plain li {
  position: relative; padding: clamp(2px, 0.35vh, 5px) 0 clamp(2px, 0.35vh, 5px) clamp(30px, 1.9vw, 38px);
  font-size: clamp(0.9rem, 0.3vw + 0.66rem, 1.08rem); line-height: 1.45;
  counter-increment: s;
}
.steps-plain li::before {
  content: counter(s) "."; position: absolute; left: 0; top: clamp(2px, 0.35vh, 5px);
  color: var(--accent); font-weight: 700; font-variant-numeric: tabular-nums;
}
/* THE VIDEO STAYS IN VIEW (his choice, 2026-09-17). The steps column is now taller than the screen
   on laptops, so the video column sticks to the top while the steps scroll past - the video and
   both buttons never leave the screen and never look like an afterthought beside a long list. */
@media (min-width: 981px) {
  .split { align-items: start; }
  .steps-frame, .steps-panel { height: auto; }
  .show { position: sticky; top: clamp(12px, 2.5vh, 28px); }
}

.video-lead { text-align: center; margin: 0 0 clamp(6px, 1.2vh, 12px); font-size: clamp(1rem, 0.5vw + 0.68rem, 1.28rem); }
/* The short accent stroke under the video lead-in - emphasis without shouting. */
.video-lead::after {
  content: ""; display: block; width: 56px; height: 3px; border-radius: 2px;
  background: var(--accent); margin: 7px auto 0;
}

/* The video, framed like it matters: a 1px gradient edge and a deep soft glow. */
.vsl-frame {
  padding: 1px; border-radius: 15px;
  background: linear-gradient(135deg, rgba(224, 118, 74, 0.55), rgba(42, 54, 70, 0.7) 38%, rgba(84, 110, 168, 0.35));
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45), 0 6px 24px rgba(224, 118, 74, 0.07);
}
.vsl-wrap {
  position: relative; padding-top: 56.25%; background: #000000;
  border-radius: var(--radius); overflow: hidden;
}
.vsl-wrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vsl-placeholder { background: linear-gradient(180deg, var(--panel), #141b25); }
.vsl-placeholder .vsl-inner {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 12px; color: var(--muted);
}
.vsl-placeholder .vsl-play {
  width: 64px; height: 64px; border-radius: 50%;
  background: rgba(224, 118, 74, 0.14); border: 2px solid var(--accent);
  display: flex; align-items: center; justify-content: center;
  animation: playPulse 2.4s ease-out infinite;
}
.vsl-placeholder .vsl-play svg { display: block; margin-left: 4px; }
@keyframes playPulse {
  0% { box-shadow: 0 0 0 0 rgba(224, 118, 74, 0.35); }
  70%, 100% { box-shadow: 0 0 0 14px rgba(224, 118, 74, 0); }
}
.vsl-placeholder::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgba(240, 244, 248, 0.05) 50%, transparent 60%);
  transform: translateX(-100%);
  animation: shimmer 3.5s ease-in-out infinite;
  pointer-events: none;
}
@keyframes shimmer {
  0% { transform: translateX(-100%); }
  60%, 100% { transform: translateX(100%); }
}

/* The two buttons SIDE BY SIDE, equal width AND equal height, notes underneath and aligned -
   when one label wraps, both buttons grow together so the row never looks lopsided. */
.cta-row { display: flex; align-items: stretch; gap: 14px; margin-top: clamp(10px, 1.6vh, 16px); }
/* 🔴 THIS LINE IS LOAD-BEARING. DO NOT DELETE IT AS REDUNDANT.
   The rule above sets `display: flex`, and an AUTHOR rule beats the browser's built-in
   `[hidden] { display: none }`. So `hidden` on a .cta-row did nothing at all, and the effect was
   not subtle: the "Go to your download / You already have this" row ships with `hidden` and was
   therefore visible to EVERY visitor, bought or not - the live page showed the $27 buy button and
   the download button at the same time, plus two paid-consultation buttons. Worse, the buyer guard
   in assets/route.js sets `normalCta.hidden = true` to hide the buy row from someone who has
   already paid, and that silently failed for the same reason, so the guard could never work.
   Found 2026-09-03 by him looking at his own page during a test order.
   This is the same trap already written down in the project's rules about `.modal-backdrop`:
   any element that carries `hidden` AND whose class sets a `display` value needs this override. */
.cta-row[hidden] { display: none; }
.cta-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; text-align: center; }
.cta-col .btn {
  width: 100%; max-width: none; flex: 1 0 auto;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(11px, 1.7vh, 15px) 10px;
  font-size: clamp(0.88rem, 0.35vw + 0.64rem, 1.04rem); line-height: 1.25;
}
.cta-col .btn-note { margin-top: clamp(4px, 0.9vh, 8px); font-size: clamp(0.76rem, 0.25vw + 0.62rem, 0.88rem); }

/* ---- Motion ------------------------------------------------------------------------------- */
.fx { animation: fadeUp 0.6s cubic-bezier(0.2, 0.7, 0.3, 1) both; }
.fx-1 { animation-delay: 0s; }
.fx-2 { animation-delay: 0.08s; }
.fx-3 { animation-delay: 0.16s; }
.fx-4 { animation-delay: 0.26s; }
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* Misc */
ul.tight { padding-left: 20px; } ul.tight li { margin: 6px 0; }
ol.tight { padding-left: 20px; } ol.tight li { margin: 8px 0; }
.footer {
  flex: 0 0 auto;
  border-top: 1px solid rgba(42, 54, 70, 0.6); margin-top: 0;
  padding: clamp(5px, 1vh, 10px) 20px clamp(6px, 1.1vh, 12px);
  font-size: 0.72rem; color: var(--muted); text-align: center; line-height: 1.5;
}
.footer p { margin: 2px 0; }
.footer a { color: var(--muted); }
.notice { font-size: 0.9rem; background: var(--panel); border-left: 3px solid var(--accent); padding: 10px 14px; border-radius: 0 8px 8px 0; }
.center { text-align: center; }

/* ---- The closing help block on /thank-you/ ---------------------------------------------------
   His review 2026-09-04: "This looks ugly... make it look professional. Simple. Don't crowd
   this section. It should be prominent though."
   Prominence here comes from SEPARATION and SIZE, not from colour or a button. The download is
   the page's only primary action; this stays a link so it cannot compete with it.
   The rule (32px above, hairline, 20px below) is what stops it crowding the steps - the two
   lines were previously butted straight against the notice above with no grouping at all. */
.help-out {
  margin-top: 32px;
  padding-top: 20px;
  border-top: 1px solid var(--edge);
}
/* Body size and full-strength ink, where these were 0.86rem muted footnotes. This is the whole
   of "prominent": the block reads as content rather than as small print. */
.help-line { font-size: 1rem; line-height: 1.6; color: var(--ink); margin: 0 0 8px; }
.help-line:last-child { margin-bottom: 0; }
/* The paid option is the one thing here worth weighting, so it carries the accent and semibold.
   The vertical padding buys tap area on a phone without changing where the text sits, and the
   non-breaking space before the price keeps "($50/h)" from being orphaned on its own line. */
.help-link {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 6px 0;
}
.help-link:hover { color: var(--accent-hi); }
.help-link:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 3px; border-radius: 3px; }
code { background: var(--panel); border: 1px solid var(--edge); border-radius: 4px; padding: 1px 6px; font-size: 0.92em; }

/* ---- Images ------------------------------------------------------------------------------- */
img { max-width: 100%; height: auto; }
.topbar .brand { display: inline-flex; align-items: center; gap: 9px; }
.brand-mark { width: 36px; height: 29px; object-fit: contain; display: block; }

/* The face beside the ask - GATE ONLY. */
.byline {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  margin: clamp(8px, 1.6vh, 16px) auto 0; max-width: 440px;
}
.byline-face {
  width: clamp(44px, 6.5vh, 54px); height: clamp(44px, 6.5vh, 54px);
  border-radius: 50%; object-fit: cover; object-position: 50% 42%;
  background: var(--panel); border: 1px solid var(--edge); flex: 0 0 auto;
}
.byline-who { display: flex; flex-direction: column; line-height: 1.35; text-align: left; }
.byline-who strong { font-size: 0.95rem; letter-spacing: -0.01em; }

/* ---- Structural breakpoints (the only media queries besides reduced-motion) ---------------- */

/* Short windows, gate: name and email side by side - saves a whole row, drops nothing. */
@media (min-width: 640px) and (max-height: 700px) {
  body[data-page="gate"] .gate-card { max-width: 560px; }
  body[data-page="gate"] .gate-fields { display: flex; gap: 12px; }
  body[data-page="gate"] .gate-field { flex: 1 1 0; min-width: 0; }
  body[data-page="gate"] .gate-field .field-label { margin-top: 0; }
}

/* Stacked layout: the draft's own top-to-bottom order. Small screens scroll - no page with
   a step list and a video fits a phone screen. */
/* Phones and small tablets: the video and both buttons come FIRST, then the steps (his approved
   plan, 2026-09-17 - everyone watches the video, and 15 steps above it would push it off screen). */
@media (max-width: 980px) {
  .split { display: flex; flex-direction: column; width: auto; margin-top: 10px; }
  .show { order: -1; width: 100%; max-width: 560px; margin: 0 auto; }
  .pitch { width: 100%; max-width: 560px; margin: 26px auto 0; }
  .steps-frame, .steps-panel { height: auto; }
}
/* HIS FOUR HEADLINE LINES ON PHONES - his instruction 2026-09-02.
   TWO parts, and the second is the load-bearing one. The spans force the breaks; the vw-scaled
   size is what makes them HOLD at every phone width instead of at one tuned breakpoint. At the
   old fixed floor (1.55rem = 24.8px) the longest line, "to build apps, tools, automations",
   needs roughly 409px and a 375px phone offers 335px - so it could not fit and the browser
   wrapped it somewhere of its own choosing, cutting words. The cap keeps larger phones from
   growing past the size the rest of the page was designed around.
   The vw figure below was MEASURED in a browser at 320/360/375/390/414/430px, not estimated. */
/* The booking calendar's card. Its spacing is here rather than on the element so the phone rule
   further down can actually override it - see the note there. */
.cal-out { margin-top: 22px; padding: 10px; }

@media (max-width: 640px) {
  h1 { text-wrap: wrap; font-size: min(5vw, 1.55rem); }
  .h-ln { display: block; }
  /* 🔴 THE BOOKING CALENDAR GOES EDGE TO EDGE ON A PHONE, and it is not a style preference.
     Measured on the live page at 375px: main's 20px gutters plus the card's 10px padding left the
     embed 314px wide, and Lunacal CLIPS its own content at that width - his job title and the
     call description were both cut off mid-word, inside a cross-origin frame where nothing on
     this side can reflow them. The only lever available is giving the frame more room, so on a
     phone the card breaks out of the gutter and drops its padding: 314 -> 375.
     THE PADDING LIVES IN .cal-out ABOVE RATHER THAN IN A style= ATTRIBUTE, and that is the whole
     reason this works: the first attempt kept padding:10px inline, an inline style beats a
     stylesheet, and the embed came back 355px instead of 375. Measured, not reasoned. */
  .cal-out {
    margin-left: -20px;
    margin-right: -20px;
    padding: 0;
    border-radius: 0;
    border-left: 0;
    border-right: 0;
  }
}
@media (max-width: 480px) {
  .byline { gap: 10px; }
  .byline-face { width: 46px; height: 46px; }
  .byline-who strong { font-size: 0.9rem; }
  .brand-mark { width: 32px; height: 26px; }
  .gate-card { padding: 18px 18px; }
  .cta-row { flex-direction: column; }
  .cta-col .btn { font-size: 1rem; }
}

/* ---- Comments (2026-09-20, his decision) --------------------------------------------------
   The same frame language as .steps-frame and .vsl-frame: a 1px gradient hairline wrapping an
   inner panel, so this reads as part of the same family rather than a widget bolted on. Narrower
   than .split on purpose - it is a closing band, not a second hero.

   🔴 EVERY CLASS BELOW THAT SETS `display` HAS A `[hidden]` PAIR, AND THAT IS NOT TIDINESS.
   An author rule beats the browser's own [hidden] rule, so a class with `display: flex` shows on
   screen even when the markup says hidden. That exact bug put the buy row and the "you already
   own this" row on the live page at the same time (see .cta-row above). scripts/test-pages.mjs
   now DERIVES the list of display-setting classes from this block and fails if any lacks its
   pair, so the next class added here is covered without anyone having to remember.
*/
.comments {
  display: block;
  width: min(100%, 860px);
  margin: clamp(28px, 4vh, 56px) auto clamp(8px, 1.5vh, 18px);
}
.comments[hidden] { display: none; }

.cm-frame {
  padding: 1px;
  border-radius: 15px;
  background: linear-gradient(160deg, rgba(224, 118, 74, 0.4), rgba(42, 54, 70, 0.7) 45%, rgba(84, 110, 168, 0.25));
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.35);
}
.cm-panel {
  display: block;
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel), #161e29);
  padding: clamp(18px, 2.2vh, 32px) clamp(18px, 2vw, 38px);
}
.cm-panel[hidden] { display: none; }

.cm-title { margin: 0 0 6px; }
.cm-lead { margin: 0 0 clamp(12px, 1.8vh, 20px); }

.cm-form { display: block; margin: 0; }
.cm-form[hidden] { display: none; }

/* The inputs inherit NOTHING: every input rule in this file is scoped to `.gate-card input`, so
   without this block a comment box would have no border, no focus ring and no error state. The
   1rem size is what stops iOS zooming the page when somebody taps into it. */
.cm-input {
  display: block;
  width: 100%;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.45;
  padding: clamp(10px, 1.6vh, 14px) 14px;
  border: 1.5px solid var(--edge);
  border-radius: 12px;
  background: var(--bg);
  color: var(--ink);
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 150ms ease, box-shadow 150ms ease;
}
.cm-input[hidden] { display: none; }
.cm-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(224, 118, 74, 0.15);
}
.cm-input::placeholder { color: var(--muted); }
.cm-input[aria-invalid="true"] { border-color: var(--warn); }
.cm-text { resize: vertical; min-height: 84px; }

.cm-send { margin-top: clamp(12px, 1.8vh, 18px); max-width: 280px; }
.cm-note { margin: 10px 0 0; line-height: 1.5; }
.cm-status { margin: 12px 0 0; min-height: 1.2em; color: var(--good); }
.cm-status.bad { color: var(--warn); }

/* The honeypot. Positioned off-screen rather than display:none, because the simplest bots skip
   anything that is display:none and fill in everything else. */
.cm-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.cm-list {
  display: block;
  margin-top: clamp(18px, 2.6vh, 30px);
  border-top: 1px solid var(--edge);
}
.cm-list[hidden] { display: none; }

.cm {
  display: block;
  padding: clamp(14px, 2vh, 20px) 0;
  border-bottom: 1px solid rgba(42, 54, 70, 0.8);
}
.cm[hidden] { display: none; }
.cm:last-child { border-bottom: 0; }

.cm-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.cm-head[hidden] { display: none; }
.cm-who { font-weight: 700; letter-spacing: -0.01em; }
.cm-when { font-size: 0.8rem; color: var(--muted); }

/* Same treatment as .phase-label, so a badge here reads as the same kind of object as the
   PHASE 1 label on the steps panel. */
.cm-badge {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}
.cm-body { margin: 8px 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }

.cm-reply {
  display: block;
  margin: 12px 0 0 0;
  padding: 10px 14px;
  background: var(--panel-2);
  border-left: 3px solid var(--accent);
  border-radius: 0 8px 8px 0;
}
.cm-reply[hidden] { display: none; }

.cm-react-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.cm-react-row[hidden] { display: none; }
.cm-react {
  font: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--edge);
  background: var(--panel-2);
  color: var(--ink);
  transition: border-color 150ms ease, transform 120ms ease;
}
.cm-react:hover { transform: translateY(-1px); border-color: var(--accent); }
.cm-react[aria-pressed="true"] { border-color: var(--accent); background: rgba(224, 118, 74, 0.14); }
.cm-react:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cm-react-n { color: var(--muted); margin-left: 6px; }

.cm-more { display: block; margin: clamp(14px, 2vh, 20px) auto 0; max-width: 240px; }
.cm-more[hidden] { display: none; }

/* ---- His comments queue (the secret address) ---------------------------------------------- */
.mod-card { max-width: 420px; }
.mod-wrap { display: block; margin-top: 20px; }
.mod-wrap[hidden] { display: none; }
.mod-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.mod-tabs[hidden] { display: none; }
.mod-tab { width: auto; max-width: none; padding: 8px 14px; font-size: 0.9rem; }
.mod-tab[aria-pressed="true"] { border-color: var(--accent); }
.mod-list { display: block; }
.mod-list[hidden] { display: none; }
.mod-item {
  display: block;
  background: var(--panel);
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  padding: 16px 18px;
  margin: 0 0 14px;
}
.mod-item[hidden] { display: none; }
.mod-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.mod-actions[hidden] { display: none; }
.mod-actions .btn { width: auto; max-width: none; padding: 8px 14px; font-size: 0.9rem; }
.mod-meta { font-size: 0.8rem; color: var(--muted); margin: 4px 0 0; }
.mod-reply { margin-top: 10px; }

@media (max-width: 700px) {
  .cm-send, .cm-more { max-width: none; }
}
