/* FUNNEL STYLES v3 (2026-08-20) — the reference funnel's own design system,
   matched token for token from the operator's saved copy of it: palette,
   type scale, weights, container, gutters, shadows.
   (operator: "Same font, colors, placement everything.")

   WHAT IS COPIED AND WHAT IS NOT, deliberately:
   - COPIED: the design system and the section order. A palette, a typeface
     choice and a layout are the proven FORMAT, which is the thing this whole
     project replicates on purpose (see the format-vs-photograph rule).
   - NOT COPIED: a single sentence of his writing. Every word on our pages is
     written fresh for the persona by build_site. Same rule as the thumbnails.

   PALETTE MODE. `--brand-primary/-accent/-bg/-ink` are still the four names
   build_site substitutes into, so nothing silently stops working. Under
   SITE_PALETTE=house (the default now) it writes the reference values below
   and every channel looks like the reference; under SITE_PALETTE=channel it
   writes that persona's own site_palette instead. One env var, no silent
   no-op either way. */

:root {
  /* the four substitution targets - house values are the reference's own */
  --brand-primary: #7A1F0E;   /* oxblood: buttons, price, the action colour */
  --brand-accent:  #BA8C3E;   /* gold: rules, eyebrows, small marks */
  --brand-bg:      #F2EBD4;   /* paper */
  --brand-ink:     #15110B;   /* ink */

  --paper:      var(--brand-bg);
  --paper-warm: #ECE3C2;
  --paper-deep: #DCD0AA;
  --ink:        var(--brand-ink);
  --ink-soft:   #2B241A;
  --ink-mid:    #4A4131;
  --ink-mute:   #786B53;
  --rule:       #C4B58A;
  --ox:         var(--brand-primary);
  --ox-dk:      color-mix(in srgb, var(--brand-primary) 78%, #000);
  --gold:       var(--brand-accent);
  --gold-soft:  #D4B070;
  --sage:       #4A5A3D;
  --sage-dk:    #2F3B26;

  --serif: 'Fraunces', 'EB Garamond', 'Iowan Old Style', Georgia, serif;
  --mono:  'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace;

  --container: 1240px;
  --gutter: 32px;
  --shadow-cover: 0 30px 60px -20px rgba(21,17,11,.4), 0 10px 20px -8px rgba(21,17,11,.3), 0 1px 0 rgba(21,17,11,.18);
  --shadow-page:  0 22px 60px -10px rgba(21,17,11,.25);
}
@media (max-width: 700px) { :root { --gutter: 22px; } }

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { background: var(--paper); color: var(--ink); font-family: var(--serif);
       font-size: 19px; line-height: 1.6; -webkit-font-smoothing: antialiased; }
img { max-width: 100%; display: block; }
.wrap { max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }
.wrap.narrow { max-width: 900px; }
.center { text-align: center; }
.dim { color: var(--ink-mute); font-size: .85rem; line-height: 1.7; }

/* ---- TYPE: his scale exactly. Big and LIGHT (500), not small and bold —
        this is the single biggest thing that made our page read as a knock-off. */
h1 { font-size: clamp(2.5rem, 5vw, 4.4rem); font-weight: 500; line-height: 1.04;
     letter-spacing: -.03em; margin: .35rem 0 1.1rem; }
/* THE HEADLINE'S EMPHASIS IS RED AND ITALIC, not the gold underline used in
   body copy. The reference sets the closing clause of its headline in oxblood
   italic - it is the one place on the page where colour does the work of a
   raised voice, and it is what our headline was missing entirely. */
h1 .hl { color: var(--ox); font-style: italic; box-shadow: none; font-weight: 500; }
h2 { font-size: clamp(2.2rem, 4.6vw, 3.8rem); font-weight: 500; line-height: 1.06;
     letter-spacing: -.025em; margin: .3rem 0 1.1rem; }
h3 { font-size: 1.4rem; font-weight: 600; letter-spacing: -.015em; }
em { font-style: italic; color: var(--ox); }
.eyebrow, .secnum, .stack-h, .tb-note, .tb-cta, .price-note {
  font-family: var(--mono); font-size: .74rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; }
.eyebrow { color: var(--ink-mute); }
.secnum  { color: var(--gold); margin-bottom: .7rem; }
.lede { font-size: 1.22rem; color: var(--ink-mid); max-width: 62ch; margin-bottom: 1.8rem; }
.lede.narrow-l { max-width: 70ch; }

/* ---- buttons ---- */
/* his buttons are MONO, UPPERCASE and LETTERSPACED with a trailing arrow -
   ours were serif sentence-case, which is most of why the page read softer */
.btn { display: inline-flex; align-items: center; gap: .6rem;
       font-family: var(--mono); font-weight: 500; font-size: .8rem;
       letter-spacing: .18em; text-transform: uppercase; text-decoration: none;
       border: 1px solid transparent; border-radius: 2px; padding: 18px 30px;
       transition: transform .12s ease, background .12s ease, box-shadow .12s ease; }
.btn::after { content: '→'; transition: transform .12s ease; }
.btn:hover::after { transform: translateX(4px); }
.btn-primary { background: var(--ox); border-color: var(--ox); color: var(--paper); }
.btn-primary:hover { background: var(--ox-dk); border-color: var(--ox-dk);
                     transform: translateY(-1px);
                     box-shadow: 0 8px 18px -6px rgba(122,31,14,.5); }
.btn-ghost { background: transparent; border-color: var(--rule); color: var(--ink); }
.btn-ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn-big { display: flex; width: 100%; justify-content: center;
           padding: 20px 34px; font-size: .84rem; }

/* ---- top bar ---- */
/* THE TIMER SCROLLED AWAY because only the top bar was sticky and the launch
   bar sat above it as an ordinary block. One sticky WRAPPER holds both, so
   they stay together and nothing has to measure the bar's height. */
.sticky-top { position: sticky; top: 0; z-index: 50; }
.topbar { display: flex; align-items: center;
          gap: 1.2rem; padding: .6rem var(--gutter);
          background: color-mix(in srgb, var(--paper) 92%, transparent);
          backdrop-filter: blur(6px); border-bottom: 1px solid var(--rule); }
.tb-name { font-weight: 600; letter-spacing: -.01em; }
.tb-note { color: var(--ink-mute); flex: 1; overflow: hidden;
           white-space: nowrap; text-overflow: ellipsis; }
.tb-nav { flex: 1; display: flex; gap: 1.6rem; justify-content: center;
          font-family: var(--mono); font-size: .7rem; letter-spacing: .16em;
          text-transform: uppercase; }
.tb-nav a { color: var(--ink-mid); text-decoration: none; }
.tb-nav a:hover { color: var(--ox); }
.tb-cta { color: var(--paper); background: var(--ox); text-decoration: none;
          padding: .5rem 1rem; border-radius: 4px; }

/* ---- LAUNCH BAR: a REAL deadline or nothing. build_site emits this block
        only when a launch window is set and still in the future; the script
        removes it the moment the clock runs out, so the page can never show a
        deadline that has passed — and never invents one that does not exist. */
.launch { background: var(--ink); color: var(--paper-warm); text-align: center;
          padding: .6rem var(--gutter); font-family: var(--mono);
          font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; }
.launch b { color: var(--gold-soft); font-variant-numeric: tabular-nums; }

/* ---- hero ---- */
.hero { padding: 5.5rem 0 4.5rem; background: linear-gradient(180deg, var(--paper-warm), var(--paper)); }
.hero-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 4rem; align-items: center; }
.sub { font-size: 1.25rem; color: var(--ink-mid); max-width: 54ch; margin-bottom: 1.9rem; }
.hero-ctas { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 2.2rem; }
.hero-stats { display: flex; gap: 2.6rem; border-top: 1px solid var(--rule);
              padding-top: 1.4rem; margin-bottom: 1.3rem; }
