/* ============================================================
   savethisguide site stylesheet
   Brand: #EFEFEF surfaces, near-black ink, yellow #ffcc62 accents,
   every yellow element carries a hairline outline (matches the PDF
   guides and the cover ribbon). Inter throughout, Anton for display.
   Structure follows Templates/sales-page/SECTION-SPEC.md, derived
   from the proven FMAT /tgth page.
   ============================================================ */

/* ---------- Self-hosted fonts ----------
   Was Google Fonts with display=swap, which measured CLS 0.1536 at 1024px
   against FMAT's 0.0014. The browser painted headings in a fallback sans and
   then swapped in Anton, a very condensed face, so every heading changed width
   and every section below it moved. Self-hosted and preloaded, the faces arrive
   before first paint and there is no swap to see. Built by tools/build_fonts.py
   (1776K of TTF down to 105K of subset woff2). */
@font-face{
  font-family:'Anton';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/anton-400.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:400;font-display:swap;
  src:url('/assets/fonts/inter-400.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:500;font-display:swap;
  src:url('/assets/fonts/inter-500.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:600;font-display:swap;
  src:url('/assets/fonts/inter-600.woff2') format('woff2');
}
@font-face{
  font-family:'Inter';font-style:normal;font-weight:700;font-display:swap;
  src:url('/assets/fonts/inter-700.woff2') format('woff2');
}

:root{
  --ink:#0c0c0e;
  --muted:#5c5c62;
  --surface:#EFEFEF;
  --card:#ffffff;
  --accent:#ffcc62;
  --line:#d8d8d8;
  --hair:#0c0c0e;
  --ok:#1a7f4b;
  --maxw:1080px;
}

*{box-sizing:border-box;}
html{scroll-behavior:auto;}
body{
  margin:0;
  background:var(--surface);
  color:var(--ink);
  font-family:'Inter',system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  font-size:18px;
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block;}
a{color:var(--ink);}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px;}
/* .narrow is retained for the legal pages only. Sales pages use one width
   throughout; long prose is kept readable by a max measure on the paragraph
   rather than by narrowing the section, which moved the section edges. */
.narrow{max-width:760px;}
section > .wrap > p,
section > .wrap > .lede,
section > .wrap > ul.checks{max-width:900px;}

/* ---------- Announcement bar ---------- */
.announce{
  background:var(--ink);color:#fff;text-align:center;
  /* Tight bottom padding: the support line sits directly under this one and the
     two must read as a single band. Loose spacing here cost vertical space above
     the fold for nothing (Gabriel 2026-07-26). */
  padding:8px 16px 2px;font-size:15px;font-weight:600;letter-spacing:.01em;
}
.announce a{color:var(--accent);text-decoration:underline;}

/* ---------- Header / logo ---------- */
.site-head{background:var(--surface);border-bottom:1px solid var(--line);}
.site-head .wrap{display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding-top:14px;padding-bottom:14px;}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;}
.brand svg{width:22px;height:30px;display:block;flex:0 0 auto;}
.brand span{
  font-family:'Anton','Inter',sans-serif;font-weight:400;
  font-size:22px;letter-spacing:.01em;color:var(--ink);line-height:1;
}
.head-links{display:flex;gap:20px;font-size:15px;font-weight:600;}
.head-links a{text-decoration:none;color:var(--muted);}
.head-links a:hover{color:var(--ink);}

/* ---------- Type ---------- */
h1,h2,h3{margin:0 0 14px;line-height:1.15;text-wrap:balance;}
h1{font-family:'Anton','Inter',sans-serif;font-weight:400;
   /* 25% down from clamp(34px,5.4vw,54px) 2026-07-26: the outcome-led H1 runs
      longer than a product name and was eating the hero. */
   font-size:clamp(26px,4.05vw,40px);}
h2{font-family:'Anton','Inter',sans-serif;font-weight:400;font-size:clamp(26px,3.6vw,38px);}
h3{font-size:21px;font-weight:700;}
p{margin:0 0 16px;text-wrap:pretty;}
.lede{font-size:21px;color:#26262b;}
.eyebrow{
  display:inline-block;font-size:12px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted);margin-bottom:10px;
}
.rule{height:6px;width:96px;background:var(--accent);border:1px solid var(--hair);
  border-radius:3px;margin:0 0 22px;}

section{padding:56px 0;}
section.tight{padding:36px 0;}

/* ---------- Strict white / grey alternation ----------
   Was a hand-applied `.alt` class, which drifted every time a section was
   inserted or removed, so the banding looked random (Gabriel 2026-07-26).
   Now positional: the browser counts, nobody maintains it, and inserting a
   section re-bands everything below it automatically.

   First section is WHITE. The colour change is the only separator; the old
   1px borders on .alt are gone because a band edge plus a rule reads as two
   boundaries. */
body > section:nth-of-type(odd){background:var(--card);}
body > section:nth-of-type(even){background:var(--surface);}

/* ---------- Buttons ---------- */
.btn{
  display:inline-block;background:var(--accent);color:var(--ink);
  border:1px solid var(--hair);border-radius:8px;
  padding:15px 26px;font-size:18px;font-weight:700;text-decoration:none;
  cursor:pointer;
}
.btn:hover{filter:brightness(1.04);}
.btn.block{display:block;width:100%;text-align:center;}
.btn.ghost{background:transparent;}
.btn-note{font-size:14px;color:var(--muted);margin-top:10px;}

/* ---------- Stat pills ---------- */
.pills{display:flex;flex-wrap:wrap;gap:12px;margin:22px 0 26px;}
.pill{
  background:var(--card);border:1px solid var(--hair);border-radius:999px;
  padding:8px 18px;font-weight:700;font-size:16px;text-decoration:none;
}

