/* Belly Laugh Books funnel — brand palette lifted from the live Shopify theme
   so the page is congruent with the store the customer lands in. */
:root{
  --yellow:#F9C120; --navy:#182352; --blue:#6597E4;
  --cream:#FFF9EC; --white:#fff;
  --ink:#182352; --ink-2:#3d4670;
  /* --ink-3 darkened #6b7396 -> #636b90 on 2026-08-19. The old value failed
     WCAG AA on the cream body (4.43 against 4.50 needed) for .kicker and
     .aside — small grey type like "Rave Reviews" and "Storyline Online".
     Now 4.96 on cream and 5.20 on white, and near-identical to look at. */
  --ink-3:#636b90;
  --line:#e9e2cf; --good:#1c7a4a;
  --shadow:0 2px 4px rgba(24,35,82,.06), 0 12px 32px rgba(24,35,82,.10);
  --sans:"Trebuchet MS",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --display:"Trebuchet MS",Verdana,Geneva,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{background:var(--cream);color:var(--ink);font-family:var(--sans);
  font-size:18px;line-height:1.6}
img{max-width:100%;height:auto;display:block}

.wrap{max-width:760px;margin:0 auto;padding:0 20px}
.narrow{max-width:620px;margin-left:auto;margin-right:auto}

section{padding:44px 0}
section.tight{padding:28px 0}
section.band{background:var(--white)}
section.navy{background:var(--navy);color:var(--white)}
section.navy .kicker{color:var(--yellow)}
section.yellow{background:var(--yellow)}

h1,h2,h3{font-family:var(--display);line-height:1.15;text-wrap:balance;font-weight:800}
h1{font-size:clamp(30px,6vw,46px);letter-spacing:-.01em}
h2{font-size:clamp(25px,4.6vw,34px);margin-bottom:14px}
h3{font-size:20px;margin-bottom:8px}
p{margin-bottom:16px}
p:last-child{margin-bottom:0}
strong{font-weight:700}

.kicker{font-size:13px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:12px}
.lead{font-size:clamp(19px,2.6vw,22px);color:var(--ink-2)}
.center{text-align:center}

/* ---------- proof ---------- */
.quote{background:var(--white);border:2px solid var(--line);border-radius:14px;
  padding:22px 24px;margin-bottom:16px;box-shadow:var(--shadow)}
.quote p{font-size:19px;margin-bottom:10px}
.quote cite{font-style:normal;font-size:15px;color:var(--ink-3);font-weight:700}
.stars{color:var(--yellow);font-size:19px;letter-spacing:2px;margin-bottom:8px;
  -webkit-text-stroke:1px #d9a412}
.hero-quote{background:var(--white);border-radius:16px;padding:26px;
  border:3px solid var(--yellow);box-shadow:var(--shadow)}
.hero-quote p{font-size:clamp(20px,3.4vw,26px);font-weight:700;line-height:1.35}
/* section.navy sets color:white on everything inside it, which rendered the
   quote card in the CTA cluster as white text on a white card — invisible.
   These cards carry their own light surface, so they must re-assert dark ink. */
section.navy .hero-quote,
section.navy .hero-quote p,
section.navy .quote,
section.navy .quote p{color:var(--ink)}
section.navy .hero-quote cite,
section.navy .quote cite{color:var(--ink-3)}

/* ---------- offer ---------- */
.covers{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin:26px 0}
.covers figure{flex:1 1 170px;max-width:210px;text-align:center}
.covers img{border-radius:8px;box-shadow:var(--shadow);width:100%;aspect-ratio:1;
  object-fit:cover;background:var(--white)}
.covers figcaption{font-size:14px;font-weight:700;margin-top:10px;line-height:1.3}

.price{display:flex;align-items:baseline;justify-content:center;gap:16px;
  flex-wrap:wrap;margin:6px 0 4px}
.price .was{font-size:26px;color:var(--ink-3);text-decoration:line-through;
  text-decoration-thickness:3px;text-decoration-color:#d94a3d}
.price .now{font-family:var(--display);font-size:clamp(44px,9vw,62px);
  font-weight:800;line-height:1;color:var(--navy)}
section.navy .price .now{color:var(--yellow)}
section.navy .price .was{color:#9aa3c4}
.ship{font-weight:700;font-size:17px}

ul.checks{list-style:none;margin:20px 0}
ul.checks li{position:relative;padding-left:34px;margin-bottom:12px;font-size:18px}
ul.checks li::before{content:"✓";position:absolute;left:0;top:-1px;
  width:24px;height:24px;border-radius:50%;background:var(--yellow);color:var(--navy);
  font-weight:800;font-size:15px;display:grid;place-items:center}

/* ---------- cta ---------- */
.cta{display:block;width:100%;max-width:520px;margin:0 auto;
  background:var(--yellow);color:var(--navy);border:none;border-radius:999px;
  padding:20px 26px;font-family:var(--display);font-size:clamp(19px,3.2vw,23px);
  font-weight:800;text-align:center;text-decoration:none;cursor:pointer;
  box-shadow:0 5px 0 #d9a412, var(--shadow);transition:transform .08s, box-shadow .08s}
.cta:hover{transform:translateY(-2px);box-shadow:0 7px 0 #d9a412, var(--shadow)}
.cta:active{transform:translateY(3px);box-shadow:0 2px 0 #d9a412}
.cta:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
.cta .sub{display:block;font-size:14px;font-weight:700;opacity:.72;margin-top:5px;
  letter-spacing:.02em}
.cta-ghost{background:transparent;color:var(--ink-3);box-shadow:none;border:2px solid var(--line);
  font-size:16px;padding:14px 22px;max-width:420px;font-weight:700}
.cta-ghost:hover{transform:none;box-shadow:none;border-color:var(--ink-3);color:var(--ink-2)}

.guarantee{display:flex;gap:16px;align-items:center;max-width:520px;
  margin:20px auto 0;background:var(--white);border:2px solid var(--line);
  border-radius:14px;padding:18px;text-align:left}
/* A scalloped badge, not a coloured circle with a number in it. The old
   version read as a notification dot — "14" out of context looks like an
   unread count, not a promise. */
.guarantee .seal{flex:none;width:76px;height:76px}
.guarantee p{font-size:15px;line-height:1.5;color:var(--ink-2);margin:0}
section.navy .guarantee p{color:var(--ink-2)}

/* ---------- misc ---------- */
.author{display:flex;gap:22px;align-items:flex-start;flex-wrap:wrap}
.author img{flex:none;width:132px;border-radius:50%;background:var(--white)}
.author div{flex:1 1 300px}

.faq{border-top:2px solid var(--line)}
.faq details{border-bottom:2px solid var(--line);padding:16px 0}
/* 44px minimum tap target: these summaries were 29px, and they are the one
   thing on the page a phone user is actively meant to tap. Flex centring
   rather than padding keeps the +/- marker aligned with the text. */
.faq summary{font-weight:700;cursor:pointer;font-size:18px;list-style:none;
  min-height:44px;display:flex;align-items:center;gap:1px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{content:"+ ";color:var(--blue);font-weight:800}
.faq details[open] summary::before{content:"– "}
.faq details p{margin-top:10px;font-size:17px;color:var(--ink-2)}

footer{background:var(--navy);color:#9aa3c4;padding:30px 0;font-size:14px;text-align:center}
footer a{color:#c7cee6}

/* ---------- order bump ---------- */
.bump{max-width:620px;margin:0 auto;padding:34px 20px;text-align:center}
.bump-card{background:var(--white);border:3px solid var(--yellow);border-radius:18px;
  padding:26px 22px;box-shadow:var(--shadow);margin:22px 0}
.bump .tiny{font-size:14px;color:var(--ink-3);margin-top:18px}
.progress{font-size:13px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:8px}

@media (max-width:600px){
  body{font-size:17px}
  section{padding:34px 0}
  .covers figure{flex:1 1 44%}
  .author img{width:96px;margin:0 auto}
}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

/* Order-bump price anchor. Personalization carries a real $20 standalone price
   on the storefront, so the strike-through is a true regular price, not a
   decorative one — the discount is applied by an automatic Shopify discount. */
.anchor{display:flex;align-items:baseline;justify-content:center;flex-wrap:wrap;
  gap:10px;margin:16px 0 14px}
.anchor .was{font-size:22px;color:var(--ink-3);text-decoration:line-through}
.anchor .now{font-family:var(--display);font-size:34px;color:var(--navy);line-height:1}
.anchor .off{background:var(--yellow);color:var(--navy);font-size:13px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;padding:5px 10px;border-radius:20px}

/* Hero photo — the Test 4 winning ad image, minus its headline and covers.
   Capped short so the CTA cluster still reaches the first viewport on mobile
   (Lesson 10): a tall hero pushes the button below the fold and the page stops
   converting. object-fit keeps the kids' faces in frame as it crops. */
.hero-img{display:block;width:100%;max-width:760px;margin:22px auto 0;
  height:clamp(190px,34vw,330px);object-fit:cover;object-position:50% 42%;
  border-radius:16px;box-shadow:var(--shadow)}

/* Child's-name capture on the order bump. Shopify checkout can't take a custom
   field on Basic (Plus only), so this is the last surface we control before
   payment. Kept visually quiet so it reads as part of the offer rather than as
   a form standing between the buyer and the button. */
.namefield{margin-top:18px;padding-top:16px;border-top:1px solid var(--line, #e3e7f0);
  text-align:left}
.namefield label{display:block;font-size:13px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--ink-2);margin-bottom:7px}
.namefield input{width:100%;padding:13px 14px;font-size:17px;font-family:inherit;
  color:var(--navy);background:#fff;border:2px solid #d8deec;border-radius:10px}
.namefield input:focus{outline:none;border-color:var(--yellow);
  box-shadow:0 0 0 3px rgba(249,193,32,.28)}
.namefield .hint{font-size:14px;color:var(--ink-3);margin:8px 0 0;line-height:1.4}
.namefield input + input{margin-top:8px}
.addname{display:inline-block;margin-top:10px;padding:0;background:none;border:0;
  font:600 14px/1 inherit;color:#2b5ca8;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px}
.addname:hover{color:var(--navy)}

/* Final CTA on the yellow band. This was inline styles overriding three
   properties at once, which left the button's hover/press transform pushing
   against a hard-coded shadow — it read as a flat rectangle rather than the
   pressable button every other CTA on the page is. As a class it inherits the
   same press behaviour, with a slightly deeper base so navy-on-yellow doesn't
   flatten out. */
.cta-navy{background:var(--navy);color:var(--yellow);
  box-shadow:0 5px 0 #0b1030, 0 10px 24px rgba(11,16,48,.28)}
.cta-navy:hover{box-shadow:0 3px 0 #0b1030, 0 6px 16px rgba(11,16,48,.30)}
.cta-navy:active{box-shadow:0 1px 0 #0b1030, 0 3px 8px rgba(11,16,48,.30)}
.cta-navy .sub{opacity:.85}

/* ---------- order bump — Steve's template layout ----------
   Matched to the screenshot of his Unbounce editor, not guessed from the JSON
   geometry. His shape is TWO COLUMNS under a full-width headline:

     headline (regular price struck through)
     ┌───────────────┬──────────────────────────┐
     │ product image │ offer line               │
     │   (left)      │ ★★★★★                    │
     │               │ testimonial (italic)     │
     │               │ -attribution             │
     │               │ [ Yes, add X ]           │
     │               │ [ No, do not add ]       │
     └───────────────┴──────────────────────────┘

   Both buttons carry the SAME treatment in his template — the decline is not
   de-emphasised. That is his proven design, so it is reproduced as-is. */
.sbump{max-width:900px;margin:0 auto;padding:34px 20px 48px}
.sbump h1{font-size:clamp(22px,3.4vw,30px);line-height:1.25;text-align:center;
  margin-bottom:26px}

/* Headline stack on bump-c: promise, then what it means to the child, then price.
   The h1 keeps its own margin when no deck follows (bump-d), so the deck resets it. */
.sbump h1:has(+ .sbump-deck){margin-bottom:10px}
.sbump-deck{text-align:center;font-size:clamp(16px,2.2vw,19px);line-height:1.4;
  color:var(--ink-2);max-width:560px;margin:0 auto 12px}
.sbump-price{text-align:center;font-family:var(--display);font-weight:800;
  font-size:clamp(19px,2.8vw,24px);margin:0 auto 22px}
.sbump-price .reg{font-family:var(--sans);font-size:clamp(15px,2vw,18px);
  font-weight:700;color:var(--ink-2)}
.sbump-price .reg s{text-decoration:line-through;text-decoration-thickness:2px}
.sbump h1 .reg{font-family:var(--sans);font-size:clamp(17px,2.4vw,22px);font-weight:700;
  color:var(--ink-2)}
.sbump h1 .reg s{text-decoration:line-through;text-decoration-thickness:2px}

.sbump-cols{display:flex;gap:34px;align-items:flex-start;justify-content:center}
.sbump-left{flex:0 1 340px;min-width:0}
.sbump-right{flex:1 1 380px;min-width:0;text-align:center}
.sbump-hero{width:100%;border-radius:10px;box-shadow:var(--shadow)}

/* Deliberately lighter and smaller than the headline. In Steve's template the
   headline carries the offer and the price; this line restates it in plain
   body text. At display-weight 800 it was a second headline, and the two
   fought each other. */
.sbump-offer{font-family:var(--sans);font-weight:400;
  font-size:clamp(16px,1.9vw,18px);line-height:1.5;color:var(--ink-2);
  margin-bottom:14px}
.sbump-offer em{font-style:italic;font-weight:700;color:var(--ink)}
.sbump-stars{color:var(--yellow);font-size:26px;letter-spacing:3px;line-height:1;
  -webkit-text-stroke:1px #d9a412;margin-bottom:10px}
.sbump-quote{font-style:italic;font-size:18px;line-height:1.4;margin-bottom:2px}
.sbump-cite{font-size:16px;color:var(--ink-2);margin-bottom:20px}

/* Same treatment on both, as his template has it. */
.sbump-btn{display:block;width:100%;max-width:400px;margin:0 auto 14px;
  background:var(--yellow);color:var(--navy);border-radius:999px;
  padding:17px 22px;font-family:var(--display);font-size:clamp(17px,2.2vw,21px);
  font-weight:800;text-align:center;text-decoration:none;
  box-shadow:0 5px 0 #d9a412, var(--shadow);transition:transform .08s, box-shadow .08s}
.sbump-btn:hover{transform:translateY(-2px);box-shadow:0 7px 0 #d9a412, var(--shadow)}
.sbump-btn:active{transform:translateY(3px);box-shadow:0 2px 0 #d9a412}
.sbump-btn:focus-visible{outline:3px solid var(--blue);outline-offset:3px}

.sbump .namefield{margin:0 0 20px;text-align:left;border-top:0;padding-top:0}

@media (max-width:720px){
  .sbump-cols{flex-direction:column;gap:20px;align-items:center}
  .sbump-left{flex:none;max-width:260px}
  .sbump-right{flex:none;width:100%}
}

/* The value clincher on OB2. $20 is exactly the book's retail price, so the
   fourth book plus dedications on all four costs what the book alone costs —
   worth saying plainly rather than leaving the buyer to do the arithmetic. */
.sbump-value{font-family:var(--display);font-weight:800;font-size:clamp(17px,2.2vw,20px);
  line-height:1.35;color:var(--navy);background:linear-gradient(transparent 62%, #FCE49A 62%);
  display:inline;box-decoration-break:clone;-webkit-box-decoration-break:clone;
  padding:0 2px;margin-bottom:14px}
.bump .sbump-value{display:block;margin:0 auto 14px;max-width:34ch}
/* .sbump-value is display:inline so the highlight wraps per line — which means
   its own margin-bottom does nothing. Space the next element instead. */
.sbump-value + .sbump-stars{margin-top:18px}
.sbump-value + .anchor{margin-top:18px}
/* Stars are inline in the attribution now, so the element following the value
   line is the testimonial wall — the old selector no longer matched and the
   quote was butting straight up against the highlight. */
.sbump-value + .sbump-wall{margin-top:16px}

/* Decline button: flat, no shadow, no press animation.
   A deliberate departure from Steve's template, where both buttons carry the
   same raised treatment. Targeted by data-track so no markup change is needed
   and bump-c/bump-d stay identical to each other. */
/* The decline was the SAME yellow, size and weight as the accept — only the drop
   shadow differed. Two equally-loud buttons make the reader choose between two
   apparent primaries, and 14 of 21 bump abandoners sat on this page 5–60s and
   then chose neither. This makes the decline quiet WITHOUT hiding it: still a
   full-width tap target, still plainly labelled, still underlined. Making it
   hard to find would be a dark pattern and is not the point — the point is that
   only one of the two should read as the recommended action. */
.sbump-btn[data-track="no"]{background:transparent;color:var(--ink-3);
  font-size:15px;font-weight:700;box-shadow:none;text-decoration:underline;
  text-underline-offset:3px;padding:12px 16px}
.sbump-btn[data-track="no"]:hover{transform:none;box-shadow:none;color:var(--ink-2)}
.sbump-btn[data-track="no"]:active{transform:none;box-shadow:none}

/* Testimonial wall on the order bump. Steve's bump ships with one quote; his
   sales-page template uses a wall, so three stays in his vocabulary.
   The stars sit INLINE on the attribution line rather than on their own row —
   three quotes with three separate star rows made the page noticeably taller
   without adding information, since the rating is the same each time. */
.sbump-wall{margin-bottom:16px}

/* The dedication explanation. The sales page already promises hand-signed books,
   so this block exists to say what the $9 buys that the signature doesn't. It
   reads left-aligned like the name field beneath it — three centered paragraphs
   are a wall, and .sbump-right centers everything by default. */
.sbump-why{text-align:left;margin-bottom:14px}
.sbump-why p{font-size:16px;line-height:1.45;margin:0 0 8px}
.sbump-why p:last-child{margin-bottom:0}
.sbump-why + .sbump-t{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.sbump-t + .sbump-t{margin-top:10px;padding-top:10px;border-top:1px solid var(--line)}
.sbump-wall .sbump-quote{font-size:16.5px;line-height:1.35;margin-bottom:2px}
.sbump-wall .sbump-cite{font-size:14.5px;margin-bottom:0;display:flex;
  align-items:center;justify-content:center;gap:8px;flex-wrap:wrap}
.sbump-wall .sbump-stars{display:inline-block;font-size:15px;letter-spacing:1px;
  margin:0;line-height:1;-webkit-text-stroke:.5px #d9a412}

/* The personalization art is a transparent PNG, not a book cover. The shared
   .sbump-hero shadow was drawing a rectangle around its transparent bounds,
   which read as a box floating behind the logo. Cover images on bump-d keep
   their shadow — that one IS a rectangle. */
.sbump-logo{box-shadow:none;border-radius:0;background:transparent}
.sbump-left-lg{flex:0 1 430px}
@media (max-width:720px){ .sbump-left-lg{flex:none;max-width:330px} }

/* ---------- order bump: mobile ----------
   The bump is a yes/no decision, so the buttons must be reachable without
   hunting for them. At 375px the desktop proportions put "Yes" 246px below the
   fold, with the logo alone consuming 40% of the screen. Everything here buys
   vertical space back so the decision is visible on arrival. */
@media (max-width:720px){
  .sbump{padding:14px 16px 12px}
  .sbump h1{font-size:clamp(20px,5.2vw,24px);line-height:1.18;margin-bottom:12px}
  .sbump h1 .reg{display:block;font-size:15px;margin-top:4px}

  .sbump-cols{gap:14px}
  /* The image box gets a DEFINITE height and a full-width column.
     width:auto here made the column derive its size from the image's intrinsic
     dimensions — which are zero until it loads, collapsing the column to 0px
     and hiding the image entirely (and shifting the layout when it arrived).
     A fixed 150px box with object-fit:contain reserves the space up front, so
     it renders identically loaded or not. */
  .sbump-left,.sbump-left-lg{flex:none;width:100%;max-width:none}
  /* aspect-ratio reserves a square box BEFORE the image loads, so the column
     can't collapse (the earlier bug) and nothing shifts when it arrives —
     while width:auto keeps the image sized to itself instead of being
     letterboxed inside a full-width strip. */
  .sbump-hero{height:112px;width:auto;aspect-ratio:1/1;max-width:100%;
    margin:0 auto;object-fit:contain}

  .sbump-offer{font-size:15px;line-height:1.38;margin-bottom:8px}
  .sbump-value{font-size:15.5px;line-height:1.3}

  .sbump-wall{margin-bottom:12px}
  .sbump-t + .sbump-t{margin-top:8px;padding-top:8px}
  .sbump-wall .sbump-quote{font-size:15px;line-height:1.3}
  .sbump-wall .sbump-cite{font-size:13px}
  .sbump-wall .sbump-stars{font-size:13px}

  .sbump .namefield{margin-bottom:10px}
  .sbump .namefield label{margin-bottom:4px}
  .sbump .namefield input{padding:11px 12px;font-size:16px} /* 16px: no iOS zoom */
  .sbump .namefield .hint{font-size:12.5px;line-height:1.3;margin-top:6px}
  .sbump .addname{font-size:13.5px;margin-top:8px}

  .sbump-btn{padding:13px 18px;font-size:16.5px;margin-bottom:0;max-width:none}
  /* Accept and decline look alike here, so they need real separation — a few
     pixels apart on a touch screen is a mis-tap waiting to happen. */
  .sbump-btn + .sbump-btn{margin-top:14px}
}

/* Short phones (iPhone SE and similar, ~667px tall). The bump has to fit a
   yes/no decision on screen; at this height the standard mobile sizes push the
   buttons out of reach. Trim the decorative space, not the words. */
@media (max-width:720px) and (max-height:700px){
  .sbump{padding:10px 16px 10px}
  .sbump h1{font-size:19px;margin-bottom:8px}
  .sbump h1 .reg{font-size:14px;margin-top:2px}
  .sbump-hero{height:84px}
  .sbump-cols{gap:10px}
  .sbump-offer{font-size:14.5px;line-height:1.32;margin-bottom:6px}
  .sbump-value{font-size:14.5px}
  .sbump-wall{margin-bottom:8px}
  .sbump-value + .sbump-wall{margin-top:10px}
  .sbump-wall .sbump-quote{font-size:14px}
  .sbump .namefield{margin-bottom:8px}
  .sbump .namefield .hint{font-size:12px;line-height:1.25;margin-top:4px}
  .sbump-btn{padding:11px 16px;font-size:16px;margin-bottom:0}
  .sbump-btn + .sbump-btn{margin-top:11px}
}

/* ══════════════════════════════════════════════════════════════════════════
   SALES-C — "Variant A build", from Jimmy's block breakdown of Steve's
   Variant A. APPENDED ONLY: nothing above this line is modified, so sales-a
   and sales-b cannot regress.

   Design rule this file enforces, per Jimmy: a photograph is CONTENT, never
   wallpaper. No copy is ever set over a photo. Photos are bounded — in a card,
   a column, or a rounded frame — and copy sits on flat brand colour.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- Block 1 · header lockup ------------------------------------------- */
.lockup{display:flex;align-items:center;justify-content:center;gap:26px;flex-wrap:wrap}
.lockup-art{flex:0 0 auto;width:clamp(150px,26vw,220px)}
.lockup-art img{width:100%;height:auto;display:block}
.lockup-id{flex:0 1 auto;text-align:center;max-width:420px}
.lockup-id img{width:clamp(190px,34vw,300px);height:auto;display:block;margin:12px auto 0}

/* The "flag" — a ribbon, not a rectangle, so it reads as a badge of origin
   rather than a stray text block. Notched ends via clip-path. */
.flag{display:inline-block;background:var(--yellow);color:var(--navy);
  font-family:var(--display);font-weight:800;line-height:1.25;
  font-size:clamp(13px,2.1vw,16px);letter-spacing:.01em;
  padding:11px 30px;clip-path:polygon(14px 0,100% 0,calc(100% - 14px) 100%,0 100%);
  box-shadow:0 3px 0 #d9a412}

/* ---- The comic down-arrow (Blocks 3, 7) -------------------------------- */
/* A beat, not a billboard — deliberately small. */
.arrow{display:block;margin:22px auto 0;width:clamp(64px,11vw,96px);height:auto}

/* ---- Block 2 · the EUREKA pivot ---------------------------------------- */
/* Block 2 is six unbroken paragraphs. This is the turn in the argument and
   the only place the eye can land, so it gets display treatment. */
.eureka{font-family:var(--display);font-weight:800;
  font-size:clamp(23px,4.2vw,31px);line-height:1.25;color:var(--ink);
  text-align:center;margin:30px auto;max-width:600px}
.eureka mark{background:linear-gradient(transparent 58%,#FCE39A 58%);
  color:inherit;padding:0 .12em}

/* ---- Standout single line (Block 3 "But Only From This Page") ----------- */
.standout{font-family:var(--display);font-weight:800;text-align:center;
  font-size:clamp(22px,4vw,30px);line-height:1.25;color:var(--navy);margin-top:26px}

/* ---- Inline SVG stars -------------------------------------------------- */
/* SVG, not images and not the ★ glyph — stays crisp and takes brand colour. */
.rating{display:flex;gap:3px;justify-content:center;margin-bottom:12px}
.rating svg{width:24px;height:24px;flex:none;fill:var(--yellow);stroke:#d9a412;stroke-width:1}
.rating.sm svg{width:19px;height:19px}

/* ---- Split rows · photo beside copy (Blocks 5, 7, 8, 10) --------------- */
/* THE core component. The photo is a bounded, rounded, shadowed object in its
   own column — never a background with type on top. */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,4vw,46px);
  align-items:center}
.split-narrow{grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr)}
.split figure{margin:0}
.split figure img{width:100%;height:auto;display:block;border-radius:16px;
  box-shadow:var(--shadow)}
.split .flip{order:2}          /* mirror on alternating blocks (Block 8) */

/* ---- Testimonial cards ------------------------------------------------- */
.tcard{background:var(--white);border:2px solid var(--line);border-radius:14px;
  padding:22px 24px}
.tcard p{font-size:clamp(17px,2.3vw,19px);line-height:1.45;margin-bottom:8px}
.tcard cite{font-style:normal;font-weight:700;font-size:15px;color:var(--ink-3)}
.trow{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:26px}
section.navy .tcard{background:#20305f;border-color:#33437a;color:#fff}
section.navy .tcard cite{color:#b9c2e0}

/* ---- Block 7 · the exclusivity stack ----------------------------------- */
/* Each "No —" on its own line, as written. The rule marks are the argument. */
.nostack{list-style:none;margin:20px 0}
.nostack li{font-family:var(--display);font-weight:800;
  font-size:clamp(21px,3.4vw,27px);line-height:1.2;color:var(--ink-3);
  padding:9px 0;border-bottom:2px solid var(--line)}
.nostack li:last-child{color:var(--navy);border-bottom:none}
.aside{font-size:16px;color:var(--ink-3);font-style:italic;margin-top:10px}

/* ---- Block 9 · the offer card ------------------------------------------ */
/* Sits on the yellow band. White card so the guarantee seal — which is gold —
   keeps its edge instead of dissolving into the band behind it. */
.offer{background:var(--white);border-radius:20px;padding:clamp(26px,4vw,44px);
  box-shadow:0 4px 0 #d9a412,0 18px 40px rgba(24,35,82,.16);text-align:center}
.offer h2{margin-bottom:6px}
.offer .bundle{font-family:var(--display);font-weight:800;
  font-size:clamp(21px,3.4vw,28px);color:var(--navy);margin-bottom:22px}

/* Price ladder as HTML type, never a raster: it reflows, it stays sharp, and
   it can be edited without reopening a design tool. */
.ladder{margin:26px auto 0;max-width:460px}
.ladder .reg{font-size:clamp(13.5px,1.35vw,16px);line-height:1.5;
  color:var(--ink-3);margin-bottom:6px}
/* The anchor lives INLINE in the setup line, not in a 51px row of its own.
   Two reasons, both from 2026-08-13. The pair was 77px of a 336px ladder on
   desktop just to set up a number nobody buys at. And $60.00 at 32px was
   competing with $54.95 at 68px — two large numbers on one card split the eye,
   on the exact comparison the card exists to make. Small and inline, the anchor
   is a setup beat and $54.95 is the only number that shouts.
   The arithmetic is kept unbreakable: at 375px the line must wrap somewhere, and
   breaking after "one at a time:" reads far better than orphaning "= $60.00". */
.ladder .reg .sum{white-space:nowrap}
.ladder .reg .was{font-family:var(--display);font-weight:800;font-size:1.55em;
  color:var(--ink-3);text-decoration:line-through;text-decoration-color:#d64545;
  text-decoration-thickness:3px;white-space:nowrap;
  /* line-height:1, or the taller inline inflates the row: at 1.5 the 24.8px
     struck price produced a 47px line box around 16px text. */
  line-height:1}
.ladder .strike{font-family:var(--display);font-weight:800;font-size:clamp(24px,4.4vw,32px);
  color:var(--ink-3);text-decoration:line-through;text-decoration-color:#d64545;
  text-decoration-thickness:3px;margin-bottom:10px}
.ladder .today{font-size:16px;color:var(--ink-2);margin-bottom:0}
.ladder .now{font-family:var(--display);font-weight:800;
  font-size:clamp(46px,9.5vw,68px);line-height:1;color:var(--navy);margin-bottom:10px}
.ladder .ship{font-family:var(--display);font-weight:800;
  font-size:clamp(18px,2.8vw,22px);color:var(--good);margin-top:0;margin-bottom:12px}
.ladder .versus{font-size:16.5px;line-height:1.5;color:var(--ink-2);
  margin-top:16px;padding-top:16px;border-top:2px solid var(--line)}

.seal-row{display:flex;align-items:center;justify-content:center;gap:20px;
  flex-wrap:wrap;margin:26px 0 6px}
.seal-row img{width:clamp(96px,17vw,132px);height:auto;flex:none}
.seal-row p{text-align:left;max-width:330px;font-size:16.5px;line-height:1.45}
.offer .cta{margin-left:auto;margin-right:auto}

/* ---- Block 10 · signature + credential --------------------------------- */
.sig{width:clamp(180px,30vw,240px);height:auto;display:block;margin:6px 0 0}
.credential{display:block;width:100%;max-width:520px;height:auto;margin:0 auto;
  border-radius:14px;box-shadow:var(--shadow)}
.closer{display:grid;grid-template-columns:auto 1fr;gap:24px;align-items:center;
  margin-top:34px}
.closer > img:not(.arrow){width:clamp(88px,15vw,116px);height:auto}

/* ---- Mobile ------------------------------------------------------------ */
@media (max-width:760px){
  .split,.split-narrow{grid-template-columns:1fr;gap:22px}
  .split .flip{order:0}                 /* image leads on mobile, always */
  .trow{grid-template-columns:1fr;gap:14px}
  .lockup{gap:16px}
  .closer{grid-template-columns:1fr;justify-items:center;text-align:center;gap:18px}
  .seal-row{flex-direction:column;gap:14px}
  .seal-row p{text-align:center}
  .sig{margin-left:auto;margin-right:auto}
}

/* Empty testimonial slot. Jimmy's layout opens seven; only three real reviews
   exist. Rendered as an unmistakable placeholder so it cannot ship by accident
   and so the layout can still be judged with the gaps visible. */
.tslot{border-style:dashed;border-color:#c9bfa4;background:transparent;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-height:132px;text-align:center}
.tslot p{font-family:var(--display);font-weight:800;color:#b3a88b;margin-bottom:2px}
.tslot cite{color:#b3a88b;font-weight:400;font-size:13.5px;letter-spacing:.04em;
  text-transform:uppercase}
section.navy .tslot{border-color:#4a5a8f;background:transparent}
section.navy .tslot p,section.navy .tslot cite{color:#7b88b4}

/* ---- sales-c revision pass ------------------------------------------------
   Headline is now the winning ad line; Jimmy's original opener is the subhead.
   It must NOT be bigger than body copy — that was the complaint. */
.subhead{font-family:var(--display);font-weight:800;color:var(--ink-2);
  font-size:1em;line-height:1.4;margin-bottom:18px}
.aside-note{font-size:16.5px;color:var(--ink-2);font-style:italic;
  max-width:560px;margin:14px auto 0}

/* ---- Dual readership path -------------------------------------------------
   Three weights of emphasis so a scanner who reads ONLY the marked words still
   gets the argument: <b> the claim, <u> the supporting specific, <bu> the one
   line that matters most in the block. <bu> is an unknown element, which is
   inline and styleable by default — kept short so the copy stays readable to
   edit. */
.wrap b,.wrap strong{font-weight:800;color:var(--ink)}
.wrap u{text-decoration:underline;text-decoration-thickness:2px;
  text-underline-offset:2px;text-decoration-color:#e2c56a}
bu{font-weight:800;color:var(--ink);text-decoration:underline;
  text-decoration-thickness:2.5px;text-underline-offset:2px;
  text-decoration-color:var(--yellow)}
section.navy .wrap b,section.navy .wrap strong,section.navy bu{color:#fff}

/* ---- The pointing arrow ---------------------------------------------------
   Same comic arrow, nudged toward the button it points at. The bob is what
   draws the eye down to the CTA; it stops entirely under reduced-motion. */
.arrow-point{margin:30px auto 14px;animation:arrow-bob 1.5s ease-in-out infinite}
@keyframes arrow-bob{
  0%,100%{transform:translateY(0)}
  50%{transform:translateY(11px)}
}
@media (prefers-reduced-motion:reduce){.arrow-point{animation:none}}

/* Breathing room before the offer button, per Jimmy. */
.offer .cta{margin-top:6px}
.strong-kicker{font-weight:800;color:var(--ink);font-size:15px}
.guar-head{font-size:clamp(19px,2.9vw,23px);line-height:1.3;display:inline-block;
  margin-bottom:4px}
.ladder .versus.big{font-size:clamp(18px,2.7vw,21px);line-height:1.45;color:var(--ink)}

/* Author letter: photo aligned to the TOP of the text, not floating centred. */
.split-top{align-items:start}

/* ---- The review wall (lifted from bellylaughbooks.com) --------------------- */
.wall-sub{color:var(--ink-3);margin-bottom:26px}
.wall{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;text-align:left}
.wcard{background:var(--white);border:2px solid var(--line);border-radius:14px;
  padding:20px 20px 18px;margin:0;display:flex;flex-direction:column}
.wcard .rating{justify-content:flex-start;margin-bottom:10px}
.wcard blockquote{font-size:16px;line-height:1.45;margin:0 0 16px;flex:1}
.wcard figcaption{display:flex;align-items:center;gap:11px}
.wcard .av{flex:none;width:38px;height:38px;border-radius:50%;
  background:var(--yellow);color:var(--navy);display:grid;place-items:center;
  font-family:var(--display);font-weight:800;font-size:18px}
.wcard figcaption b{display:block;font-size:15.5px;line-height:1.2;color:var(--ink)}
.wcard figcaption em{display:block;font-style:normal;font-size:13px;
  color:#96700c;font-weight:700;margin-top:2px}

@media (max-width:900px){ .wall{grid-template-columns:repeat(2,1fr)} }
@media (max-width:760px){ .wall{grid-template-columns:1fr} }

/* The closer rows put the guarantee seal to the LEFT of the button, so a
   straight-down arrow lands in the gap between them. Tilt those toward the
   button. The offer-card button is centred directly beneath its arrow, so that
   one stays vertical. Mobile stacks the row centred — reset the tilt there. */
.arrow-point.aim{margin-left:auto;margin-right:auto;
  animation:arrow-bob-aim 1.5s ease-in-out infinite}
@keyframes arrow-bob-aim{
  0%,100%{transform:rotate(15deg) translateY(0)}
  50%{transform:rotate(15deg) translateY(11px)}
}
@media (prefers-reduced-motion:reduce){
  .arrow-point.aim{animation:none;transform:rotate(15deg)}
}
@media (max-width:760px){
  .arrow-point.aim{animation:arrow-bob 1.5s ease-in-out infinite}
  @media (prefers-reduced-motion:reduce){.arrow-point.aim{animation:none;transform:none}}
}

/* Bottom ask: seal | button | arrow on one line, so the review wall doesn't hand
   off into a tall empty gap. The arrow points LEFT at the button from beside it.
   Mobile stacks, so it returns to a normal downward arrow above the button. */
.closer-inline{grid-template-columns:auto 1fr auto;gap:18px}
.arrow-side{width:clamp(56px,7vw,78px);margin:0;
  animation:arrow-nudge 1.5s ease-in-out infinite}
@keyframes arrow-nudge{
  0%,100%{transform:rotate(90deg) translateY(0)}
  50%{transform:rotate(90deg) translateY(10px)}
}
@media (prefers-reduced-motion:reduce){
  .arrow-side{animation:none;transform:rotate(90deg)}
}
@media (max-width:760px){
  .closer-inline{grid-template-columns:1fr}
  .arrow-side{order:-1;width:clamp(64px,11vw,96px);margin:0 auto 4px;
    animation:arrow-bob 1.5s ease-in-out infinite}
}

/* Closing quote inside the offer card — stars now live in the box. */
.closing-quote{border:none;box-shadow:none;padding-top:0}
.closing-quote .rating{margin-bottom:8px}
/* Give the inline bottom CTA more room so its label doesn't break after
   "Purchase" — the seal and arrow flank it, not compete with it. */
.closer-inline{gap:14px}
.closer-inline > img:first-child{width:clamp(70px,10vw,92px)}
.closer-inline .arrow-side{width:clamp(46px,6vw,64px)}
@media (max-width:760px){ .closer-inline > img:first-child{width:clamp(88px,15vw,116px)} }

/* ---- sales-c spacing pass -------------------------------------------------- */

/* Cranston: the still, then the classroom watching it. The second photo is the
   literal proof of the "one view is a whole class" line beside it. */
.stackshot{display:grid;gap:12px}
.stackshot img{width:100%;height:auto;display:block;border-radius:16px;
  box-shadow:var(--shadow)}
.stackshot figcaption{font-family:var(--display);font-weight:800;font-size:15px;
  color:var(--ink-3);text-align:center;letter-spacing:.02em}

/* Stars inline with the citation instead of stacked above the quote — the split
   cards were spending a whole row of height on them. */
.rating.inline{display:inline-flex;vertical-align:-4px;margin:0 8px 0 0}
.rating.sm.inline svg{width:16px;height:16px}

/* Offer card: the CTA and the closing proof were colliding. */
.closing-quote.spaced{margin-top:30px}

/* Wife block: the arrow was carrying more space than the beat needs. */
.wife-arrow{margin-top:8px}
#wife-block .nostack{margin-bottom:12px}
#wife-block .aside{margin-top:6px}

/* Letter close: the arrow tucks against the button's top-right corner instead of
   sitting in its own row, so the signature and the button come together. */
.closer-tight{position:relative;margin-top:18px}

/* ⭐ The scarcity line is a THIRD in-flow child of .closer on sales-c, and
   .closer is `auto 1fr` — two columns sized for exactly seal + button.
   Left alone the paragraph drops into the `auto` column, where its own text
   width inflates that column and starves the `1fr` column the button lives in.
   Result: the CTA collapses to a tall narrow pill with "Don't Wait! Purchase
   Today." wrapping onto four lines, and the arrow overlaps what's left of it.
   Spanning it across both columns puts it under the pair, which is where it
   reads anyway, and gives the button its full width back. */
.closer > .scarcity{grid-column:1/-1;margin-top:6px}
/* Sits OUTSIDE the button's top-right corner and aims down-left INTO it.
   The art points down at rest. CSS rotate() is clockwise, so a down vector (0,1)
   under +45deg becomes (-0.707, 0.707) = down-LEFT, which is what we want;
   -45deg gives (0.707, 0.707) = down-RIGHT, i.e. pointing away from the button. */
.arrow-corner{position:absolute;top:-42px;right:-56px;width:clamp(84px,10vw,116px);
  margin:0;pointer-events:none;
  animation:arrow-corner-bob 1.5s ease-in-out infinite}
@keyframes arrow-corner-bob{
  0%,100%{transform:rotate(45deg) translate(0,0)}
  50%{transform:rotate(45deg) translate(0,9px)}
}
@media (prefers-reduced-motion:reduce){
  .arrow-corner{animation:none;transform:rotate(45deg)}
}

/* Final ask sits right under the wall — no tall run-up. */
.final-ask{padding-top:16px}

/* 900px, not 760: a ROTATED element's bounding box is wider than its layout box,
   so the corner arrow pushed the document 10px past the viewport in the 760-830px
   band even though the un-rotated maths said it fitted. Measured, not assumed.
   Below this width it goes back to a plain arrow above the button. */
@media (max-width:900px){
  .closer-tight{margin-top:26px}
  .arrow-corner{position:static;display:block;margin:0 auto 6px;
    width:clamp(60px,11vw,86px);
    animation:arrow-bob 1.5s ease-in-out infinite}
  @media (prefers-reduced-motion:reduce){.arrow-corner{animation:none;transform:none}}
}
/* Captions under the stacked Cranston shots. */
.stackshot .shotcap{font-family:var(--sans);font-weight:600;font-size:13.5px;
  line-height:1.35;color:var(--ink-3);text-align:center;letter-spacing:0;
  margin:-4px 0 4px}
.stackshot .shotcap i{font-style:italic}

/* Award seals under the ask, inside the offer card. Institutional proof beside
   the customer proof — a different kind of evidence, so it adds instead of
   repeating. Wraps to two rows on narrow screens rather than shrinking to
   illegible. */
.awards{margin-top:30px;padding-top:24px;border-top:2px solid var(--line)}
.awards-cap{font-family:var(--display);font-weight:800;
  font-size:clamp(17px,2.6vw,21px);color:var(--ink);margin-bottom:16px}
.awards-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(14px,3vw,28px)}
.awards-row img{width:clamp(66px,10vw,98px);height:auto;display:block}
/* Offer-card CTA gets the same corner arrow as the letter close. The wrapper is
   pinned to the button's own width (not the card's) so the arrow lands on the
   BUTTON's corner; anchoring to the card would float it out in the margin. */
.cta-wrap{position:relative;max-width:520px;margin:0 auto}
.cta-wrap .cta{margin-top:0}
@media (max-width:900px){ .cta-wrap{max-width:none} }

/* The guarantee seal row and the button were sitting 6px apart. */
.offer .seal-row{margin-bottom:20px}
.offer .cta-wrap{margin-top:22px}

/* ══════════════════════════════════════════════════════════════════════════
   SALES-D — "Variant C build". Appended; nothing above is modified, so
   sales-a/b/c cannot regress.
   ══════════════════════════════════════════════════════════════════════════ */

/* Block 1 — the hook. The quoted phrase carries the joke, so it gets the colour. */
.hook-q{color:#c8402f}
.crazy{display:block;width:100%;max-width:520px;height:auto;margin:26px auto 0;
  border-radius:16px;box-shadow:var(--shadow);background:var(--line)}

/* Block 3 — book cards with the description on an accordion.
   The HOOK LINE stays visible so a reader who never opens one still learns what
   each book is; only the fuller description sits behind the toggle. Native
   <details>, so it needs no JS and stays keyboard accessible. */
.tap-hint{text-align:center;font-family:var(--display);font-weight:800;
  font-size:15px;letter-spacing:.02em;color:var(--ink-3);margin:26px 0 16px}
.bookrow{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:start}
.bookcard{background:var(--white);border:2px solid var(--line);border-radius:16px;
  padding:18px 18px 16px;display:flex;flex-direction:column}
/* ⭐ 2026-08-19: the cover, the title AND the hook now live inside <summary>, so
   the whole top of the card is the toggle. The page said "Tap each title" while
   only a 35px "Read the story" link was live — leftover wording from Steve's
   LIGHTBOX design, which we replaced with accordions (see the note in sales-d).
   Our tracker caught 14 dead clicks in these cards, 3 of them on the titles:
   people doing exactly what the page told them to. */
.bookcard summary > img{width:100%;height:auto;display:block;margin-bottom:12px}
.bookcard summary{cursor:pointer;list-style:none;display:block}
.bookcard summary::-webkit-details-marker{display:none}
.bookcard h3{font-size:17px;line-height:1.25;margin-bottom:8px}
.bookhook{font-size:15.5px;line-height:1.45;color:var(--ink-2);margin-bottom:10px}
.bookcard details{border:none;padding:0;margin:0 0 10px}
/* The affordance moved to .readmore — summary is now the whole card top, so it
   must not look like a link itself. */
.readmore{display:inline-block;font-family:var(--display);font-weight:800;
  font-size:14.5px;color:var(--blue);min-height:24px}
.readmore::after{content:" \203A"}
.bookcard details[open] .readmore::after{content:" \2039"}
.bookcard summary:hover .readmore{text-decoration:underline}
.bookcard summary:focus-visible{outline:3px solid var(--blue);outline-offset:3px;
  border-radius:10px}
.bookcard details[open] .readmore{color:var(--ink-3)}
.bookmore{padding-top:6px}
.bookmore p{font-size:15px;line-height:1.5;margin-bottom:9px}
.bookmeta{font-size:13.5px;color:var(--ink-3);margin-bottom:0}
.bookprice{margin-top:auto;padding-top:10px;font-size:15px;color:var(--ink-3)}
.bookprice .reg{display:block;font-size:12.5px;letter-spacing:.08em;
  text-transform:uppercase;font-weight:700}
.bookprice s{font-family:var(--display);font-weight:800;font-size:22px;
  color:var(--ink-3);text-decoration-color:#d64545;text-decoration-thickness:3px}
.allthree{text-align:center;margin-top:24px;font-family:var(--display);
  font-weight:800;font-size:clamp(18px,2.8vw,22px);color:var(--ink)}
.allthree s{text-decoration-color:#d64545;text-decoration-thickness:4px;
  font-size:1.35em;margin-left:6px}

/* Block 6 — the price argument */
.bigstrike{font-family:var(--display);font-weight:800;
  font-size:clamp(44px,9vw,66px);line-height:1;margin:10px 0 18px}
.bigstrike s{text-decoration-color:#d64545;text-decoration-thickness:5px;
  color:var(--ink-3)}
.pricecovers figcaption{font-size:15px}
.pricecovers figcaption s{color:var(--ink-3);text-decoration-color:#d64545}
.pricecovers figcaption b{color:var(--good);font-size:18px;margin-left:4px}

/* Award rows outside the offer card need no divider above them. */
.awards-bare{border-top:none;padding-top:0;margin-top:30px}
.awards-row.wide{max-width:820px;margin:0 auto}

/* Block 11 — press logos. Greyed so they read as a quiet credential strip
   rather than competing with the award seals directly above. */
.press{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(22px,4vw,44px);margin-top:14px}
.press img{height:clamp(24px,3.4vw,34px);width:auto;opacity:.62;
  filter:grayscale(1)}

/* Block 13 — cover left, description right */
.bookline{display:grid;grid-template-columns:auto 1fr;gap:20px;align-items:center;
  text-align:left;padding:16px 0;border-bottom:2px solid var(--line)}
.bookline:last-of-type{border-bottom:none}
.bookline > img{width:clamp(88px,14vw,124px);height:auto;display:block}
.bookline h3{font-size:clamp(17px,2.4vw,20px);line-height:1.25;margin-bottom:6px}
.bookline p{font-size:16px;line-height:1.45;margin-bottom:0}

@media (max-width:760px){
  .bookrow{grid-template-columns:1fr;gap:16px}
  .bookcard{padding:16px}
  .bookcard summary > img{max-width:220px;margin-left:auto;margin-right:auto}
  .bookline{grid-template-columns:1fr;text-align:center;gap:12px}
  .bookline > img{margin:0 auto;width:clamp(110px,30vw,150px)}
  .press img{height:26px}
}

/* The corner arrow is tuned for the 520px offer button. Inside a .split column
   the button is roughly half that, so the same 92px of overlap swallows the
   label. Scale the arrow and its protrusion down to match the smaller target. */
.split .cta-wrap .arrow-corner{width:clamp(44px,4.6vw,58px);top:-24px;right:-22px}
@keyframes arrow-corner-bob-sm{
  0%,100%{transform:rotate(45deg) translate(0,0)}
  50%{transform:rotate(45deg) translate(0,7px)}
}
.split .cta-wrap .arrow-corner{animation-name:arrow-corner-bob-sm}

/* Equal-height book cards so the struck prices line up across the row. */
.bookrow{align-items:stretch}

/* The press strip was reading too faint to identify. */
.press img{opacity:.78}
/* Block 3 opens on a parent's own words rather than a claim, so it is set as a
   quote, not a headline. */
.parent-quote{font-style:italic;color:var(--ink);margin-bottom:14px}
/* Block 13 — per-title editorial reviews instead of descriptions. */
.edrev{margin:0;font-size:15.5px;line-height:1.5;font-style:italic;color:var(--ink-2)}
.edrev b{font-style:normal}
/* Stacked press quotes need air; .edrev is margin:0 for single use. */
.edrev + .edrev{margin-top:20px}
.edrev cite{display:block;font-style:normal;font-weight:700;font-size:14px;
  color:var(--ink-3);margin-top:7px}

/* "Just me. The author." — the cutout carries that line, and it is transparent,
   so it needs no frame or shadow the way a photograph does. */
.author-shot img{width:100%;height:auto;display:block;border-radius:0;box-shadow:none}
/* Press strip reads bigger, and gets air before the CTA underneath it. */
.press{margin-top:20px;margin-bottom:44px}
.press img{height:clamp(34px,4.8vw,50px)}
@media (max-width:760px){ .press img{height:34px} .press{margin-bottom:34px} }
/* 12 seals on a flex-wrap row landed 5+5+2, which still leaves an odd last row.
   An explicit grid divides 12 evenly at every breakpoint: 6x2, 4x3, 3x4. */
.awards-row.wide{display:grid;grid-template-columns:repeat(6,1fr);
  justify-items:center;align-items:center;gap:clamp(12px,2.2vw,24px);max-width:760px}
@media (max-width:860px){ .awards-row.wide{grid-template-columns:repeat(4,1fr)} }
@media (max-width:520px){ .awards-row.wide{grid-template-columns:repeat(3,1fr)} }
/* Kirkus is a wide wordmark and JacketFlap is a tall crest, so sizing the press
   logos by height alone threw the row out. Cap both axes and let each logo find
   its own size inside that box. */
.press img{height:auto;width:auto;max-height:clamp(30px,4vw,44px);
  max-width:clamp(110px,15vw,168px);object-fit:contain}
/* Beat between the end of the price argument and "Here's the deal though..." */
.deal-gap{height:clamp(28px,5vw,52px)}
/* A testimonial with the moment it describes sitting underneath it. */
.proofshot{margin:18px 0 0}
.proofshot img{width:100%;height:auto;display:block;border-radius:14px;
  box-shadow:var(--shadow)}
.proofshot figcaption{font-size:13.5px;font-weight:600;color:var(--ink-3);
  text-align:center;margin-top:8px}
/* The one honest limit on this page. Sits under the button, where scarcity does
   its work — not in the headline, where it would read as pressure. */
.scarcity{margin-top:16px;font-size:16px;line-height:1.45;color:var(--ink-2);
  max-width:440px;margin-left:auto;margin-right:auto}
.scarcity b{color:var(--ink)}

/* ---- $54.95 (regularly $60.00) — 2026-08-18 ---------------------------------
   The struck anchor moved out of its own row and in beside the price. It must
   NOT inherit `.was{font-size:1.55em}` from the old ladder rule: 1.55em of a
   68px price is ~105px, which would make the crossed-out number the biggest
   thing on the card — the exact opposite of the point.
   Sits on its own line under the price on phones, where the pair will not fit. */
.ladder .now .reg-inline{font-family:var(--sans);font-weight:400;
  font-size:clamp(15px,2.2vw,18px);line-height:1.2;color:var(--ink-3);
  white-space:nowrap;margin-left:8px;vertical-align:middle}
.ladder .now .reg-inline .was{font-size:1em;font-weight:700;
  text-decoration:line-through;text-decoration-color:#d64545;
  text-decoration-thickness:2px;color:var(--ink-3)}
@media (max-width:600px){
  .ladder .now .reg-inline{display:block;margin-left:0;margin-top:4px}
}

/* The guarantee now sits UNDER the button, so it needs air above it rather than
   below — it used to be the last thing before the CTA. */
.offer .cta-wrap + .seal-row{margin:24px 0 6px}

/* .parent-quote became the page's h1 when sales-d's hero was removed (2026-08-18).
   h1 carries its own clamp() size from the base rules; the quote is meant to read
   as a quiet opening line, not a billboard, so hold it at the h2 scale. */
h1.parent-quote{font-size:clamp(25px,4.6vw,34px);letter-spacing:0}

/* The lede h1 on sales-d, sitting above the split rather than inside it.
   Centred and measure-capped so a full-width band does not stretch it into a
   single thin line on desktop. */
/* px, not ch: 1ch at a 40px display face is ~17.6px, so 24ch resolved to 422px
   inside a 760px wrap and broke a 63-character quote across four lines. */
h1.lede-h1{max-width:640px;margin:0 auto 22px;text-align:center;
  font-size:clamp(27px,5.2vw,40px);line-height:1.2;text-wrap:balance}
@media (max-width:600px){ h1.lede-h1{max-width:none;margin-bottom:18px} }

/* ---- Compact Cranston strip (2026-08-19) -----------------------------------
   Sits directly above the early offer box on both sales pages. The FULL Cranston
   block stays where it was, deeper down — this is the headline claim, that is the
   whole story, same repeat-at-depth pattern as the offer box.
   ⚠️ The height budget is a PHONE constraint, not a design preference: 75% of
   traffic is phone, and every pixel here pushes the buy button down and costs
   reach. Desktop has no such squeeze — vertical space is cheap and the column is
   wide — so the base rules below are sized for DESKTOP and the phone override at
   the bottom pins it back to the ~185px it must stay. Change the base freely;
   check the override before touching anything inside it. */

/* Must out-specify `section.tight{padding:28px 0}` (0,1,1) or it silently loses —
   which is exactly what happened on the first build: the intended value never
   applied and it rendered at 28px. Top padding is 0 on purpose; the preceding
   section already contributes 44px of its own, which is the whole gap needed. */
section.cran-band{padding:0 0 26px}
/* GRID, not flex, and on purpose. Jimmy asked for the Cranston photo to line up
   with the line carrying his name, and the Brody photo to end on the last line
   of text. Putting the kicker in row 1 and the photo column + copy in row 2
   makes that alignment STRUCTURAL: row 2 starts at the Cranston line and ends
   at the last line, and space-between pins a photo to each end. No hardcoded
   offsets, so it survives a font-size or breakpoint change. */
.cran-strip{display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:22px;align-items:stretch;max-width:760px;margin:0 auto;
  background:var(--white);border:2px solid var(--line);border-radius:16px;
  padding:18px;box-shadow:var(--shadow)}
.cran-strip > img{flex:none;width:210px;height:auto;border-radius:10px;display:block}
/* sales-e ad-match hero. The Test 4 winning ad image, cropped to drop only the
   baked-in headline. Full-bleed to the wrap so it reads as the ad, not as an
   illustration sitting in a page. Aspect ratio is reserved so it cannot shift
   the headline while it loads. */
/* The hero and the headline sat in adjacent sections, each contributing 28px of
   padding: a measured 58px of dead space between the ad image and the H1.
   Jimmy: "a bit of wasted space below the head image." Collapses to ~8px. */
.ad-hero-band{padding-bottom:0!important}
.ad-hero-band + section{padding-top:6px!important}
.cran-second{margin-top:6px}
.ad-hero{display:block;width:100%;height:auto;aspect-ratio:1080/920;
  border-radius:12px;margin:0 auto 4px}
@media(max-width:640px){ .ad-hero{border-radius:8px;margin-bottom:2px} }
/* Storyline seal, pinned to the photo corner so it adds ZERO page height.
   See the button-reach note in sales-c.html before changing this. */
.cran-strip > .cran-kicker{grid-column:2;grid-row:1;margin:0 0 6px}
/* The strip photos are 4:3 CROPS OF THE FILE (cranston-strip.jpg / brody-strip.jpg),
   not the 16:9 stills. Jimmy wanted them taller; doing that in CSS meant either
   squashing the subject (rejected: "Bryan is too high", "you stretched the box")
   or widening the column, which narrows the copy, which makes the copy TALLER, so
   the gap grew faster than the photos did. Cropping the asset gives the height for
   free: same 112px column, 63px -> 84px tall, no reflow, no button cost.
   The 16:9 originals are untouched and still serve the lightbox at full size.

   ⛔ DO NOT make these photos stretch or crop to fill the row. That was tried
   2026-09-14 (flex:1 1 0 + object-fit:cover) and Jimmy rejected it on sight:
   "Bryan is too high on mobile" and "you stretched the box on desktop."
   Forcing a 16:9 still into a 1.22 box crops the subject badly.
   The photos keep their NATIVE aspect. space-between pins one to the top of
   the Cranston line and one to the bottom of the last line, and the GAP
   absorbs the leftover height. Desktop width is sized so two natural photos
   plus a sane gap fit inside the copy's span. */
/* Desktop: top-align only. The copy runs wider there, so its span is ~144px while
   two 4:3 photos plus a gap are ~182px — forcing bottom alignment would either
   overflow or shrink the photos to ~87px. Mobile is 92% of this traffic and gets
   the exact top-AND-bottom alignment Jimmy asked for, in the media query below. */
.cran-shots{grid-column:1;grid-row:2;width:112px;min-height:0;
  display:flex;flex-direction:column;justify-content:flex-start;gap:14px}
.cran-shot > img:first-child,.cran-shot-b{width:100%;height:auto;
  border-radius:10px;display:block}
.cran-copy{grid-column:2;grid-row:2}
.cran-shot{position:relative;width:100%;display:block}
.cran-seal{position:absolute;right:-12px;bottom:-10px;width:82px;height:auto;
  display:block;filter:drop-shadow(0 2px 7px rgba(0,0,0,.38))}
.cran-copy{flex:1 1 auto;min-width:0}
.cran-copy .kicker{margin-bottom:6px}
.cran-head{font-family:var(--display);font-weight:800;
  font-size:clamp(17px,3.2vw,25px);line-height:1.25;margin-bottom:6px}
.cran-sub{font-size:16px;line-height:1.45;color:var(--ink-2);margin-bottom:0}
@media (max-width:600px){
  /* Stays side-by-side on a phone ON PURPOSE. Stacking would make the image full
     width and roughly double the strip's height — the one thing this block cannot
     afford. These values ARE the height budget; the clamp above already floors the
     headline at 17px on a phone, so only the box metrics need pinning back. */
  section.cran-band{padding:0 0 20px}
  .cran-strip{gap:12px;padding:12px}
  .cran-strip > img{width:112px}
  .cran-strip{column-gap:12px}
  .cran-shots{width:112px;gap:14px;justify-content:space-between}
  .cran-seal{width:54px;right:-8px;bottom:-7px}
  .cran-sub{font-size:14px}
}

/* ---- "Look inside" cover lightbox — sales-d only (2026-08-27) ----------------
   Built on the strongest friction signal on either page: 63 dead taps on the
   book covers in a week, more than double any other element. People were already
   trying to open them; this makes the tap do what they expected.

   ⭐ Deliberately costs ZERO height. Every previous persuasion add pushed the buy
   button down and spent reach (~13 points per 1,000px near the button). The
   spreads live behind a tap, and the affordance is an absolutely-positioned
   badge, so nothing moves. This is the first change that buys persuasion for
   free.
   The markup only exists on sales-d, so these rules are inert on sales-c. */
.covers figure[data-inside]{position:relative;cursor:pointer}
.peek{position:absolute;left:50%;transform:translateX(-50%);bottom:6px;
  background:rgba(24,35,82,.9);color:#fff;font-size:11px;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;padding:5px 10px;border-radius:99px;
  pointer-events:none;white-space:nowrap}
.ilb{position:fixed;inset:0;background:#12162d;z-index:9999;
  overflow-y:auto;-webkit-overflow-scrolling:touch;display:none}
.ilb.open{display:block}
.ilb-in{max-width:820px;margin:0 auto;padding:64px 14px 40px}
.ilb h3{color:#fff;font-family:var(--display);font-size:22px;text-align:center;margin:0 0 4px}
/* ⚠️ Was `.ilb .sub`, which also matched `.cta .sub` — the CTA's price line —
   and painted it pale lavender on a yellow button: near-invisible, and the
   thing Jimmy spotted. `.sub` is a shared utility class, so anything inside
   .ilb must NOT claim it. Own class instead. */
.ilb-sub{color:#c9cee8;font-size:14px;text-align:center;margin:0 0 20px}
.ilb img{width:100%;height:auto;display:block;border-radius:10px;margin:0 0 14px;
  background:#fff}   /* the width/height attrs give the browser the ratio */
.ilb-x{position:fixed;top:10px;right:12px;width:44px;height:44px;border-radius:50%;
  border:0;background:rgba(255,255,255,.16);color:#fff;font-size:26px;line-height:1;
  cursor:pointer;z-index:1}
/* ⚠️ `auto` on the sides is load-bearing. .cta centres itself with margin:0 auto;
   writing the shorthand as `6px 0 0` here zeroed those and left the button
   hanging off the left edge of a much wider image (520px button under a
   792px spread on desktop). */
.ilb-cta{display:block;text-align:center;margin:6px auto 0}
body.ilb-lock{overflow:hidden}

/* The name field read as a gate: a bold label, a big empty input and three
   lines of instruction, all BEFORE the yes/no choice. It has always been
   optional in code — funnel.js allows blank and the Klaviyo flow asks by
   email — but nothing on the page said so. */
.namefield .opt{font-weight:400;font-size:14px;color:var(--ink-3);text-transform:none;letter-spacing:0}

/* Proof lightbox on sales-c. Reuses the .ilb shell from sales-d's interior
   lightbox; only the payload differs. The badge sits at the bottom of the cover,
   except where a figcaption follows — there the image is not the last thing in
   the figure, so the badge moves to the top rather than landing on the caption. */
.covers figure[data-proof]{position:relative;cursor:pointer}
.covers figure[data-proof]:has(figcaption) .peek{top:6px;bottom:auto}
.ilb .pf-hero{display:block;width:100%;height:auto;border-radius:10px;margin:0 0 16px;
  background:#fff}
.ilb .pf-vid{display:block;width:100%;height:auto;border-radius:10px;margin:0 0 16px;
  background:#000}
.ilb-in .pf-lead{color:#fff;font-size:18px;line-height:1.45;margin:0 0 12px}
.ilb-in p{color:#c9cee8;font-size:16px;line-height:1.5;margin:0 0 14px}
.pf-cred{font-size:12px!important;color:#8a93b8!important;margin:-10px 0 16px!important;
  text-align:center}
.pf-q{margin:0 0 18px;padding:14px 16px;border-left:3px solid var(--yellow);
  background:rgba(255,255,255,.05);border-radius:0 8px 8px 0;color:#fff;
  font-size:17px;line-height:1.45}
.pf-q cite{display:block;margin-top:10px;font-style:normal;font-weight:700;
  font-size:14px;color:#c9cee8}
.pf-note{font-size:15px!important}

/* A quote with the speaker's face. Used for Courtney B. Vance, where the title
   is doing the persuading and a face makes it a person rather than a citation.
   Deliberately small: the Brody still at the top of that panel already carries
   the visual weight, and two large faces would compete. */
.ilb .pf-q-face{display:flex;gap:14px;align-items:flex-start}
.ilb .pf-face{flex:0 0 62px;width:62px;height:62px;border-radius:50%;object-fit:cover;
  margin-top:2px;background:#fff}
@media (max-width:420px){
  .ilb .pf-q-face{gap:11px}
  .ilb .pf-face{flex-basis:52px;width:52px;height:52px}
}

/* Ten seals, always two rows of five (Jimmy 2026-10-04: six seals wrapped 5+1, an orphan). A fixed grid instead of
   flex-wrap so no screen width can leave a lone seal. Used on sales-e, krfsales-e, krfsales-a. */
.awards-row.ten{display:grid;grid-template-columns:repeat(5,1fr);justify-items:center;align-items:center;
  gap:clamp(10px,2.4vw,24px);max-width:620px;margin:0 auto}
.awards-row.ten img{width:100%;max-width:98px}