.hero-stats b { display: block; font-size: 1.7rem; font-weight: 500; letter-spacing: -.02em; }
.hero-stats span { font-family: var(--mono); font-size: .66rem; letter-spacing: .14em;
                   text-transform: uppercase; color: var(--ink-mute); }
.kicker { font-style: italic; color: var(--ink-mid); }
.hero-book img { width: min(380px, 100%); margin: 0 auto; border-radius: 3px;
                 box-shadow: var(--shadow-cover); }
.hero-book figcaption { text-align: center; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-mute); margin-top: 1.1rem; }

/* ---- sections ---- */
.sec { padding: 5.5rem 0; }
.sec.alt { background: var(--paper-deep); }

/* ---- the math ---- */
.math-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.2rem; margin-bottom: 1.8rem; }
.math-col { padding: 1.5rem 1.6rem; border-radius: 6px; }
.math-col h3 { margin-bottom: .5rem; }
.math-col.before { background: var(--paper-deep); border: 1px solid var(--rule); }
.math-col.after { background: color-mix(in srgb, var(--sage) 12%, var(--paper));
                  border: 1px solid color-mix(in srgb, var(--sage) 40%, var(--rule)); }
.math-wrap table { width: 100%; border-collapse: collapse; margin: 1.4rem 0; }
.math-wrap th { font-family: var(--mono); font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink-mute); text-align: right;
  padding: .55rem .85rem; border-bottom: 2px solid var(--ink); }