/* ---------- Bento grid ---------- */
.bento{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
.bento.two{grid-template-columns:1fr 1fr;}
.box{
  background:var(--card);border:1px solid var(--hair);border-radius:10px;
  padding:22px 22px;
  /* Equal height with the CTA pinned to the bottom, so buttons line up across
     the row even when the copy lengths differ (QA 2026-07-25). */
  display:flex;flex-direction:column;height:100%;
}
.bento{align-items:stretch;}
.box > .box-cta{margin-top:auto;padding-top:16px;margin-bottom:0;}
.box h3{margin-bottom:8px;}
.box p{margin:0;color:#3a3a40;font-size:17px;}
.box .num{font-family:'Anton','Inter',sans-serif;font-size:34px;line-height:1;
  display:block;margin-bottom:8px;}

/* ---------- Checklist ---------- */
ul.checks{list-style:none;padding:0;margin:0 0 20px;}
ul.checks li{position:relative;padding-left:34px;margin-bottom:12px;}
ul.checks li::before{
  content:"";position:absolute;left:0;top:4px;width:20px;height:20px;
  background:var(--accent);border:1px solid var(--hair);border-radius:5px;
  background-image:url("data:image/svg+xml,%3Csvg class='lucide lucide-check' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%230c0c0e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' %3E %3Cpath d='M20 6 9 17l-5-5' /%3E %3C/svg%3E");
  background-repeat:no-repeat;background-position:center;background-size:14px 14px;
}

/* ---------- Alignment rule ----------
   MEASURED on FMAT 2026-07-26: 52 left-aligned paragraphs against 3 centred, and
   13 left H2s against 6 centred. The exceptions are not arbitrary. Everything
   centred is a SHORT LABEL introducing a full-width symmetric block (the pricing
   header, the reviews header, the FAQ header) or a top bar. Everything the reader
   actually READS is left aligned.

   The reason left wins for prose: centring moves the start of every line, so the
   eye has to re-find the left edge on each return sweep. That cost scales with
   line count, which is why a one-line label is fine and a four-line paragraph is
   not. On a 50+ audience the penalty is larger, not smaller.

   RULE: centre only a focal block of at most two lines that opens or closes a
   symmetric section. Never centre a reading passage. */
.center-block{text-align:center;}
/* A max-width child with no auto margins sits flush left, so its centred text
   looked off-centre against the section. Centre the box as well as the text. */
.center-block > p,
.center-block > .lede,
.center-block > ul.checks{margin-left:auto;margin-right:auto;}
.center-block .rule{margin-left:auto;margin-right:auto;}
.center-block h2:has(> .h-ic){justify-content:center;}
.center-block .cta-block,
.center-block .paycards{margin-left:auto;margin-right:auto;}
/* Reading passages inside a centred section stay left: ladder rows and FAQ
   answers are prose, not labels. */
.center-block .ld,
.center-block .ld-body,
.center-block details{text-align:left;}

/* ---------- Boxes contrast with their band (Gabriel 2026-07-26) ----------
   The stat box is grey and reads well on the white hero, so every box got the
   same treatment: grey on a white section, white on a grey section. A white box
   on a white band has only its hairline to define it, which is what made those
   sections harder to read. Pills follow the same rule.

   Driven off the same nth-of-type alternation as the bands, so it can never fall
   out of sync with them. */
body > section:nth-of-type(odd) .box,
body > section:nth-of-type(odd) .tile,
body > section:nth-of-type(odd) .pill,
body > section:nth-of-type(odd) details{background:var(--surface);}
body > section:nth-of-type(even) .box,
body > section:nth-of-type(even) .tile,
body > section:nth-of-type(even) .pill,
body > section:nth-of-type(even) details{background:var(--card);}

/* ---------- Heading icon chip + numbered box head ----------
   Same yellow-chip-with-ink-hairline device as the six tiles, so the icons read
   as part of the brand rather than decoration. Applied to content sections only:
   the narrative sections keep a bare Anton headline, because an icon on every
   heading stops being navigation and becomes noise.

   .box-head puts the numeral BESIDE the title. It used to sit above, which cost
   a full line of height per box and told the reader nothing extra. */
h2:has(> .h-ic){display:flex;align-items:center;gap:14px;}
.h-ic{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:11px;
  background:var(--accent);border:1px solid var(--hair);
}
.h-ic svg{width:21px;height:21px;stroke:var(--ink);stroke-width:2;}

/* When a heading carries an icon chip, the rule beneath it starts under the TEXT,
   not under the chip: 40px chip + 14px gap (Gabriel 2026-07-26). */
h2:has(> .h-ic) + .rule{margin-left:54px;}
.center-block h2:has(> .h-ic) + .rule{margin-left:auto;}

.box-head{display:flex;align-items:center;gap:12px;margin-bottom:8px;}
.box-head h3{margin:0;}
.box-head .num{margin:0;font-size:30px;line-height:1;}

/* ---------- Hero payoff stat + payment reassurance ----------
   .hero-proof is the THIRD grid child of .hero-split. With .hero-media on
   order:-1, auto-placement puts media r1c1, copy r1c2, proof r2c1, so the stat
   lands under the carousel thumbnails on desktop and last in the stack (under
   the button) once everything is single column. No extra placement rules.

   Every statistic carries a visible source. On a page selling protection from
   deception an unattributed number does more harm than no number. */
.hero-proof{
  background:var(--surface);border:1px solid var(--hair);border-radius:10px;
  padding:15px 17px;margin-top:16px;align-self:start;
}
.hero-proof p{margin:0;font-size:16px;line-height:1.5;}
.hero-proof b{font-weight:700;}
.hero-proof .src{
  display:block;margin-top:8px;font-size:12.5px;line-height:1.4;color:var(--muted);
}
/* Styling deliberately identical to the pricing block: same card width, same
   note weight and colour. Gabriel found the pricing version easier to read, so
   the hero matches it rather than the reverse. The card strip and the two lines
   read as ONE unit, so the gap between them is tight. */
.hero-pay{margin-top:16px;}
.hero-pay img,
.paycards img{max-width:380px;height:auto;margin:0 auto;}
/* Full column width with the strip centred inside, so the block's centre lines up
   with the full-width CTA directly above it. Pinning the block to 380px left the
   two centres 70px apart. */
.hero-pay{max-width:none;}
.hero-pay p,
.pay-note{
  margin:6px 0 0;text-align:center;font-weight:700;font-size:16.5px;
  line-height:1.4;color:#26262b;
}

/* ---------- Fixed bottom CTA, below desktop only ----------
   FMAT carries one on every width under 1280: position fixed, full width, about
   84px tall, z-index very high. We had none, so on a phone the only way to buy
   was to scroll back. Revealed by JS once the hero CTA leaves the viewport, so
   it never sits on top of the button it duplicates. */
.stickybar{
  position:fixed;left:0;right:0;bottom:0;z-index:900;
  background:var(--surface);border-top:1px solid var(--hair);
  padding:10px 16px calc(10px + env(safe-area-inset-bottom));
  transform:translateY(110%);transition:transform .22s ease;
  display:none;
}
.stickybar.on{transform:translateY(0);}
.stickybar .cta-block{max-width:640px;margin:0 auto;padding:12px 20px;}
.stickybar .cta-main{font-size:18px;}
.stickybar .cta-sub{font-size:13px;}

/* ---------- Narrative section with a 1:1 image beside it ----------
   FMAT's villain text is 443px wide and its coverage text 428px, because each
   sits next to an 864x864 square image. I had copied the narrow measure and
   dropped the image, which left the page with no 1:1 art outside the carousel
   AND made the left edge jump while scrolling (Gabriel, 2026-07-26).

   The image side ALTERNATES down the page, which is FMAT's rhythm: `.pair` puts
   the art right, `.pair.flip` puts it left.
   NAME COLLISION, fixed 2026-07-26: this modifier was `.pair.rev`, and `.rev` is
   also the review-card class, so every reversed pair silently inherited the card's
   white background, border and 10px radius and rendered as a panel floating in the
   band. Single-word utility names collide; modifiers are prefixed now. */
.pair{display:grid;grid-template-columns:.85fr 1.15fr;gap:44px;align-items:center;}
.pair .pair-media{order:2;}
.pair.flip .pair-media{order:-1;}
.pair-media .ph{max-width:400px;margin:0 auto;}
.pair-body > :last-child{margin-bottom:0;}

/* ---------- Accepted payment cards ----------
   Card marks, transparent PNG so they sit on any surface. FMAT's own file had a
   cream background baked in, which showed as a cream box on our #EFEFEF. */
.paycards{max-width:380px;margin:18px auto 0;}
.paycards img{width:100%;height:auto;}
.pay-note{text-align:center;font-size:14px;color:var(--muted);margin:10px 0 0;}

/* ---------- Hero benefit checks (FMAT parity) ----------
   FMAT puts three ticked benefit lines between the descriptive paragraph and the
   CTA. They answer the three fastest objections (is it instant, how long does it
   take, can I read it) before the price is seen. */
ul.hchecks{list-style:none;padding:0;margin:20px 0 24px;}
ul.hchecks li{position:relative;padding-left:32px;margin-bottom:10px;font-weight:600;}
ul.hchecks li::before{
  content:"";position:absolute;left:0;top:2px;width:22px;height:22px;
  background:var(--accent);border:1px solid var(--hair);border-radius:6px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%230c0c0e' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:center;background-size:15px 15px;
}

/* ---------- CTA block: price in the button, note inside the yellow ----------
   FMAT's hero CTA carries the price and an arrow, with the reassurance line
   inside the same yellow block rather than floating under it. */
.cta-block{
  display:block;background:var(--accent);border:1px solid var(--hair);
  border-radius:10px;padding:16px 26px;text-decoration:none;text-align:center;
  max-width:520px;
}
.cta-block .cta-main{display:block;font-size:20px;font-weight:700;color:var(--ink);}
.cta-block .cta-sub{display:block;font-size:14px;font-weight:500;color:#3a3a40;margin-top:4px;}
.cta-block:hover{filter:brightness(1.04);}

/* ---------- Accepted payments strip ----------
   Text rather than card logos: honest, no trademarked artwork to source, and it
   reads correctly on the #EFEFEF surface. Swapping in real card marks is an
   image-phase item. */
.paystrip{
  text-align:center;margin:22px auto 0;max-width:640px;
  font-size:14px;font-weight:600;color:var(--muted);line-height:1.7;
}
.paystrip .pay-label{display:block;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;margin-bottom:6px;}

/* ---------- Review wall ----------
   Structure only until real buyers exist. `.rev-empty` is the state that ships:
   the solicitation ask, with no invented reviews. When real reviews arrive they
   drop in as .rev cards and .rev-empty is removed. */
.reviews{max-width:100%;margin:0 auto;}
.rev-ask{
  background:var(--card);border:1px solid var(--hair);border-radius:10px;
  padding:20px 22px;margin-bottom:18px;font-size:16.5px;
}
.rev{
  background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:18px 20px;margin-bottom:12px;
}
.rev-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;flex-wrap:wrap;margin-bottom:6px;}
.rev-who{font-weight:700;}
.rev-when{font-size:14px;color:var(--muted);}
.rev-title{font-weight:700;margin:6px 0 4px;}
.rev p{margin:0;font-size:16.5px;color:#3a3a40;}
.rev-empty{
  background:var(--card);border:1px dashed var(--hair);border-radius:10px;
  padding:22px;text-align:center;color:var(--muted);font-size:16px;
}

/* ---------- Pricing cards ---------- */
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:start;}
.card{
  background:var(--surface);border:1px solid var(--hair);border-radius:12px;
  padding:26px 22px;display:flex;flex-direction:column;height:100%;
}
.card.best{background:var(--accent);}
.card .badge{
  display:inline-block;background:var(--ink);color:var(--accent);
  font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:5px 11px;border-radius:6px;margin-bottom:12px;align-self:flex-start;
}
.card h3{font-family:'Anton','Inter',sans-serif;font-weight:400;font-size:25px;}
.price{font-family:'Anton','Inter',sans-serif;font-size:40px;line-height:1;margin:6px 0 4px;}
.price s{font-family:'Inter',sans-serif;font-size:19px;color:var(--muted);
  font-weight:500;margin-right:10px;}
.card ul{list-style:none;padding:0;margin:14px 0 18px;font-size:16.5px;}
.card ul li{padding-left:20px;position:relative;margin-bottom:9px;}
.card ul li::before{content:"";position:absolute;left:0;top:9px;width:9px;height:9px;
  border-radius:50%;background:var(--ink);}
.card .upsell{font-size:15px;color:#44444a;margin:0 0 16px;}
.card .cta{margin-top:auto;}
.guarantee{text-align:center;font-size:15.5px;color:var(--muted);margin-top:20px;}

/* ---------- FAQ ---------- */
details{background:var(--card);border:1px solid var(--line);border-radius:10px;
  padding:16px 20px;margin-bottom:10px;}
details[open]{border-color:var(--hair);}
summary{cursor:pointer;font-weight:700;font-size:18px;list-style:none;}
summary::-webkit-details-marker{display:none;}
summary::after{
  content:"";float:right;width:20px;height:20px;margin-left:12px;
  background-repeat:no-repeat;background-position:center;background-size:20px 20px;
  background-image:url("data:image/svg+xml,%3Csvg class='lucide lucide-plus' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%235c5c62' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' %3E %3Cpath d='M5 12h14' /%3E %3Cpath d='M12 5v14' /%3E %3C/svg%3E");
}
details[open] summary::after{background-image:url("data:image/svg+xml,%3Csvg class='lucide lucide-minus' xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%235c5c62' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' %3E %3Cpath d='M5 12h14' /%3E %3C/svg%3E");}
details p{margin:12px 0 0;color:#3a3a40;}

/* ---------- Forms ---------- */
.field{margin-bottom:16px;}
label{display:block;font-weight:700;font-size:15px;margin-bottom:6px;}
input[type=email],input[type=text]{
  width:100%;padding:14px 15px;font-size:18px;font-family:inherit;
  border:1px solid var(--hair);border-radius:8px;background:#fff;
}
.msg{padding:14px 16px;border-radius:8px;border:1px solid var(--hair);
  background:var(--card);margin-top:16px;font-size:16.5px;}
.msg.ok{background:#eefaf2;border-color:var(--ok);}

/* ---------- Footer ---------- */
.site-foot{background:var(--ink);color:#c9c9cf;padding:40px 0 46px;font-size:15px;}
.site-foot .brand span{color:#fff;}
.site-foot a{color:#c9c9cf;}
.foot-links{display:flex;flex-wrap:wrap;gap:18px;margin:18px 0 14px;}
.site-foot .fine{color:#8a8a92;font-size:13.5px;}

/* ---------- Image placeholders (1:1) ----------
   Square slots marking where real art goes. FMAT's proven page carries a hero
   product shot, a six tile icon row, and a cover in every pricing card; those
   slots were missing here (Gabriel, 2026-07-25). Swap .ph for an <img> when
   the art exists; the aspect ratio is already correct. */
.ph{
  aspect-ratio:1/1;width:100%;
  background:
    repeating-linear-gradient(45deg,#e4e4e4 0 10px,#ededed 10px 20px);
  border:1px solid var(--hair);border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  text-align:center;padding:14px;
  font-size:13px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:#6a6a72;
}
.ph.sm{max-width:120px;}
.ph.hero{max-width:380px;margin:0 0 26px;}
.hero-split{display:grid;grid-template-columns:1.25fr .75fr;gap:34px;align-items:start;}

/* six tile icon row */
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
.tile{
  background:var(--card);border:1px solid var(--hair);border-radius:10px;
  padding:20px;text-align:center;
}
.tile-ic{
  display:flex;align-items:center;justify-content:center;
  width:54px;height:54px;margin:0 auto 14px;
  background:var(--accent);border:1px solid var(--hair);border-radius:13px;
}
.tile-ic svg{width:26px;height:26px;stroke:var(--ink);stroke-width:2;}
.tile h3{font-size:18px;margin-bottom:6px;}
.tile p{font-size:15.5px;color:#3a3a40;margin:0;}

/* cover slot inside a pricing card */
.card .ph{max-width:150px;margin:0 auto 14px;}

/* ---------- Hero carousel (image LEFT, matching the proven FMAT layout) ----
   Native scroll-snap instead of Swiper: no CDN dependency, no external
   request that can fail, swipeable on touch, arrow + dot controls on desktop. */
.hero-split{
  /* TWO INDEPENDENT COLUMNS, not a 2x2 grid. A shared-row grid cannot start row 2
     until the TALLER column ends, which left a 102px gap between the thumbnails
     and the stat box (Gabriel 2026-07-26). Each column is its own block flow, so
     the stat sits directly under the thumbnails and the cards directly under the
     button, whatever the two column heights are.

     On tablet and mobile both wrappers become display:contents, which promotes
     the four inner blocks to grid items so they can be reordered into
     image, copy, stat, cards. */
  grid-template-columns:.9fr 1.1fr;
  column-gap:34px;align-items:start;
}
/* Image column sits LEFT, matching the FMAT sales page (Gabriel 2026-07-25).
   order:-1 must be global, not only inside the mobile query. */
.hero-media{position:relative;}
.carousel{
  display:flex;overflow-x:auto;scroll-snap-type:x mandatory;
  gap:0;border:1px solid var(--hair);border-radius:12px;background:#e9e9e9;
  scrollbar-width:none;-ms-overflow-style:none;
}
.carousel::-webkit-scrollbar{display:none;}
.carousel > *{flex:0 0 100%;scroll-snap-align:center;}
.carousel .ph{border:0;border-radius:0;}
/* Thumbnail strip + progress bar, matching FMAT's hero. Replaced bare dots
   2026-07-26: dots tell you how many slides exist, thumbnails tell you what is
   ON them, which is the job on a page selling a document. Thumbs are generated
   in JS from the slides, so this works with .ph placeholders and with real
   <img> without any change. */
.car-thumbs{
  display:flex;gap:8px;margin-top:12px;overflow-x:auto;
  scrollbar-width:none;-ms-overflow-style:none;padding-bottom:2px;
}
.car-thumbs::-webkit-scrollbar{display:none;}
.car-thumbs button{
  flex:0 0 auto;width:74px;height:74px;padding:0;cursor:pointer;
  border:1px solid var(--line);border-radius:7px;overflow:hidden;
  background:repeating-linear-gradient(45deg,#e4e4e4 0 8px,#ededed 8px 16px);
  display:flex;align-items:center;justify-content:center;
  opacity:.62;transition:opacity .15s,border-color .15s;
}
.car-thumbs button:hover{opacity:.85;}
.car-thumbs button[aria-current="true"]{
  opacity:1;border-color:var(--hair);box-shadow:0 0 0 2px var(--accent);
}
.car-thumbs img{width:100%;height:100%;object-fit:cover;display:block;}
.car-thumb-label{
  font-size:9px;font-weight:700;line-height:1.25;letter-spacing:.04em;
  text-transform:uppercase;color:#6a6a72;padding:5px;text-align:center;
}
.car-prog{
  height:3px;background:#d5d5da;border-radius:2px;margin-top:10px;overflow:hidden;
}
.car-prog span{
  display:block;height:100%;background:var(--ink);border-radius:2px;
  transition:transform .2s ease;
}
/* The arrows must centre on the IMAGE. They used to be absolute inside
   .hero-media, which also contains the thumbnail strip and the progress bar, so
   top:50% landed below the carousel and they sat low (Gabriel 2026-07-26).
   .car-frame wraps only the arrows and the carousel, so 50% is the image centre. */
.car-frame{position:relative;}
.car-arrow{
  position:absolute;top:50%;transform:translateY(-50%);
  width:38px;height:38px;border-radius:50%;cursor:pointer;
  background:var(--card);border:1px solid var(--hair);
  display:flex;align-items:center;justify-content:center;
  color:var(--ink);padding:0;
}
.car-arrow svg{width:20px;height:20px;pointer-events:none;}
.car-arrow.prev{left:-14px;}
.car-arrow.next{right:-14px;}
@media (max-width:770px){
  .hero-split{grid-template-columns:1fr;}
  .hero-media{order:-1;max-width:340px;margin:0 auto;}
  .car-arrow{display:none;}
}

/* ---------- Pricing ladder (FMAT proven layout) ----------
   Horizontal rows, cover left, title+price on one line, a flowing
   description with bold highlights, full width CTA. Stacks at 820px.
   Replaces the 3-up vertical card grid (Gabriel, 2026-07-25). */
/* Full width: the ladder used to be 900px inside a 1040px container, so its
   edges did not line up with any other section (Gabriel, 2026-07-26). */
.ladder{max-width:100%;margin:0 auto;}
.ld-rows{display:flex;flex-direction:column;gap:18px;}
.ld{
  display:flex;align-items:center;gap:26px;
  background:var(--card);border:1px solid var(--hair);border-radius:12px;
  padding:24px 26px;
}
.ld.best{background:var(--accent);}
.ld-img{flex:0 0 190px;}
.ld-img .ph{border-radius:8px;}
.ld-body{flex:1;min-width:0;}
.ld-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap;}
.ld-head h3{
  font-family:'Anton','Inter',sans-serif;font-weight:400;font-size:26px;margin:0;
}
.ld-price{font-family:'Anton','Inter',sans-serif;font-size:32px;line-height:1;white-space:nowrap;}
.ld-price s{font-family:'Inter',sans-serif;font-size:17px;color:var(--muted);font-weight:500;margin-right:9px;}
.ld-badge{
  display:inline-block;background:var(--ink);color:var(--accent);
  font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  padding:4px 10px;border-radius:6px;margin-bottom:8px;
}
.ld-desc{font-size:16.5px;line-height:1.55;margin:10px 0 16px;color:#26262b;}
.ld-desc b{font-weight:700;color:var(--ink);}
.ld .cta{
  display:block;width:100%;text-align:center;cursor:pointer;
  font-family:inherit;font-size:17.5px;font-weight:700;
  background:transparent;color:var(--ink);
  border:1px solid var(--hair);border-radius:10px;padding:14px 26px;
  transition:filter .15s,transform .05s;
}
.ld.best .cta{background:var(--ink);color:var(--accent);}
.ld .cta:hover{filter:brightness(1.06);}
.ld .cta:active{transform:translateY(1px);}
.ld-note{text-align:center;font-weight:700;font-size:16.5px;margin:6px 0 0;color:#26262b;}
/* Sourcing line under the six tiles. Its own class on purpose: it used to reuse
   .ld-note, and the payment strip's anchor matched that one first and landed up
   beside the tiles instead of under the ladder (2026-07-26). */
.tiles-note{text-align:center;font-size:15.5px;margin:22px 0 0;color:var(--muted);}

@media (max-width:820px){
  .ld{flex-direction:column;align-items:stretch;gap:16px;padding:22px 20px;}
  .ld-head{justify-content:flex-start;}
  .ld-price{font-size:28px;}
}

/* Support strip under the offer bar on sales pages. Sales pages carry no nav
   header at all: cold traffic gets no exit links above the fold, and the space
   goes to the offer instead (Gabriel 2026-07-25, matching FMAT). */
/* Support strip stays INSIDE the dark bar, matching FMAT: the offer line and the
   support line read as one band rather than two competing strips. Corrected
   2026-07-26 during the FMAT parity audit. */
.announce.sub{
  background:var(--ink);color:#fff;
  /* No border: the offer line and the support line are ONE band, not two
     stacked bars with a rule between them (Gabriel, 2026-07-26). */
  font-weight:600;font-size:14px;padding-top:0;padding-bottom:8px;line-height:1.35;
}
.announce.sub a{color:#fff;text-decoration:underline;}
section:first-of-type{padding-top:40px;}

/* ============================================================
   RESPONSIVE, MOVED TO THE END OF THE FILE 2026-07-26.

   It used to sit in the middle, which meant every base rule declared BELOW it
   (.tiles, .ph, .hero-split, the carousel, the ladder) beat its own breakpoints
   on source order at equal specificity. The breakpoints simply did not apply.
   It stayed hidden while the six tiles held small Lucide chips that fitted three
   across even at 480px; swapping in 1:1 image slots made the same three columns
   overflow the viewport and exposed it.

   Anything that needs a breakpoint must be declared ABOVE this block.
   ============================================================ */
/* ---------- Responsive ----------
   Breakpoints mirror the proven FMAT page: 1279px (tablet ceiling),
   770px (mobile), 480px (small phone). A single breakpoint collapsed
   3 columns straight to 1 and left tablet unhandled (QA 2026-07-25). */

/* Tablet: 770 to 1279. Three-up becomes two-up; hero stacks but stays wide. */
@media (max-width:1279px){
  /* ONE LAYOUT FROM HERE DOWN. Measured on FMAT 2026-07-26: at 1024, 820, 768
     and 430 it puts every multi-column row into a single column, stacks the
     hero with the copy under the image, and shows the fixed bottom CTA. Tablet
     is not a separate design; it is the mobile design at a larger scale.
     This also removes the orphan third card that the earlier
     three-up-at-tablet workaround existed to hide. */
  .wrap{max-width:760px;}
  .bento,.bento.two,.cards{grid-template-columns:1fr;}
  /* Tiles are the ONE exception to single-column below 1280: they are an icon
     plus two short lines, so 2-up halves the scroll without crowding
     (Gabriel 2026-07-26). */
  .tiles{grid-template-columns:1fr 1fr;gap:12px;}
  .tile{padding:16px 12px;}
  .tile .ph{max-width:150px;}
  .tile h3{font-size:16px;}
  .tile p{font-size:14px;}
  /* Reset the explicit 2x2 and order the four blocks:
     image, copy + CTA, payoff stat, cards + reassurance. */
  .hero-split{grid-template-columns:1fr;gap:22px;}
  /* Dissolve the column wrappers so their children become grid items and can be
     ordered independently: image, copy + CTA, payoff stat, cards. */
  .hero-left,.hero-right{display:contents;}
  .hero-media{order:-1;max-width:520px;margin:0 auto;width:100%;}
  .hero-copy{order:0;}
  /* Stat and cards sit the SAME distance below the button, so the button, the
     stat and the cards read as one bento group rather than three strays. The
     grid gap supplies the spacing, so both margins are zero. */
  .hero-proof{order:1;margin-top:0;}
  .hero-pay{order:2;margin-top:0;max-width:none;}
  .hero-split{row-gap:14px;}
  .hero-pay img{max-width:340px;}
  .pair{grid-template-columns:1fr;gap:24px;}
  .pair .pair-media,.pair.flip .pair-media{order:-1;}
  .pair-media .ph{max-width:420px;}
  .ld{flex-direction:column;align-items:stretch;gap:18px;}
  .ld-head{justify-content:flex-start;}
  .tile .ph{max-width:320px;margin:0 auto 12px;}
  .box{padding:22px 20px;}
  .stickybar{display:block;}
  /* The room reserved for the fixed bar is set in JS from the bar's measured
     height, and only while it is actually visible. A static reserve left 104px of
     empty space under the footer once the bar learned to hide near the bottom
     (round 11). The footer must be the last thing on the page. */
  /* The hero CTA is full width here, so the sticky bar reads as the same button. */
  .hero-split .cta-block{max-width:none;}
  .hero-pay{max-width:none;}
  .h-ic{width:34px;height:34px;border-radius:9px;}
  .h-ic svg{width:18px;height:18px;}
  h2:has(> .h-ic){gap:11px;}
}

/* 770 and below: TYPE AND SPACING ONLY. Column counts are already single
   from 1279 down, so nothing here may change a grid. Touch targets go full
   width and the carousel arrows give way to swipe plus the thumbnail strip. */
@media (max-width:770px){
  body{font-size:17px;}
  section{padding:40px 0;}
  .wrap{padding:0 18px;}
  .head-links{display:none;}
  .pair-media .ph{max-width:300px;}
  .hero-media{max-width:360px;}
  .card .ph{max-width:120px;}
  h1{font-size:clamp(23px,6vw,30px);}
  .lede{font-size:19px;}
  .btn{display:block;width:100%;text-align:center;}
  .cta-block{max-width:none;}
  .cta-block .cta-main{font-size:18px;}
  ul.hchecks li{font-size:16px;}
  .rev-head{gap:4px;}
  .pills{gap:9px;}
  .pill{font-size:15px;padding:7px 15px;}
  .foot-links{gap:12px;flex-direction:column;}
}

/* Small phone: up to 480. Tiles single column, tighter type. */
@media (max-width:480px){
  .stickybar{padding:8px 12px calc(8px + env(safe-area-inset-bottom));}
  .stickybar .cta-main{font-size:16px;}
  .stickybar .cta-sub{font-size:12px;}
  .pair-media .ph{max-width:300px;}
  .tile .ph{max-width:130px;}
  body{font-size:16.5px;}
  section{padding:32px 0;}
  .brand span{font-size:19px;}
  .announce{font-size:13.5px;padding:9px 12px;}
  .price{font-size:34px;}
  .ph.hero{max-width:210px;}
}

/* ---------- ONE PARAGRAPH SIZE (Gabriel, 2026-07-26 round 9) ----------
   The page carried eight paragraph sizes (21 / 18 / 17 / 16.5 / 16 / 15.5px plus
   the footer's 13.5px). Mixed body sizes do not read as hierarchy, they read as
   some paragraphs being harder work than others, which on a 50+ audience is a
   real cost for no gain.

   Every reading paragraph now INHERITS the body size, so there is one size on
   desktop and the responsive body steps carry all of them down together. Headings
   (h1, h2, h3), the eyebrow, the tiny carousel thumb labels and the footer legal
   block keep their own sizes: those are not reading paragraphs.

   Appended last on purpose. Same specificity as the rules above, so source order
   decides, and every original declaration stays visible as history. */
.lede,
.box p,
.tile p,
.tiles-note,
.hero-proof p,
.hero-pay p,
.pay-note,
.ld-desc,
.ld-note,
.rev p,
.rev-empty,
.rev-ask,
.guarantee,
.card ul,
details p,
summary{font-size:inherit;}
/* The closer is centred as a BLOCK, not just centred text: capped at 900px with
   no auto margins it sat 70px left of the tile row above it. */
.tiles-note{margin-left:auto;margin-right:auto;}
/* One border language. The FAQ row was the only container on the page not
   carrying the ink hairline, and it swapped TO the hairline when opened, so the
   branding changed as you used it. State is said with the accent, never by
   weakening the hairline. */
details{border-color:var(--hair);}
.car-thumbs button{border-color:var(--hair);}

/* ---------- LADDER ART, MEASURED OFF LIVE FMAT (round 10, 2026-07-26) ----------
   findmeatrip.com/tgth in a real browser: 220x220 at 1440 and 1279, 270x270 at
   770 and 480, identical on all three rows at every width.

   Ours was 190px on desktop and, below 1280, THREE DIFFERENT SIZES (127 / 115 /
   107px) because `.ld-img{flex:none;max-width:230px}` leaves a flex item with no
   basis, so each box collapsed to the width of its own placeholder text. A
   max-width cannot hold a size open. Width can. */
.ld-img{flex:0 0 220px;width:220px;max-width:220px;aspect-ratio:1/1;}
@media (max-width:820px){
  .ld-img{flex:none;width:270px;max-width:270px;margin:0 auto;}
}
/* The sticky bar carries the button only. Its reassurance line repeated the one
   inside the hero CTA and cost a line of height on a fixed bar. */
.stickybar .cta-sub{display:none;}

/* ---------- LADDER STAYS SIDE BY SIDE AT EVERY WIDTH (round 12, 2026-07-26) ----
   Gabriel: image left, content right, on tablet and mobile exactly as on desktop.
   This DIVERGES from FMAT, which stacks below 820 (measured: flex-direction column,
   270x270 centred). Deliberate, so do not "restore parity" over it.

   The image steps down as the row narrows, because side by side means the cover and
   the text share one line and a 270px cover leaves no text column on a phone. The
   text column is what is being protected here, not the cover. */
.ld{flex-direction:row;align-items:center;}
@media (max-width:1279px){
  .ld{flex-direction:row;align-items:center;gap:20px;}
  .ld-img{flex:0 0 220px;width:220px;max-width:220px;margin:0;}
}
@media (max-width:820px){
  .ld{flex-direction:row;align-items:center;gap:18px;padding:20px 18px;}
  .ld-img{flex:0 0 200px;width:200px;max-width:200px;margin:0;}
}
@media (max-width:600px){
  .ld{gap:14px;padding:18px 16px;}
  .ld-img{flex:0 0 150px;width:150px;max-width:150px;}
}
@media (max-width:400px){
  .ld{gap:12px;padding:16px 14px;}
  .ld-img{flex:0 0 128px;width:128px;max-width:128px;}
}

/* ---------- HERO STAT READS AS A FACT BOX (round 13, 2026-07-26) -------------
   Gabriel asked for an icon marking the line as data, and for the box to look
   official. Form does the work; no seal, no badge, no "verified", because this
   brand cannot invent authority it does not hold. The named source underneath is
   the credibility, so it is ruled off and set as a citation instead of a caption. */
/* The chip FLOATS. Making the paragraph a flexbox turned every text node and <b>
   into a flex item, so the sentence rendered as three ragged columns. A float
   keeps the sentence one normal paragraph and still opens it with the mark. */
.hero-proof p{margin:0;}
.proof-ic{
  float:left;width:34px;height:34px;margin:3px 12px 2px 0;
  background:var(--accent);border:1px solid var(--hair);border-radius:9px;
  display:flex;align-items:center;justify-content:center;
}
.proof-ic svg{width:18px;height:18px;stroke:var(--ink);}
.hero-proof .src{
  display:block;margin-top:12px;padding-top:10px;
  border-top:1px solid var(--hair);
  font-size:12.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);
}
@media (max-width:480px){
  .proof-ic{flex:0 0 30px;width:30px;height:30px;border-radius:8px;}
  .proof-ic svg{width:16px;height:16px;}
}

/* ---------- HERO STAT: THINNER, MARK INSIDE THE SENTENCE (round 15, 2026-07-26) --
   Supersedes the round 13 chip. A 34px yellow chip beside a sentence reads as a UI
   component; the glyph alone, inline and in ink, reads as part of the sentence.
   The box also lost ~20px of height without losing a word of copy. */
.hero-proof{padding:12px 14px;}
.hero-proof p{line-height:1.45;}
.proof-ic{
  float:none;display:inline;width:auto;height:auto;margin:0 7px 0 0;
  background:none;border:0;border-radius:0;
}
.proof-ic svg{
  width:19px;height:19px;stroke:var(--ink);
  display:inline-block;vertical-align:-3px;
}
.hero-proof .src{margin-top:8px;padding-top:8px;}
@media (max-width:480px){
  .proof-ic svg{width:18px;height:18px;vertical-align:-3px;}
}

/* round20 */
/* Light yellow. NOT a new colour: #fff6e0 is --accent-soft in the guide PDF
   stylesheet, where it already fills callout boxes and worksheet cells. Reusing
   it keeps the pages and the guides one brand instead of two. */
:root{ --accent-soft:#fff6e0; }

/* Highlight box. Long prose gets scanned, not read, so the one or two lines
   that actually sell inside a long section get lifted out of the flow. Same
   hairline as every other bordered container: the fill changes, the border
   language does not. The badge is the ink pill, which is the brand's "this is
   a label" element, and it is the ONLY inverted thing in the box so it cannot
   be mistaken for a button. */
.hl{
  background:var(--accent-soft); border:1px solid var(--hair); border-radius:12px;
  padding:20px 22px 18px; margin:22px 0 6px; position:relative;
}
.hl p{margin:0;}
.hl p + p{margin-top:10px;}
.hl-badge{
  position:absolute; top:-12px; left:22px;
  background:var(--ink); color:var(--accent); border:1px solid var(--hair);
  border-radius:999px; padding:3px 13px; font-size:13px; font-weight:700;
  letter-spacing:.02em; white-space:nowrap;
}
@media (max-width:480px){ .hl{padding:22px 16px 16px;} .hl-badge{left:16px;} }

/* Get It All row. It was full --accent with an INK button, and the ink badge
   sat two inches away in the same ink-on-yellow treatment, so the badge and the
   button read as the same component. Light fill, and the CTA goes back to the
   site's one button language: accent fill, ink hairline, ink text. The button
   is then the only saturated element in the box. */
.ld.best{background:var(--accent-soft);}
.ld.best .cta{background:var(--accent); color:var(--ink); border:1px solid var(--hair);}

/* round21 */
summary{display:flex; align-items:center; justify-content:space-between; gap:12px;}
summary::after{float:none; margin-left:0; flex:0 0 20px;}

/* round28 */

/* 1. Half the space between the announce bar and the hero. The rendered value
      was a flat 40px at every width (section:first-of-type, line 622), not the
      56/40/32 the base rhythm suggests, so 50% is one rule at 20px. */
.announce.sub + section{padding-top:20px;}

/* 2. Below 1280 the carousel shares the H1's column, so both have one left edge.
      Overrides the 520px tablet cap and the 360px mobile cap above. */
@media (max-width:1279px){
  .hero-media{max-width:none;width:100%;margin:0;}
  /* 3b. Full-bleed means the arrows can no longer hang outside the frame:
         at -14px they leave the wrap and break the no-overflow check. */
  .car-arrow.prev{left:10px;}
  .car-arrow.next{right:10px;}
}

@media (max-width:770px){
  /* 3. The arrows stay on mobile, where the carousel has no other affordance. */
  .car-arrow{display:flex;}
}

/* 4. Accent fill so the carousel reads as browsable. Hairline unchanged, so the
      one-border-language rule holds and only the fill moves. */
.car-arrow{background:var(--accent);}

/* round29 */

/* The hero pills read as one separated line instead of three chips.
   The two band-alternation selectors must be repeated, because they set the
   pill background at a higher specificity than a bare .pill rule can beat. */
.pills{align-items:baseline;}
.pill{border:0;border-radius:0;padding:0;}
body > section:nth-of-type(odd) .pill,
body > section:nth-of-type(even) .pill{background:none;}

/* Separator is the inherited ink at low opacity, never a new colour. */
.pill:not(:last-child)::after{
  content:"|";margin-left:12px;font-weight:400;opacity:.4;
}

/* round30 */

/* The USP line is prose now, so it takes the body's size at every step instead
   of the chip's 16/15. One declaration, all three responsive steps. */
.pill{font-size:inherit;}

/* 10/20 rather than a symmetric halve: the USPs support the H1, so they sit
   closer to it than to the paragraph. Equal space would say they belong to
   neither, which is what made them read as adrift. */
.pills{margin:10px 0 20px;}

/* round31 */

/* The USP line is a SPEC STRIP: bounded below so the headline group has a floor
   and the line reads as metadata, not as a short paragraph. The rule is below
   only; above it would cut the USPs off from the H1 they support. 10/10 keeps
   the total gap to the lede at the 20px round 30 set. */
.pills{
  border-bottom:1px solid var(--hair);
  padding-bottom:10px;
  margin-bottom:10px;
}

/* A real hairline instead of the | glyph, which sits off optical centre and
   takes its weight from the font rather than from the design system. */
.pill:not(:last-child)::after{
  content:"";display:inline-block;
  width:1px;height:14px;background:var(--hair);
  margin-left:12px;vertical-align:-2px;opacity:1;
}

/* Digits stop the wandering eye (copy doctrine Rule 1), so the leading token
   carries the accent. A gradient, NOT a border-bottom: an accent-coloured
   border would be a second border language. */
.pill-k{
  background:linear-gradient(var(--accent),var(--accent)) 0 92%/100% 3px no-repeat;
}

/* round32 */

/* The carousel progress track was #d5d5da, a grey used exactly once in this
   stylesheet and belonging to no part of the palette. Same defect class as the
   FAQ row's #d8d8d8 that round 9 removed; it survived because brand_audit
   inspects borders and this is a background. Height stays 3px: it is a state
   indicator, not a divider, and 1px would make it unreadable. */
.car-prog{background:rgba(12,12,14,.15);}

/* The leading token of each USP takes the HEADLINE's face, so the strip reads as
   part of the H1 without asking anyone to read a condensed display face at body
   size. font-weight:400 is mandatory: only anton-400.woff2 exists and .pill sets
   700, so anything else synthesises fake bold on a condensed face. */
.pill-k{
  font-family:'Anton','Inter',sans-serif;
  font-weight:400;
  font-size:1.12em;
  letter-spacing:.01em;
  background-position:0 calc(100% - 1px);
}

/* round33 */

/* The leading-token decoration is retired: one font, one size, no accent
   underline. The strip's identity comes from its floor and its separators,
   which is what actually fixed the floating; the Anton token and the yellow
   underline were a fourth and fifth signal on a line that already had three.
   This reset must stay even though the <b class="pill-k"> wrapper is gone,
   because rounds 31 and 32 write those rules from their own CSS_BLOCK strings
   and would reinstate them if either is ever re-run. Round 33 runs last. */
.pill-k{
  font-family:inherit;
  font-weight:inherit;
  font-size:inherit;
  letter-spacing:inherit;
  background:none;
}

/* ===== round 36: Gabriel's 14-point copy review (2026-07-28) =====

   1. The offer bar's link loses its underline. It is already var(--accent) on
      ink, which is affordance enough on its own.

      THE SUPPORT LINE'S EMAIL LINK KEEPS ITS UNDERLINE, deliberately. It is
      #fff on ink, identical to the text beside it, so the underline is its
      ONLY affordance; removing it leaves a mailto nobody can see. `.announce
      .sub a` is 0,2,1 against this rule's 0,1,1, so it wins on specificity
      regardless of source order. (The specificity trap, four times now.)

   7. The trademark mark, first mention only. Sized in `em` so it tracks the
      H1's clamp instead of fighting it, and `line-height:0` keeps it from
      opening the H1's line box, which would have been geometry drift during a
      copy round.
*/
.announce a{text-decoration:none;}
.tm{font-size:.42em;vertical-align:super;line-height:0;letter-spacing:.02em;}

/* ===== round 38: the 22-point review (2026-07-28) =====

   1. The trademark mark was too small and sat too high. Gabriel asked for it
      to be more prominent and to sit further from the top of the letters.
      `position:relative` + `top` rather than `vertical-align:super`, because
      super is a fixed offset the browser picks and cannot be tuned; this can.
      `line-height:0` still keeps it out of the line box, which is what stops a
      glyph added to four H1s from registering as geometry drift.

   N746. The home page product row carries FOUR products now. `.bento` is a
      hard 3-column grid, and a 4th item orphans alone on row two, which is the
      exact defect that made `.bento.two` exist. 2x2 is the only layout that
      does not orphan, and it has to be repeated inside the 770 breakpoint
      because `.bento.four` (0,2,0) outranks the `.bento` collapse (0,1,0)
      there. Specificity beats source order, fifth time in this project.
*/
.tm{font-size:.5em;position:relative;top:-.55em;margin-left:.06em;line-height:0;
    font-weight:inherit;letter-spacing:.02em;}
.bento.four{grid-template-columns:repeat(2,1fr);}
@media (max-width:770px){ .bento.four{grid-template-columns:1fr;} }

/* ===== round 39: the home page joins the doctrine (2026-07-28) =====

   ONE PARAGRAPH SIZE, finally reaching the home page. Round 9 put every
   reading paragraph on `font-size:inherit` and built its list by auditing the
   SALES pages, so `.hero-pay p` and `.pay-note` are in it and `.btn-note`,
   which is the home page's version of the same reassurance line under the same
   kind of button, was never added. It has rendered at 14px against the page's
   18px ever since, and no gate could see it because `brand_audit` only ever
   loaded the four sales pages.

   Round 9's own test decides it: what the element IS, not what it is called.
   A reassurance line in the reading column is a reading paragraph.
*/
.btn-note{font-size:inherit;}

/* ===== round 40: length, the mark, and the price stack (2026-07-28) =====

   THE TRADEMARK MARK IS NOW A FIXED SIZE. It was `.5em`, and `em` resolves
   against the PARENT, so the same mark rendered 20px inside a 40px H1 and 9px
   inside 18px body copy. Gabriel: "sometimes the tm is too small, make sure it
   is the same size everywhere and in all devices." A fixed 12px is identical in
   every context, and `top` in `em` now resolves against the mark's OWN size, so
   the raise is consistent too. It does not scale with the responsive body
   steps, which is the point.

   THE LADDER PRICE MOVES TO ITS OWN LINE. `.ld-head` was a flex ROW with the
   tier name and the price sharing a baseline. This is a deliberate design
   change, asked for directly, and it is the first geometry unlock since round
   28: `design_baseline` must be re-captured after it, never before.
*/
.tm{font-size:12px;position:relative;top:-.55em;margin-left:.06em;line-height:0;
    font-weight:inherit;letter-spacing:.02em;}
.ld-head{display:block;}
.ld-head h3{margin-bottom:4px;}
/* inline-block, not the block default: a block price fills the whole 1040px
   row, which makes its measured width meaningless to `design_baseline` and
   gives the element a hit area it has no use for. */
.ld-head .ld-price{display:inline-block;}

/* THE PILL STRIP WRAPPED ON EVERY PHONE, AND THE COPY WAS ONLY HALF THE CAUSE.
   Shortening "Instant PDF download" to "Instant PDF" bought back 414 and 430,
   and 393 down still wrapped, because each boundary spends `gap:12px` PLUS the
   separator's own `margin-left:12px` = ~24px, twice, on a 353px column. The
   text was never the whole problem: **measure the spacing before blaming the
   words.** Tightened below 480 only, so the desktop rhythm is untouched. */
@media (max-width:480px){
  .pills{gap:7px;}
  .pill:not(:last-child)::after{margin-left:7px;}
}

/* ===== round 41: the support email loses its underline (2026-07-28) =====

   Round 36 kept this one underlined because it is #fff on ink and the underline
   was its only affordance. Gabriel asked for it removed, and the original
   argument does not survive scrutiny: an email ADDRESS is self-identifying
   content, unlike link text that merely describes a destination.

   Deliberately NOT re-coloured to var(--accent) to win back an affordance. The
   accent on the offer bar directly above is the OFFER, and its power is that
   nothing else in that band uses it. A $0 support link in the same colour as
   the money link, two lines apart, spends that for nothing.

   Same specificity as the base rule (0,2,1), so this wins on SOURCE ORDER and
   must stay in a block appended after it.
*/
.announce.sub a{text-decoration:none;}

/* ===== round 43: the ladder CTA stops wrapping on phones (2026-07-29) =====

   MEASURED FIRST, AND THE LABEL WAS NOT THE WHOLE CAUSE. The button box is only
   246px at 480 and **169px at 375**, because the ladder stays image-left /
   content-right at every width (the round-11 amendment, deliberate). In a 169px
   column even "Get It All Now" wrapped to two lines. So this is a COLUMN
   problem wearing a label problem's clothes.

   `white-space:nowrap` was the first attempt and it is exactly wrong: it forces
   the button to its natural text width, which is wider than the column, so the
   whole page overflowed (docW 377 against a 375 viewport). **A nowrap inside a
   too-narrow column does not fix wrapping, it converts it into overflow.**

   Shipped instead: shorter labels (the article "the" earns nothing here) plus a
   size and padding step below 480. No nowrap, so the button can never widen the
   page. */
@media (max-width:480px){
  .ld .cta{font-size:15px;padding-left:8px;padding-right:8px;letter-spacing:0;}
}
/* The ladder art holds 128px below 400, which leaves the text column ~169px at
   375. One more step is needed there, and it is a step rather than a floor
   because 360 and below still overflow for a different reason (N751). */
@media (max-width:400px){
  .ld .cta{font-size:13.5px;padding-left:6px;padding-right:6px;}
}

/* ===== round 44: a wrapped spec strip is still ONE strip (2026-07-29) =====

   `.pills` carried a single `gap:12px`, which applies to BOTH axes, so a
   wrapped second line sat exactly as far from line 1 as the pills sit from
   each other. Two rows then read as two separate things.

   Splitting the axes is the fix, and it is round 30's lesson turned 90
   degrees: space is how a page says which things belong together. Row gap is
   half the column gap, so a wrap reads as a fold in one strip rather than a
   new block. Copy length is a losing battle against every phone width that
   exists, so the strip has to survive wrapping, not just avoid it. */
.pills{column-gap:12px;row-gap:6px;}
/* Halving the row-gap alone barely moves the rows, because the visible
   distance between them is dominated by LINE-HEIGHT, not by the gap: 26px of
   leading against a 7px gap. Both have to come down for two rows to read as
   one folded strip. Measure the row-to-row distance, not the gap value. */
@media (max-width:480px){
  .pills{column-gap:7px;row-gap:2px;line-height:1.25;}
}

/* ===== round 53 ===== */
/* 1. The login link was display:none below 700. A buyer on a phone who wants
   back into what they paid for had no way in from the home page, which is the
   page they land on when they type the domain from memory. Visible at every
   width; the gap and size step down so it does not crowd the brand. */
@media (max-width:700px){
  .head-links{display:flex;gap:14px;font-size:14px;}
}
@media (max-width:400px){
  .head-links{gap:10px;font-size:13px;}
}

/* 2. Home hero art slot. `.pair.flip` already puts media left and stacks it
   above the copy below 1280, which is the behaviour we want on a phone: the
   picture sells the scroll. Capped so a 1:1 does not tower over the H1. */
.home-hero .pair-media .ph{max-width:340px;}
@media (max-width:1279px){
  .home-hero .pair-media .ph{max-width:300px;}
}

/* ===== round 56: N751, the sub-375 overflow (2026-07-30) =====

   Below 375 the pages overflowed to a 371px floor (index: 364). The floor is
   the grid's automatic minimum, not any literal width: `1fr` is minmax(auto,1fr)
   and min-width:auto keeps items at min-content, so the hero track floored at
   353px (carousel chain + the pay img's 340px cap), the 2-up tiles floored at
   320 on long words, and two nowrap rows (.ld-price, index's header) did the
   rest. minmax(0,1fr) removes a track's floor, min-width:0 an item's.

   ONE narrow media query on purpose: 480 / 770 / 1279 / 1440 are captured,
   locked geometry and this block cannot apply at any of them. All selectors
   are bare classes beating their base rules on source order from the tail. */
@media (max-width:375px){
  .hero-split{grid-template-columns:minmax(0,1fr);}
  .hero-media,.hero-copy,.hero-proof,.hero-pay{min-width:0;}
  .hero-pay img{max-width:100%;}
  .tiles{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
  .tile{min-width:0;}
  .ld-price s{display:block;margin-right:0;}
  .site-head .wrap{flex-wrap:wrap;}
}

/* ===== round 65: real carousel, pair-media and ladder images ===== */
/* A real <img> has an INTRINSIC width the .ph placeholders never had, and a
   flex/grid item's min-width:auto floor lets that 1080px blow the track open
   (docW 1508 at 1440 on the first gate run). min-width:0 on the slide lets
   flex-basis rule; max-width:100% on the ladder art caps its min-content
   contribution so .ld-img keeps its written width. Round 10's lesson bites in
   reverse: a width can hold a size open, so an image must be told it cannot. */
.carousel img{display:block;width:100%;max-width:100%;height:auto;min-width:0;}
/* The measured offender at every width: 11 thumbnails at 74px+8 gap put a
   894px MIN-CONTENT inside the hero's left grid item, and a scroll container's
   intrinsic size ignores its own overflow. min-width:0 on the grid items lets
   the fr tracks rule again (.hero-media carries it below 1280, where
   .hero-left becomes display:contents and stops being the item). */
.hero-left,.hero-right,.hero-media{min-width:0;}
.pair .pair-media{min-width:0;}
.pair-media img{display:block;width:100%;height:auto;max-width:400px;margin:0 auto;
  border:1px solid var(--hair);border-radius:10px;}
.ld-img img{display:block;width:100%;max-width:100%;height:auto;}
@media (max-width:770px){
  .pair-media img{max-width:420px;}
}
/* ===== /round 65 ===== */

/* ===== round 66: ladder art stacks on top below 820 ===== */
@media (max-width:820px){
  .ld{flex-direction:column;align-items:stretch;}
  .ld-img{flex:none;width:270px;max-width:270px;margin:0 auto;}
}
/* ===== /round 66 ===== */

/* ===== round 72: a 3-tile method grid never orphans (2026-08-05) =====
   .tiles goes 2-up below 1280, which wraps a 3-tile page 2+1 and strands
   the third tile alone (the phone page's method has exactly 3 parts, by
   design and permanently). Scoped with :has() (round 64 precedent) to
   grids whose third tile is the last child, so the 6-tile pages keep
   their 2-up. minmax(0,1fr) + min-width:0 per round 56: 1fr's automatic
   minimum is the overflow, not any literal width. */
@media (max-width:1279px){
  .tiles:has(> .tile:nth-child(3):last-child){grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;}
  .tiles:has(> .tile:nth-child(3):last-child) .tile{min-width:0;padding:14px 10px;}
}
@media (max-width:480px){
  .tiles:has(> .tile:nth-child(3):last-child){gap:8px;}
  .tiles:has(> .tile:nth-child(3):last-child) .tile{padding:12px 8px;}
  .tiles:has(> .tile:nth-child(3):last-child) .tile h3{font-size:15px;}
  .tiles:has(> .tile:nth-child(3):last-child) .tile p{font-size:13px;}
}
/* Half A (2026-08-06): the Rule 63 standing disclosure under a voice block
   takes the same de-emphasized legal style it has in the footer. .fine was
   footer-scoped only, so inside .box it inherited the 18px body size and
   read as a third quote. .fine is on brand_audit's SIZE_EXEMPT list by
   class, so this is the sanctioned exception, not a new paragraph size. */
.box .fine{color:#8a8a92;font-size:13.5px;margin-top:10px;}

/* ===== round 73: the voices section + the decide note (2026-08-06) =====
   .bento.voices: six quote cards, 3x2 on desktop, 2-up below 1280 per
   Gabriel's spec (tablet AND mobile two by two). minmax(0,1fr) +
   min-width:0 per round 56. The decide note is plain text under the
   Get It All card, centered as a BLOCK at the ladder's own width
   (round 9: a centred element shares the CENTRE of the row above). */
.bento.voices{grid-template-columns:repeat(3,minmax(0,1fr));}
.bento.voices .box{min-width:0;}
@media (max-width:1279px){
  .bento.voices{grid-template-columns:repeat(2,minmax(0,1fr));}
}
.decide-note{max-width:730px;margin:18px auto 0;text-align:center;}
/* The quote highlighter (Gabriel 2026-08-06): brand accent as a marker-pen
   wash + bold on the load-bearing fragment of each story, so a scanner
   gets the ambush without reading the paragraph. Background, not border,
   so the one-border language is untouched; box-decoration-break keeps a
   wrapped highlight continuous. */
.hlt{background:var(--accent);padding:0 2px;box-decoration-break:clone;-webkit-box-decoration-break:clone;}

/* ===== round 74: travelled cards + the under-button proof (2026-08-06) =====
   A travelled quote card caps at the pair image's own 400px and centers,
   so on desktop it sits squarely under the 1:1 picture and on mobile it
   joins the stack at the same width. The final CTA paragraph widens to
   the wrap so it holds two lines at 1440; the close-proof note narrows
   to read as the button's caption (Gabriel: minus ~25%, no highlighter
   against the yellow button). */
.pair > .box{max-width:400px;margin:0 auto;min-width:0;}
.voice-solo{max-width:400px;margin-left:auto;margin-right:auto;}
section > .wrap > p.cta-para{max-width:1080px;}
.closeproof-note{max-width:548px;margin:14px auto 0;text-align:center;}

/* ===== round 75: order security + the write-in ask (2026-08-06) ============
   Both are short centred notes attached to something above them, so they take
   the .decide-note shape rather than a new one. The order-security line sits
   with the card icons (one visual unit, section integrity); the write-in ask
   sits under the close proof as a postscript, never as a second CTA. */
.paysec-note{max-width:730px;margin:10px auto 0;text-align:center;}
.writein-note{max-width:640px;margin:18px auto 0;text-align:center;}

/* ===== round 77: the travelled card, the pricing lede, the close note =====
   (2026-08-06, Gabriel's read of rounds 75/76)

   1. THE TRAVELLED QUOTE CARD, desktop. `.pair` is a 2-column grid with
      align-items:center, and the card is a THIRD grid item, so it auto-places
      into column 1 ROW 2 - and row 1 is as tall as the BODY column, which
      floated the card far below the picture it belongs to. Pinning the body
      across both rows lets the card sit directly under the image. Placement is
      explicit (grid-column/grid-row) rather than order-based, because the flip
      class already uses `order` and the two do not compose predictably.
      Scoped with :has() so a pair without a card is untouched.
   2. The pricing lede drops the 900px reading cap to the wrap's own width, so
      the sentence lands on 2 lines at 1440 instead of 3.
   3. The close-proof note narrows to 660px, MEASURED as the tightest width
      that still holds 2 lines on all four pages (620 pushes tax and repair
      to 3). At the inherited 900px its second line orphaned a few words.
      Note this also FIXES round 74: its own `.closeproof-note{max-width:
      548px}` never applied, because the base `section > .wrap > p` rule
      outranks a bare class here. The note has rendered at 900px since the
      day it shipped. Specificity, eighth occurrence. */
@media (min-width:1280px){
  /* row-gap:0 because the body spans BOTH rows, so the only gap the
     grid can still open is the one between the picture and the card. */
  .pair.flip:has(> .box){align-items:start;row-gap:0;}
  .pair.flip:has(> .box) > .pair-media{grid-column:1;grid-row:1;}
  /* LONGHAND deliberately: the `grid-row:1 / span 2` shorthand was dropped
     as invalid here, which is silent - the rule still matched, the
     declaration just never existed, so the body stayed grid-row:auto and the
     card kept floating below a full-height row. A declaration that vanishes
     looks exactly like a selector that does not match. */
  .pair.flip:has(> .box) > .pair-body{grid-column:2;grid-row-start:1;grid-row-end:span 2;}
  .pair.flip:has(> .box) > .box{grid-column:1;grid-row:2;margin-top:18px;}
}
@media (max-width:1279px){
  /* Mobile already stacks the card straight after the yellow .hl by source
     order; it only needed to sit closer to it than the 24px row gap. */
  .pair.flip:has(> .box) > .box{margin-top:-8px;}
}
section > .wrap > p.pricepara-wide{max-width:1080px;}
/* SPECIFICITY, eighth occurrence in this project, and it means round 74's
   own `.closeproof-note{max-width:548px}` NEVER APPLIED: the base
   `section > .wrap > p` rule wins, so this note has rendered at the full 900px
   reading width since the day it shipped. Same fix round 74 used one line
   above for .cta-para. Measured, not assumed. */
section > .wrap > p.closeproof-note{max-width:660px;}