.math-wrap th:first-child { text-align: left; }
.math-wrap td { padding: .7rem .85rem; border-bottom: 1px solid var(--rule);
                text-align: right; font-size: .98rem; color: var(--ink-mid); }
.math-wrap td:first-child { text-align: left; color: var(--ink); }
/* COLOUR CARRIES THE ARGUMENT, not decoration. The whole math section exists
   to make one comparison land, so the two sides must be readable as loss and
   gain at a glance - before the reader has read a single row. Oxblood is
   already the page's "this costs you" colour and sage its "this is settled"
   colour, so the table simply reuses them rather than introducing new hues. */
.math-wrap td:nth-child(2) { color: var(--ox); }
.math-wrap td.after { color: var(--sage-dk); font-weight: 600;
                      background: color-mix(in srgb, var(--sage) 8%, transparent); }
.math-wrap th:last-child { color: var(--sage-dk); }
.math-wrap th:nth-child(2) { color: var(--ox); }
.math-col.before { border-left: 3px solid color-mix(in srgb, var(--ox) 55%, var(--rule)); }
.math-col.after  { border-left: 3px solid var(--sage); }
/* ONE phrase per field may be emphasised (see _emph). A warm underline, never a
   highlighter block - a block of colour behind text reads as an advert, an
   underline reads as someone stressing a word while speaking. */
.hl { font-weight: 600; color: var(--ink);
      box-shadow: inset 0 -.45em 0 color-mix(in srgb, var(--gold) 34%, transparent); }
.publisher-line { font-size: .85rem; color: var(--ink-mute); margin-top: .8rem; }
.publisher-line strong { color: var(--ink); }
.publisher-mark { font-family: var(--mono); font-size: .8rem; letter-spacing: .24em;
                  text-transform: uppercase; color: var(--ink); margin-bottom: .9rem; }
.math-net { font-size: 1.2rem; padding: 1rem 1.3rem; border-radius: 6px;
  background: color-mix(in srgb, var(--gold) 16%, var(--paper));
  border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--rule)); }

/* ---- contents grid (markup emitted by build_site) ---- */
.contents-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
                 gap: 1.1rem; margin: 2rem 0; }
.contents-grid .ch { background: var(--paper); border: 1px solid var(--rule);
                     border-radius: 6px; padding: 1.3rem 1.4rem; }
.sec.alt .contents-grid .ch { background: var(--paper-warm); }
.contents-grid .ch b { display: block; font-size: 1.15rem; font-weight: 600;
                       letter-spacing: -.015em; line-height: 1.28; margin-bottom: .3rem; }
.contents-grid .ch .pp { font-family: var(--mono); font-size: .66rem; letter-spacing: .14em;
                          text-transform: uppercase; color: var(--gold); }
.contents-grid .ch p { font-size: .95rem; color: var(--ink-mid); margin-top: .5rem; }
.sec-cta, .faq-cta { margin-top: 2rem; }

/* ---- author ---- */
.about-grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: 3.5rem; align-items: center; }
.about-photo img { border-radius: 6px; box-shadow: var(--shadow-page); }
.bio { color: var(--ink-mid); white-space: pre-line; }

/* ---- the offer stack ---- */
.offer { background: var(--paper-deep); }
.offer-grid { display: grid; grid-template-columns: minmax(280px, .85fr) 1.15fr;
              gap: 72px; align-items: start; }
/* a paper MAT around the cover, not a border - the cover sits on a page that
   is itself lifted off the background. This is what makes his offer read as a
   physical object rather than a product tile. */
.cover-frame { width: 100%; max-width: 480px; margin: 0 auto; padding: 14px;
               background: var(--paper); box-shadow: var(--shadow-page); }
.cover-frame img { width: 100%; }
.offer-card { background: transparent; border: 0; border-radius: 0;
              padding: 0; box-shadow: none; }
.offer-title { font-size: 1.9rem; font-weight: 600; letter-spacing: -.022em; margin: .3rem 0 .9rem; }
.price-line { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
              padding: 18px 0; border-top: 1px solid var(--rule);
              border-bottom: 1px solid var(--rule); margin-bottom: 26px; }
.price-now { font-family: var(--serif); font-size: 3.2rem; font-weight: 500;
             font-style: italic; color: var(--ox); line-height: 1; letter-spacing: -.02em; }
.price-was { font-family: var(--mono); font-size: .94rem; color: var(--ink-mute);
             text-decoration: line-through; }
.price-note { color: var(--ox); letter-spacing: .24em; }
.offer-tag { font-family: var(--mono); font-size: .74rem; letter-spacing: .24em;
             text-transform: uppercase; color: var(--ox); font-weight: 500;
             margin-bottom: 18px; display: block; }
.offer-lede { font-size: 1.12rem; color: var(--ink-soft); line-height: 1.55; margin-bottom: 22px; }
.payback { font-size: 1.08rem; color: var(--ink); font-style: italic;
           background: color-mix(in srgb, var(--sage) 12%, var(--paper));
           border-left: 3px solid var(--sage); padding: .9rem 1.1rem;
           border-radius: 0 6px 6px 0; margin-bottom: 1.6rem; }
/* an empty slot must leave NO furniture behind - an old page built before
   these tokens existed fills them with "" */
.payback:empty, .offer-tag:empty { display: none; }
.stack-h { color: var(--ox); letter-spacing: .24em; margin-bottom: .7rem; }
.addon-row { display: flex; justify-content: space-between; gap: 1.5rem; align-items: baseline;
             padding: .9rem 0; border-bottom: 1px solid var(--rule); }
.addon-row strong { font-size: 1.1rem; font-weight: 600; display: block; }
.bonus-tag { display: inline-block; font-family: var(--mono); font-size: .6rem;
             font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
             color: var(--paper); background: var(--gold);
             padding: .18rem .5rem; border-radius: 2px; margin-bottom: .4rem; }
.addon-row p { font-size: .95rem; color: var(--ink-mid); margin-top: .2rem; }
.addon-price { font-family: var(--mono); font-size: .95rem; color: var(--ink-mute); white-space: nowrap; }
.stack-total { display: flex; justify-content: space-between; font-weight: 600;
               padding: 1.1rem 0 .4rem; font-size: 1.08rem; }
.pay-today { display: flex; justify-content: space-between; align-items: baseline;
             background: color-mix(in srgb, var(--gold) 15%, var(--paper));
             border: 1px solid color-mix(in srgb, var(--gold) 42%, var(--rule));
             border-radius: 6px; padding: 1rem 1.3rem; margin: 1.1rem 0 1.7rem; }
.pay-today span { font-style: italic; font-size: 1.2rem; color: var(--ink); }
/* THE TWO FIGURES ARE SEPARATE ELEMENTS (operator, 2026-08-24: "$57$37" with
   no gap, both in the same oxblood - "should be a different font color and
   spacing"). The old markup leaned on flex gap between an element and a bare
   text node, and on the struck price inheriting a muted colour it never got.
   Each figure now carries its own colour and its own margin, so neither
   depends on inheritance or on anonymous flex items. */
.pay-today b.pay-figure { font-family: var(--mono); font-size: 1.6rem;
                          display: inline-block; white-space: nowrap; }
.pay-today .pay-was { color: color-mix(in srgb, var(--ink-mute) 88%, var(--paper));
                      font-size: 1.06rem; font-weight: 400; margin-right: .62rem;
                      text-decoration: line-through;
                      text-decoration-thickness: .07em;
                      text-decoration-color: color-mix(in srgb, var(--ink-mute) 70%, transparent); }
.pay-today .pay-was:empty { display: none; margin-right: 0; }
.pay-today .pay-now { color: var(--ox); font-weight: 600; letter-spacing: -.01em; }
.delivery, .guarantee { font-size: .95rem; color: var(--ink-mid); margin-top: .9rem; }

/* ---- faq ---- */
#faq details { border-bottom: 1px solid var(--rule); padding: 1.1rem 0; }
#faq summary { font-weight: 600; font-size: 1.15rem; letter-spacing: -.015em;
               cursor: pointer; list-style: none; }
#faq summary::-webkit-details-marker { display: none; }
#faq summary::after { content: '+'; float: right; font-family: var(--mono); color: var(--gold); }
#faq details[open] summary::after { content: '\2013'; }
#faq details p { padding-top: .7rem; color: var(--ink-mid); }

/* ---- close + footer ---- */
.close { background: var(--ink); color: var(--paper); }
.close h2 { color: var(--paper); font-size: clamp(2.6rem, 5vw, 4.4rem); max-width: 18ch;
            margin: 0 auto 1.2rem; }
.close .lede { color: color-mix(in srgb, var(--paper) 72%, var(--ink));
               margin-left: auto; margin-right: auto; }
.close .btn-big { width: auto; }
/* THE HIGHLIGHT WENT INVISIBLE ON THE INVERTED BAND (operator, 2026-08-24:
   "Give tomorrow [less to carry]" - the emphasised half unreadable). `.hl`
   sets color:var(--ink) for the light page, and this section paints --ink as
   its BACKGROUND, so the emphasised words were dark-on-dark. Repaint them for
   the inverted context and lift the underline so it still reads as emphasis. */
.close .hl, .close h2 .hl { color: var(--paper);
      box-shadow: inset 0 -.45em 0 color-mix(in srgb, var(--gold) 55%, transparent); }
.close em { color: color-mix(in srgb, var(--gold) 70%, var(--paper)); }
/* THE FOOTER SHARES THE CLOSING BAND'S DARK GROUND (operator, 2026-08-24:
   "bottom of the footer, text blurred out"). It sits directly under .close
   with no background of its own, so it inherited the dark band while its
   muted legal line kept the light-page colour - measured 3.61:1, under the
   4.5:1 a body text needs to be read. Both lines now take their colour from
   the paper, which is correct on either polarity. */
footer { padding: 3rem 0 4rem; border-top: 1px solid var(--rule);
         background: var(--ink); color: var(--paper); }
footer .dim { color: color-mix(in srgb, var(--paper) 74%, var(--ink)); }
footer .publisher-mark { color: color-mix(in srgb, var(--paper) 90%, var(--ink)); }

/* PURCHASE-NOTICE-START */
/* ---- recent purchase notice ---- */
.purchase-notice { position: fixed; left: max(16px, env(safe-area-inset-left));
                   bottom: max(16px, env(safe-area-inset-bottom)); z-index: 40;
                   width: min(360px, calc(100vw - 32px)); display: grid;
                   grid-template-columns: 38px 1fr 28px; gap: 11px; align-items: center;
                   padding: 13px 12px 13px 13px; border: 1px solid var(--rule);
                   border-left: 3px solid var(--sage); border-radius: 6px;
                   background: var(--paper-warm); color: var(--ink);
                   box-shadow: 0 13px 34px rgba(21,17,11,.2);
                   opacity: 0; transform: translate3d(0,14px,0);
                   transition: opacity .26s ease, transform .26s ease; }
.purchase-notice[hidden] { display: none; }
.purchase-notice.is-visible { opacity: 1; transform: translate3d(0,0,0); }
.purchase-notice-icon { display: grid; place-items: center; width: 36px; height: 36px;
                        border-radius: 50%; background: var(--sage); color: var(--paper);
                        font-family: var(--mono); font-size: .9rem; font-weight: 700; }
.purchase-notice-body { min-width: 0; }
.purchase-notice-body p { margin: 0; font-size: .94rem; line-height: 1.32; }
.purchase-notice-body strong { font-family: var(--serif); font-style: italic;
                                font-weight: 600; color: var(--ox); }
.purchase-notice-meta { margin-top: 3px !important; font-family: var(--mono);
                        font-size: .65rem !important; letter-spacing: .09em;
                        text-transform: uppercase; color: var(--ink-mute); }
.purchase-notice-close { align-self: start; width: 28px; height: 28px; border: 0;
                         background: transparent; color: var(--ink-mute); cursor: pointer;
                         font-size: 1.2rem; line-height: 1; border-radius: 3px; }
.purchase-notice-close:hover, .purchase-notice-close:focus-visible {
  color: var(--ink); background: color-mix(in srgb, var(--rule) 25%, transparent); }
@media (prefers-reduced-motion: reduce) {
  .purchase-notice { transition: none; transform: none; }
}
/* PURCHASE-NOTICE-END */

/* ---- exit modal ---- */
dialog#exit-modal { margin: auto; border: 1px solid var(--rule); border-radius: 8px;
                    background: var(--paper); color: var(--ink); width: min(32rem, calc(100vw - 2rem));
                    max-width: none; padding: 2.2rem 2.4rem; text-align: center; }
dialog#exit-modal::backdrop { background: rgba(21,17,11,.6); }
dialog#exit-modal h2 { font-size: 1.9rem; margin-bottom: .9rem; }
dialog#exit-modal p { color: var(--ink-mid); margin: 0 0 1.5rem; }
.modal-cover { width: 120px; aspect-ratio: 3/4; margin: 0 auto 22px;
              box-shadow: var(--shadow-cover); }
.modal-cover img { width: 100%; height: 100%; object-fit: contain; }
.modal-price { display: flex; align-items: baseline; justify-content: center; gap: 14px;
               padding: 14px 0; border-top: 1px solid var(--rule);
               border-bottom: 1px solid var(--rule); margin-bottom: 14px; }
.modal-price .price-now { font-size: 2.6rem; }
.modal-clock { font-family: var(--mono); font-size: .72rem; letter-spacing: .16em;
               text-transform: uppercase; color: var(--ink-mute); margin-bottom: 16px; }
.modal-clock b { color: var(--ox); font-variant-numeric: tabular-nums; }
.modal-clock[hidden], .modal-price:empty { display: none; }
.modal-x { display: block; margin: 16px auto 0; background: none; border: none;
           font-family: var(--mono); font-size: .72rem; letter-spacing: .18em;
           text-transform: uppercase; color: var(--ink-mute); cursor: pointer;
           text-decoration: underline; }

/* ---- responsive ---- */
@media (max-width: 900px) {
  .hero { padding: 3.5rem 0 3rem; }
  .hero-grid, .about-grid, .math-cols { grid-template-columns: 1fr; gap: 2.4rem; }
  .hero-book { order: -1; }
  .hero-book img { width: min(240px, 68%); }
  .hero-stats { gap: 1.6rem; flex-wrap: wrap; }
  .offer-grid { grid-template-columns: 1fr; gap: 2.4rem; }
  .cover-frame { max-width: 300px; }
  .tb-note, .tb-nav { display: none; }
}

/* ============================================================================
   READABILITY FOR AN OLDER READER (operator, 2026-09-06: "Make text bigger
   too, its targeted to old people").

   MEASURED ON THE LIVE PAGE BEFORE TOUCHING ANYTHING - every visible text
   node's own computed size, not the first match of a selector. That
   distinction mattered: querySelector('p') reported the body copy as 11.8px
   when 11.8px was a caption and the body was already 19px, and acting on it
   would have fixed the wrong thing. What the real distribution showed: about
   thirty elements of genuine reading matter at 15-16px, the comparison table
   at 15.7px, and EVERY BUY BUTTON AT 12.8px.

   THE ROOT STAYS 16px ON PURPOSE. rem drives padding, gaps and the container
   width here as well as type, so raising it re-flows the whole page to fix
   text. Each size is raised where it is set instead - predictable, and every
   line below is revertible on its own.

   LETTERSPACING COMES DOWN AS THE MONO CAPS GO UP. At .18-.24em a label gets
   wider faster than it gets clearer, the top bar has a fixed row to fit, and
   wide tracking works against word-shape recognition - which is exactly what
   an older reader leans on most.
   ========================================================================= */
body { font-size: 20.5px; line-height: 1.68; }
h3 { font-size: 1.5rem; }
.lede { font-size: 1.3rem; }
.sub { font-size: 1.32rem; }
.dim { font-size: .95rem; }

.eyebrow, .secnum, .stack-h, .tb-note, .tb-cta, .price-note {
  font-size: .86rem; letter-spacing: .17em; }
.btn { font-size: .95rem; letter-spacing: .13em; }
.btn-big { font-size: 1.02rem; }
.tb-nav { font-size: .82rem; letter-spacing: .12em; }
.launch { font-size: .88rem; letter-spacing: .12em; }
.hero-stats span { font-size: .78rem; letter-spacing: .11em; }
.hero-book figcaption { font-size: .78rem; letter-spacing: .12em; }
.math-wrap th { font-size: .8rem; letter-spacing: .12em; }
.math-wrap td { font-size: 1.08rem; }
.publisher-line { font-size: .95rem; }
.publisher-mark { font-size: .9rem; letter-spacing: .18em; }
.contents-grid .ch b { font-size: 1.24rem; }
.contents-grid .ch .pp { font-size: .78rem; letter-spacing: .11em; }
.contents-grid .ch p { font-size: 1.06rem; }
.offer-tag { font-size: .86rem; letter-spacing: .18em; }
.offer-lede { font-size: 1.2rem; }
.payback { font-size: 1.14rem; }
.addon-row strong { font-size: 1.18rem; }
.addon-row p { font-size: 1.06rem; }
.addon-price { font-size: 1.06rem; }
.bonus-tag { font-size: .74rem; letter-spacing: .14em; }
.stack-total { font-size: 1.16rem; }
.delivery, .guarantee { font-size: 1.06rem; }
#faq summary { font-size: 1.24rem; }
.modal-clock, .modal-x { font-size: .82rem; letter-spacing: .13em; }

/* ----------------------------------------------------------------------------
   THE AUTHOR PHOTO IS A MOUNTED PLATE, NOT A FLOATING RECTANGLE (operator,
   same message: "A better avatar design on the page").

   It was a bare 6px-radius image dropped on the cream - and the take itself
   had him looking DOWN at a plank, face small inside a busy wide workshop.
   No eye contact is the weakest thing an author photo can do on a page whose
   entire job is getting a stranger to trust him with $37. The take was
   swapped for the one where he looks up at the camera (same shoot, same
   bench, so the at-work rule still holds); this gives it a warm mat, a
   hairline rule and a caption, and crops to 4:5 so the face carries the block
   rather than the tools around it.

   THE CROP IS object-fit, NOT A NEW IMAGE. Re-rendering a tighter shot costs
   an image generation and would not reproduce the same moment, while the
   source is already 896x1184 - far more resolution than a 448px column shows,
   so the crop takes detail off the sides rather than inventing any.
   ------------------------------------------------------------------------- */
.about-photo { background: var(--paper-warm); padding: 14px 14px 0;
               border: 1px solid var(--rule); border-radius: 4px;
               box-shadow: var(--shadow-page); }
.about-photo img { border-radius: 2px; box-shadow: none; width: 100%;
                   aspect-ratio: 4 / 5; object-fit: cover; object-position: 54% 26%; }
.about-photo figcaption { font-family: var(--mono); font-size: .88rem;
                          letter-spacing: .16em; text-transform: uppercase;
                          color: var(--ink-mute); text-align: center;
                          padding: 14px 0 15px; }
