/* hwr-v3.css: the v3 preview sheet for heywillray.com.
   Will's direction, 2026-08-22: the aicom.co / course.aicom.co treatment,
   which is LIGHT, FLAT and RESTRAINED, carried in HWR green instead of their
   purple. It exists because the dark hwr.css read as AI-generated, and the
   reason it read that way was decoration density, not the color: a glow blob
   baked into every card corner, a glowing shadow under every button, gradient
   text on headlines, a pill with a pulsing dot over every section.

   So the rules here are subtractive, and they are the whole point:

     1. GREEN IS THE ACCENT, NOT A SURFACE. This is the rule the whole sheet
        turns on, and it was arrived at the hard way, so read the history
        before changing it.

        Where aicom puts purple, we put green: the mast, the CTA, eyebrows,
        step pills, the rail, checkmarks, card edges, the big numbers. That
        is a LOT of green, deliberately, and it is what makes the page feel
        like a brand rather than a template. Green on small, sharp elements
        is the look.

        What broke was scale, not amount. A full-height green HERO made the
        ground itself green, and then the button sitting on it had nothing
        left to say. Will, 2026-08-22: "i dont like the hero too much green".
        The fix was to take green off the big surfaces, not off the details.
        A first pass stripped the details too and went visibly dead, which he
        also caught: "we want the green on there, I feel like we went too
        far."

        So: green on hundreds of small things is right. Green on one big
        thing is wrong. Dark blocks are SPOTS, not the page.
     2. FLAT. No glow, no gradient text, no glass. Shadows are a single soft
        lift under cards, never a colored halo.
     3. Type carries the page. One 800-weight grotesk for display, one plain
        body face, one mono for labels only.
     4. Structure is information. A numbered rail goes on content that is
        genuinely ordered, never on an inventory.
     5. The page ALTERNATES. Will's brand guide already specifies the shape
        for web: "carbon hero, bone content sections, carbon footer". Dark
        blocks are structural, marking where the page changes subject, and
        they are not a second theme. See the dark-ground block below.

   Do NOT load this alongside hwr.css. They are separate worlds and the class
   prefixes (hw- vs v3-) exist so a page can only ever be in one of them.

   Single theme on purpose, in the sense that matters: there is no dark-mode
   toggle and no prefers-color-scheme branch, because the live site has
   neither. Light and dark here are page REGIONS the author picks, not a
   viewer preference, so every color is painted explicitly and the page looks
   the same on any host ground. */

:root {
  --page: #eef6f0;
  --card: #ffffff;
  --sunk: #f6faf7;
  --line: rgba(11, 26, 17, .09);
  --line-2: rgba(11, 26, 17, .16);

  --ink: #0c1a11;
  --ink-soft: #4c5d52;
  --ink-faint: #8a998f;

  --green: #16a34a;
  --green-deep: #0d7a37;
  --green-rail: #14532d;
  --green-wash: rgba(22, 163, 74, .10);

  /* The two dark grounds. Two depths, not one, so the page can layer: the
     standard dark block, and one deeper tone reserved for the single beat
     the page turns on. Using one tone for both makes adjacent dark sections
     merge into an undifferentiated slab.

     NEAR-BLACK WITH A GREEN CAST, NOT GREEN. These were #0d3a1f and #06170d,
     a saturated green, and Will called it: the hero was too much green. He is
     right and the brand guide agrees. It names Carbon #111520 as the dark
     surface and gives the accents the color work, and rule 1 at the top of
     this file says green is the CTA and never decorates. A saturated green
     ground breaks that rule at the largest possible scale, because the
     surface then outshouts the button sitting on it.

     Keep any future dark tone in this range. If the ground reads as "green"
     rather than "dark", it is wrong. */
  --ground-dark: #0e3a20;
  --ground-deep: #08240f;

  /* The page ground OUTSIDE the content sheet. aicom runs a near-black
     shell with the whole page floating on it as one big rounded card, and
     that is where the "dark on the outside" comes from: the dark is the
     margin, not the hero. Near-black with a green cast, never saturated. */
  --shell: #080d0a;

  --flag: #b45309;

  --shadow: 0 18px 40px -26px rgba(12, 40, 22, .38);
  --shadow-lift: 0 22px 50px -28px rgba(12, 40, 22, .45);

  --maxw: 720px;
  --wide: 1040px;

  --head: 'Plus Jakarta Sans', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ease: cubic-bezier(.16, .84, .44, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--shell);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--green-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
  font-family: var(--head);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.16;
  margin: 0;
  color: var(--ink);
  text-wrap: balance;
}
h1 { font-size: clamp(30px, 6.4vw, 44px); line-height: 1.1; }
h2 { font-size: clamp(23px, 4.2vw, 31px); }
h3 { font-size: 18px; line-height: 1.3; }
p { margin: 0; }
ul, ol { margin: 0; padding-left: 1.15em; }
strong { color: var(--ink); font-weight: 700; }
em { font-style: normal; color: var(--green-deep); }
hr { border: 0; border-top: 1px solid var(--line); margin: 0; }
:focus-visible { outline: 2px solid var(--green-deep); outline-offset: 3px; }
.v3-sr { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ── Dark ground ───────────────────────────────────────────
   Will's brand guide already asks for this shape on web: "carbon hero, bone
   content sections, carbon footer". So the page alternates rather than
   running light end to end.

   Implemented by REDEFINING THE TOKENS on the dark container, not by writing
   a dark override for every component. Custom properties inherit, so a card,
   a step, a FAQ row or a file frame dropped inside a dark section reads the
   dark values with no extra rule and no specificity fight. Add a component
   later and it works on both grounds for free.

   Two consequences worth knowing before editing:
     - The accent LIFTS on dark. #0d7a37 is unreadable on #101a14, so
       --green-deep becomes a bright green here. That is the same lift the
       brand guide describes for Brick and Navy on carbon. It still only
       reaches the three things rule 1 allows.
     - A filled button therefore needs DARK text, not white. That is the one
       thing the token swap cannot infer, so it is stated explicitly below. */
.v3-section--dark,
.v3-navbar--dark,
.v3-foot--dark {
  --card: #12301f;
  --sunk: #0a2415;
  --line: rgba(255, 255, 255, .12);
  --line-2: rgba(255, 255, 255, .22);

  --ink: #ffffff;
  --ink-soft: #b9d6c2;
  --ink-faint: #8fb69c;

  --green: #22c55e;
  --green-deep: #4ade80;
  --green-wash: rgba(74, 222, 128, .14);

  --shadow: 0 18px 40px -26px rgba(0, 0, 0, .6);
  --shadow-lift: 0 22px 50px -28px rgba(0, 0, 0, .7);

  background: var(--ground-dark);
  color: var(--ink-soft);
}

/* The deeper tone. One per page at most: it marks the beat the page turns
   on, and it is what stops two adjacent dark sections reading as one slab. */
.v3-section--deep { background: var(--ground-deep); }

/* A filled button on dark ground. The lifted accent is bright enough that
   white text on it fails contrast, so the label goes dark. */
.v3-section--dark .v3-btn,
.v3-navbar--dark .v3-btn {
  color: #06170d;
  box-shadow: 0 10px 24px -14px rgba(0, 0, 0, .8);
}
.v3-section--dark .v3-btn:hover,
.v3-navbar--dark .v3-btn:hover { color: #06170d; }
.v3-section--dark .v3-btn--ghost,
.v3-navbar--dark .v3-btn--ghost { color: #fff; background: transparent; }
.v3-section--dark .v3-btn--ghost:hover,
.v3-navbar--dark .v3-btn--ghost:hover { color: #fff; border-color: #fff; }

/* The rail track is the one hardcoded color left, because it is a tint of
   the accent rather than a token in its own right. */
.v3-section--dark .v3-flow__rail { background: rgba(255, 255, 255, .12); }
.v3-section--dark .v3-flow__dot { border-color: var(--ground-dark); }
.v3-section--deep .v3-flow__dot { border-color: var(--ground-deep); }
/* A filled step marker on dark: the bright accent with dark numerals. */
.v3-section--dark .v3-step.on .v3-step__icon { color: #06170d; }
.v3-section--dark .v3-step.on .v3-step__pill { color: #06170d; }

/* ── Preview flag ──────────────────────────────────────────
   This sheet only ever serves behind HWR_V3_OPEN. The banner is here so
   nobody screenshots a preview and mistakes it for the live site. */
.v3-flag {
  background: var(--flag); color: #fff;
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  text-align: center; padding: 7px 12px;
}

/* ── Layout ────────────────────────────────────────────────
   Narrow by default, which is the aicom read: one column, generous line
   length, nothing competing sideways. --wide is opt-in for grids and the
   before/after pair, which genuinely need the room. */
/* The content sheet. Everything between the mast and the footer lives in
   here, floating on the dark shell with a gap on every side. It is what
   makes the page read as a card rather than a wall, and it is how the
   design gets dark edges without a dark hero.

   overflow:hidden is load-bearing: the dark message band runs the full
   width of the sheet, and without it the band's square corners punch out
   through the sheet's rounded ones. */
.v3-sheet {
  background: var(--page);
  border-radius: 20px;
  overflow: hidden;
  /* The gutter GROWS with the window instead of sitting at a fixed hairline.
     It was a flat 10px until 1260px, where the max-width finally took over and
     produced a real margin. That meant the dark shell was ~100px either side
     on a 1440 monitor and a 10px thread on a 1180 laptop, so the whole "page
     floats on a dark ground" idea only existed on the widest screens. Will
     looked at it on a normal window and reported the dark edge missing, which
     is exactly what a 10px thread looks like. Measured at both widths before
     changing it, 2026-08-23.

     clamp, not a breakpoint, because the gutter should track the window the
     way the sheet does. The 10px floor is deliberate: on a phone the dark is
     a detail and horizontal space is the scarce thing, so it must not eat
     into the reading width. */
  margin: 10px clamp(10px, 3vw, 34px) 0;
  max-width: 1240px;
}
@media (min-width: 1260px) { .v3-sheet { margin: 14px auto 0; border-radius: 26px; } }

.v3-wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 22px; }
.v3-wrap--wide { max-width: var(--wide); }
.v3-wrap--tight { max-width: 600px; }

.v3-section { padding: 44px 0; }
.v3-section--sunk { background: var(--sunk); }
.v3-center { text-align: center; }
.v3-stack { display: flex; flex-direction: column; gap: 18px; align-items: center; text-align: center; }
.v3-row { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; align-items: center; }
@media (min-width: 768px) { .v3-section { padding: 68px 0; } }

.v3-head { display: flex; flex-direction: column; gap: 10px; align-items: center; text-align: center; margin-bottom: 26px; }
.v3-head p { color: var(--ink-soft); font-size: 16px; max-width: 560px; }
@media (min-width: 768px) { .v3-head { margin-bottom: 34px; } }

/* Kicker. A plain mono label between two hairlines. Deliberately NOT a
   filled pill with a dot: that badge is the single most AI-looking element
   in the dark sheet and it sat above every section. */
.v3-kicker {
  display: flex; align-items: center; gap: 9px; justify-content: center;
  font-family: var(--mono); font-weight: 700; font-size: 11px;
  letter-spacing: .13em; text-transform: uppercase; color: var(--green-deep);
}
.v3-kicker::before, .v3-kicker::after { content: ""; width: 22px; height: 1px; background: currentColor; opacity: .45; }
.v3-kicker--bare::before, .v3-kicker--bare::after { display: none; }
.v3-kicker--muted { color: var(--ink-faint); }
.v3-kicker--muted::before, .v3-kicker--muted::after { opacity: .35; }

/* ── Nav ───────────────────────────────────────────────────
   Two items, no link list. A sales page nav that offers five destinations is
   five ways to leave before the buy box. */
.v3-navbar {
  position: sticky; top: 0; z-index: 50;
  background: rgba(238, 246, 240, .88);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.v3-nav {
  position: relative;
  max-width: var(--wide); margin: 0 auto; padding: 11px 22px;
  display: flex; align-items: center; gap: 14px;
}
.v3-nav__brand {
  font-family: var(--mono); font-weight: 700; font-size: 13px;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink);
  white-space: nowrap;
}
.v3-nav__brand:hover { text-decoration: none; color: var(--green-deep); }
/* Sitewide links, behind a hamburger since 2026-08-23 (Will's call: the nav
   CTA button is gone and everything lives in one menu). The panel is a fixed
   row of links on every width, not a scrolling strip, because it is no longer
   competing with a button for the bar. The page CTA is the first item and the
   only filled one. */
.v3-nav__toggle {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0);
}
.v3-nav__burger {
  margin-left: auto; cursor: pointer;
  display: flex; flex-direction: column; justify-content: center; gap: 5px;
  width: 40px; height: 34px; padding: 0 8px; border-radius: 8px;
  border: 1px solid var(--line);
}
.v3-nav__burger span {
  display: block; height: 2px; border-radius: 2px; background: var(--ink);
  transition: transform .18s ease, opacity .18s ease;
}
.v3-nav__toggle:focus-visible + .v3-nav__burger { outline: 2px solid var(--green-deep); outline-offset: 2px; }
.v3-nav__toggle:checked + .v3-nav__burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.v3-nav__toggle:checked + .v3-nav__burger span:nth-child(2) { opacity: 0; }
.v3-nav__toggle:checked + .v3-nav__burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.v3-nav__links {
  display: none;
  position: absolute; left: 0; right: 0; top: 100%;
  flex-direction: column; align-items: stretch; gap: 2px;
  padding: 10px 22px 16px;
  background: #eef6f0;
  box-shadow: 0 12px 24px -12px rgba(6, 23, 13, .35);
  border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 12px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase;
}
.v3-nav__toggle:checked ~ .v3-nav__links { display: flex; }
.v3-nav__links a {
  color: var(--ink-soft); padding: 11px 2px;
  border-bottom: 1px solid var(--line);
}
.v3-nav__links a:last-child { border-bottom: 0; }
.v3-nav__links a:hover { text-decoration: none; color: var(--green-deep); }
.v3-nav__go {
  font-family: var(--head); font-weight: 800; font-size: 13.5px;
  letter-spacing: 0; text-transform: none;
  color: #fff; background: var(--green-deep);
  padding: 11px 17px; border-radius: 999px; text-align: center;
  margin-bottom: 6px; border-bottom: 0;
}
.v3-nav__links a.v3-nav__go:hover { color: #fff; background: var(--green); }
.v3-navbar--dark .v3-nav__burger { border-color: rgba(255, 255, 255, .28); }
.v3-navbar--dark .v3-nav__burger span { background: #fff; }
.v3-navbar--dark .v3-nav__links {
  background: #0e3a20;
  border-bottom-color: rgba(255, 255, 255, .12);
}
.v3-navbar--dark .v3-nav__links a { color: rgba(255, 255, 255, .78); border-bottom-color: rgba(255, 255, 255, .12); }
.v3-navbar--dark .v3-nav__links a:hover { color: #fff; }
.v3-navbar--dark .v3-nav__go { background: var(--green-deep); color: #06170d; }
.v3-navbar--dark .v3-nav__links a.v3-nav__go:hover { background: #fff; color: #06170d; }

/* Dark nav. It sits directly above a dark hero, so the two read as one
   carbon block at the top of the page rather than a light strip stranded on
   dark. Sticky, so that block is what follows you down. */
.v3-navbar--dark {
  background: rgba(14, 58, 32, .92);
  border-bottom-color: rgba(255, 255, 255, .12);
}
.v3-navbar--dark .v3-nav__brand { color: #fff; }
.v3-navbar--dark .v3-nav__brand:hover { color: var(--green-deep); }

/* ── Hero ──────────────────────────────────────────────────
   The mast is the one saturated block on the page. Flat dark green, no
   radial glow behind the headline. */
.v3-hero { padding: 38px 0 10px; text-align: center; }
.v3-hero h1 { max-width: 640px; margin: 0 auto; }
.v3-lead { max-width: 560px; margin: 0 auto; font-size: 16.5px; color: var(--ink-soft); }

/* Two columns from 900px, the way aicom sets its hero on desktop: the
   argument on the left, the artifact on the right. Below that it stacks and
   the art goes first, because on a phone the picture earns the scroll.
   A page with nothing worth showing should stay centered and skip this. */
.v3-hero--split .v3-wrap { max-width: var(--wide); }
.v3-hero--split .v3-hero__grid { display: grid; gap: 28px; align-items: center; }
.v3-hero--split .v3-stack { align-items: center; text-align: center; }
.v3-hero--split .v3-lead, .v3-hero--split .v3-hero h1 { margin-left: auto; margin-right: auto; }
.v3-hero__art img {
  width: 100%; max-width: 320px; margin: 0 auto;
  border-radius: 14px; box-shadow: var(--shadow-lift);
}
@media (min-width: 900px) {
  .v3-hero--split .v3-hero__grid { grid-template-columns: 1.15fr .85fr; gap: 44px; }
  .v3-hero--split .v3-stack { align-items: flex-start; text-align: left; }
  .v3-hero--split .v3-stack .v3-lead { margin-left: 0; }
  .v3-hero--split .v3-stats { margin-left: 0; }
  .v3-hero--split .v3-row { justify-content: flex-start; }
  .v3-hero__art img { max-width: 360px; }
}
@media (min-width: 768px) { .v3-hero { padding: 56px 0 14px; } .v3-lead { font-size: 17.5px; } }

/* ── Buttons ───────────────────────────────────────────────
   One filled pill. The shadow is a neutral lift, not a green halo. */
.v3-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--head); font-weight: 800; font-size: 16px; letter-spacing: -.01em;
  color: #fff; background: var(--green-deep);
  padding: 16px 30px; border-radius: 999px; border: 0; cursor: pointer;
  text-decoration: none; width: 100%; max-width: 420px;
  box-shadow: 0 10px 24px -14px rgba(12, 40, 22, .7);
  transition: background .2s var(--ease), transform .2s var(--ease);
}
.v3-btn:hover { background: var(--green); text-decoration: none; color: #fff; transform: translateY(-1px); }
.v3-btn:active { transform: translateY(0); }
.v3-btn--ghost {
  background: transparent; color: var(--ink);
  border: 1px solid var(--line-2); box-shadow: none;
}
.v3-btn--ghost:hover { background: transparent; color: var(--ink); border-color: var(--green); }
.v3-btn--block { max-width: none; }
@media (min-width: 560px) { .v3-btn { width: auto; } .v3-btn--block { width: 100%; } }

.v3-sub { font-size: 14px; color: var(--ink-soft); max-width: 440px; }
.v3-fine { font-size: 12.5px; color: var(--ink-faint); max-width: 520px; }
.v3-fine a { color: var(--ink-soft); text-decoration: underline; }
.v3-note { display: block; margin-top: 10px; font-size: 12.5px; color: var(--ink-faint); }

/* ── Forms ─────────────────────────────────────────────────
   Tier 2. Only the base is here: /v3/unsubscribe is a hidden field and one
   button, and that is all it needs. The fields, the choice chips and the
   alert land with /v3/review, so each page adds only what it uses.

   Flat, like everything else in the sheet: a hairline box on the card
   surface, and the accent shows up on focus rather than sitting there. */
.v3-form { width: 100%; max-width: 520px; display: flex; flex-direction: column; gap: 12px; text-align: left; }
.v3-form--wide { max-width: 640px; }
.v3-form .v3-btn { max-width: none; width: 100%; margin-top: 4px; }

/* Fields, landed with /v3/review. A label is a small mono-ish caption above
   its field rather than a floating placeholder: a placeholder that doubles as
   the label disappears the moment somebody types, which is the one time they
   need to know what they are answering. */
.v3-form__row { display: flex; flex-direction: column; gap: 6px; }
.v3-form label { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); letter-spacing: .02em; }
.v3-form legend { font-size: 12.5px; font-weight: 600; color: var(--ink-soft); letter-spacing: .02em; padding: 0; }
.v3-form input[type="text"], .v3-form input[type="email"], .v3-form input[type="url"], .v3-form textarea, .v3-form select {
  width: 100%; padding: 15px 16px; border-radius: 12px;
  border: 1px solid var(--line-2); background: var(--card);
  color: var(--ink); font: inherit; font-size: 16px; outline: none;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
/* 16px on the inputs is not a taste call: anything smaller makes iOS Safari
   zoom the page on focus, and the reader loses their place in the form. */
.v3-form textarea { min-height: 120px; resize: vertical; }
.v3-form input:focus, .v3-form textarea:focus, .v3-form select:focus {
  border-color: var(--green); box-shadow: 0 0 0 4px var(--green-wash);
}
.v3-form input::placeholder, .v3-form textarea::placeholder { color: var(--ink-faint); }

/* Multi-select chips. Real tap targets, because the phone is where these get
   filled in, and a bare 13px checkbox next to a label is not one. */
.v3-choice { display: flex; flex-wrap: wrap; gap: 10px; }
.v3-choice label {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 12px;
  border: 1px solid var(--line-2); background: var(--card);
  color: var(--ink); font-size: 14px; font-weight: 500; cursor: pointer;
}
.v3-choice label:hover { border-color: var(--green); }
.v3-choice input, .v3-check input { accent-color: var(--green); }
.v3-check { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; color: var(--ink-soft); }
.v3-check input { margin-top: 4px; }

/* The one place the sheet uses a warm colour, and it is deliberately the same
   amber as the preview flag rather than red: "check the fields and try again"
   is a nudge, not a failure, and red on a form somebody just filled in reads
   as an accusation. */
.v3-alert {
  font-size: 14px; color: var(--flag); padding: 12px 14px;
  border: 1px solid rgba(180, 83, 9, .3); border-radius: 12px;
  background: rgba(180, 83, 9, .07); max-width: 520px;
}

/* Amber on a dark ground, the same move the buttons make two hundred lines
   up: --flag is a deep amber picked for white paper and it disappears against
   --ground-deep. /v3/second-brain puts its opt-in form inside the dark band,
   and that is where ?busy=1 and ?error=1 render, so this is not decoration. */
.v3-section--dark .v3-alert {
  color: #fbbf24;
  border-color: rgba(251, 191, 36, .35);
  background: rgba(251, 191, 36, .1);
}

/* ── Stat strip ────────────────────────────────────────────
   Flat, hairline-divided, no card chrome. */
.v3-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
  max-width: 560px; margin: 0 auto; width: 100%;
}
.v3-stats div { padding: 18px 6px; text-align: center; }
.v3-stats div + div { border-left: 1px solid var(--line); }
.v3-stats b {
  display: block; font-family: var(--head); font-weight: 800;
  font-size: clamp(22px, 5.4vw, 30px); line-height: 1; letter-spacing: -.03em;
  font-variant-numeric: tabular-nums; color: var(--green-deep);
}
.v3-stats span {
  display: block; margin-top: 7px; font-size: 11px; line-height: 1.35;
  color: var(--ink-faint); padding: 0 4px;
}

/* Inline code. hwr.css has always styled this and the v3 sheet never did,
   which went unnoticed until /v3/whole-machine, the first ported page to
   render a <code> element (it names THE-BOOK.html inside a card). Without a
   rule it falls back to the browser's default monospace at the wrong size. */
code, kbd {
  font-family: var(--mono); font-size: .92em; color: var(--ink);
  background: var(--sunk); padding: 2px 6px; border-radius: 6px;
  border: 1px solid var(--line);
}

/* ── Prose ─────────────────────────────────────────────────*/
.v3-prose { display: flex; flex-direction: column; gap: 15px; color: var(--ink-soft); font-size: 16.5px; }
.v3-prose h2 { color: var(--ink); margin-bottom: 2px; }
.v3-prose strong { color: var(--ink); }
.v3-prose blockquote {
  margin: 0; padding: 15px 18px;
  background: var(--card); border: 1px solid var(--line);
  border-left: 3px solid var(--green); border-radius: 0 12px 12px 0;
  color: var(--ink);
}
/* Long copy, settled on /privacy and /terms (Tier 1). The flex gap above
   spaces the BLOCKS; it does nothing inside a list, and those two pages run
   several hundred words of list-heavy legal prose. Without the first rule the
   items in "What I collect" run together into one grey wall. The green marker
   is the accent doing what rule 1 asks of it: small, sharp, structural. */
.v3-prose li + li { margin-top: 9px; }
.v3-prose li::marker { color: var(--green); }
/* A heading gets more air above it than a paragraph does, so a long document
   reads as sections rather than as one column. */
.v3-prose h2 { margin-top: 10px; }
.v3-prose > h2:first-child { margin-top: 0; }

/* The one pull quote. Big, ink, no accent color: it is the sentence the
   section turns on, and coloring it green would make it decoration. */
.v3-pull {
  font-family: var(--head); font-weight: 800;
  font-size: clamp(19px, 3vw, 25px); line-height: 1.3;
  color: var(--ink); letter-spacing: -.02em;
  padding: 4px 0;
}

/* ── Flow: scroll-linked sequence rail ─────────────────────
   Earns its structure only where the content is genuinely ordered. Do not
   put this on an inventory list; a numbered rail over an unordered set is
   exactly the decoration this sheet exists to remove. */
.v3-flow { position: relative; display: grid; gap: 15px; }
.v3-flow__rail {
  position: absolute; left: 26px; top: 28px; bottom: 28px; width: 4px;
  border-radius: 999px; background: rgba(13, 122, 55, .13); overflow: hidden;
}
.v3-flow__fill {
  position: absolute; left: 0; top: 0; width: 100%; height: 0;
  border-radius: 999px;
  background: linear-gradient(180deg, var(--green-rail), var(--green));
}
.v3-flow__dot {
  position: absolute; left: 20px; top: 0; width: 16px; height: 16px;
  border-radius: 50%; background: var(--green); border: 3px solid var(--page);
  box-shadow: 0 0 0 2px rgba(22, 163, 74, .28);
  opacity: 0; z-index: 2; pointer-events: none;
}
.v3-step { position: relative; display: grid; grid-template-columns: 56px 1fr; gap: 14px; align-items: start; }
.v3-step__icon {
  width: 56px; height: 56px; border-radius: 17px; z-index: 1;
  background: var(--card); border: 1px solid var(--line);
  display: grid; place-items: center; color: var(--green-deep);
  box-shadow: var(--shadow);
  font-family: var(--head); font-weight: 800; font-size: 15px;
  font-variant-numeric: tabular-nums;
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease), border-color .3s var(--ease);
}
.v3-step__icon svg { width: 23px; height: 23px; }
.v3-step.on .v3-step__icon {
  background: var(--green-deep); color: #fff;
  border-color: transparent; transform: scale(1.04);
}
.v3-step__card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 18px; padding: 17px 18px 19px; box-shadow: var(--shadow);
}
.v3-step__pill {
  display: inline-block; margin-bottom: 9px;
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  padding: 5px 11px; border-radius: 999px;
  background: var(--green-wash); color: var(--green-deep);
  transition: background .3s var(--ease), color .3s var(--ease);
}
.v3-step.on .v3-step__pill { background: var(--green-deep); color: #fff; }
.v3-step__card h3 { margin-bottom: 6px; }
.v3-step__card p { font-size: 14.5px; color: var(--ink-soft); }
@media (prefers-reduced-motion: reduce) {
  .v3-step__icon, .v3-step__pill { transition: none; }
}

/* ── Cards ─────────────────────────────────────────────────*/
.v3-grid { display: grid; gap: 14px; }
@media (min-width: 640px) { .v3-grid--2 { grid-template-columns: repeat(2, 1fr); } }
.v3-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 18px; padding: 20px;
  display: flex; flex-direction: column; gap: 9px;
  box-shadow: var(--shadow);
}
.v3-card p { color: var(--ink-soft); font-size: 14.5px; }
.v3-card__k {
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--green-deep);
}
.v3-card__meta { font-size: 12.5px; color: var(--ink-faint); margin-top: auto; }
/* The author card is the only card that carries the accent, because it is
   the only one making a claim about a person rather than a feature. */
.v3-card--accent { border-top: 3px solid var(--green); }
@media (min-width: 768px) { .v3-card { padding: 24px; } }

/* ── Bento ─────────────────────────────────────────────────
   From Will's desktop screenshots: one card carrying the dominant point,
   taller and wider, beside a stack of supporting ones. Not a uniform grid.

   Use it ONLY where one item genuinely leads. On this site that is the
   product ladder, where Build First is the proven seller and everything
   else is a step off it. Three equal things in a bento is a uniform grid
   wearing a costume, and the reader has to work out a hierarchy that is
   not there. Below 820px it stacks in source order, so the lead card must
   come first in the markup as well as in the layout. */
.v3-bento { display: grid; gap: 14px; }
@media (min-width: 820px) {
  .v3-bento { grid-template-columns: 1.3fr .7fr; align-items: stretch; }
  /* Spans however many supporting cards there are. With two it makes the
     aicom shape; with one it is a tall lead beside a short support, which
     is still correct and is what the homepage renders today. */
  .v3-bento__lead { grid-row: 1 / -1; }
}
.v3-bento__lead { position: relative; overflow: hidden; }
/* The one gradient wash in the sheet, and it is nearly invisible on
   purpose: it lifts the lead card off the ground without becoming the
   glow-blob-in-every-corner that got the old design called AI slop. */
.v3-bento__lead::after {
  content: ""; position: absolute; right: -70px; top: -70px;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(closest-side, var(--green-wash), transparent);
  pointer-events: none;
}
.v3-bento__lead > * { position: relative; }

/* Icon tile. Rounded square, accent glyph on a wash. */
.v3-tile {
  width: 46px; height: 46px; border-radius: 13px; flex: none;
  background: var(--green-wash); border: 1px solid var(--line);
  display: grid; place-items: center; color: var(--green-deep);
}
.v3-tile svg { width: 22px; height: 22px; }

/* The headline number on a bento lead card. */
.v3-figure {
  font-family: var(--head); font-weight: 800;
  font-size: clamp(40px, 8vw, 62px); line-height: 1;
  letter-spacing: -.04em; color: var(--green-deep);
  font-variant-numeric: tabular-nums;
}

/* ── Video poster ──────────────────────────────────────────
   display:block is load-bearing. This is an <a>, and aspect-ratio plus
   width do nothing on an inline element: hwr.css shipped without it once
   and the hero collapsed to the play glyph while the audio played on. */
.v3-video { position: relative; width: 100%; max-width: 640px; margin: 0 auto; }
.v3-video__frame {
  display: block; position: relative; aspect-ratio: 16 / 9; width: 100%;
  border-radius: 16px; overflow: hidden; background: #000;
  border: 1px solid var(--line); box-shadow: var(--shadow-lift);
}
.v3-video__frame img, .v3-video__frame iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: cover;
}
.v3-play { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; }
.v3-play span {
  width: 62px; height: 62px; border-radius: 50%;
  background: var(--green-deep); display: grid; place-items: center;
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, .6);
}
.v3-play svg { width: 22px; height: 22px; margin-left: 3px; color: #fff; }

/* ── Numbered rules ────────────────────────────────────────
   A plain ordered list with accent numerals. Deliberately NOT the scroll
   rail: these are principles held at once, not steps taken in order. */
.v3-rules { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; counter-reset: rule; }
.v3-rules li { display: grid; grid-template-columns: 30px 1fr; gap: 12px; align-items: baseline; color: var(--ink-soft); font-size: 15px; }
.v3-rules li::before {
  counter-increment: rule; content: "0" counter(rule);
  font-family: var(--mono); font-weight: 700; font-size: 12px;
  color: var(--green-deep); letter-spacing: .04em;
}

/* For / not-for */
.v3-split { display: grid; gap: 14px; }
@media (min-width: 768px) { .v3-split { grid-template-columns: 1fr 1fr; } }
.v3-split ul { list-style: none; padding: 0; display: grid; gap: 9px; color: var(--ink-soft); font-size: 14.5px; }
.v3-split li { padding-left: 26px; position: relative; }
.v3-split li::before {
  content: ""; position: absolute; left: 0; top: 3px;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230d7a37' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12l4 4 8-9'/%3E%3C/svg%3E") center/11px no-repeat;
}
/* The not-for column reads as absence, not as a warning. A red cross here
   would make disqualifying look like failure. */
.v3-card--no li::before {
  background: rgba(11, 26, 17, .06) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a998f' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M7 12h10'/%3E%3C/svg%3E") center/11px no-repeat;
}

/* ── Band ──────────────────────────────────────────────────
   Kept as a padding modifier only. It used to carry its own hand-written
   dark overrides for h2, prose, pull quote, kicker and the file frame; all
   of that is gone, because .v3-section--dark now does it through the tokens
   and two copies of the same intent drift. Put --dark (or --deep) on the
   section alongside this. */
.v3-band { padding: 46px 0; }
@media (min-width: 768px) { .v3-band { padding: 66px 0; } }

/* ── File / screenshot frame ───────────────────────────────*/
.v3-file {
  border-radius: 14px; border: 1px solid var(--line);
  background: var(--card); overflow: hidden;
  display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.v3-file__bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 10px 14px; border-bottom: 1px solid var(--line);
  background: var(--sunk);
  font-family: var(--mono); font-size: 11px; color: var(--ink-faint);
  letter-spacing: .04em;
}
.v3-file__bar b { color: var(--green-deep); font-weight: 700; text-transform: uppercase; letter-spacing: .1em; }
.v3-file pre {
  margin: 0; padding: 16px;
  font-family: var(--mono); font-size: 13px; line-height: 1.6;
  color: var(--ink); background: none;
  white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}
.v3-file--filled { border-color: rgba(22, 163, 74, .45); }
.v3-file img { width: 100%; height: auto; }
/* No dark-band special case here any more: --card, --sunk, --line, --ink and
   --green-deep are all redefined by .v3-section--dark, and this component
   reads every one of them from a token, so it follows the ground it lands
   on. That is the whole reason the dark ground is done with tokens. */

.v3-compare { display: grid; gap: 14px; }
@media (min-width: 768px) { .v3-compare { grid-template-columns: 1fr 1fr; align-items: start; } }

/* ── FAQ ───────────────────────────────────────────────────*/
.v3-faq { display: grid; gap: 10px; }
.v3-faq details {
  background: var(--card); border: 1px solid var(--line);
  border-radius: 14px; padding: 0 18px;
}
.v3-faq summary {
  list-style: none; cursor: pointer; padding: 16px 0;
  font-family: var(--head); font-weight: 700; font-size: 15.5px; color: var(--ink);
  display: flex; justify-content: space-between; gap: 14px; align-items: center;
}
.v3-faq summary::-webkit-details-marker { display: none; }
.v3-faq summary::after {
  content: "+"; color: var(--green-deep); font-size: 21px; line-height: 1;
  flex: none; transition: transform .2s var(--ease);
}
.v3-faq details[open] summary::after { transform: rotate(45deg); }
.v3-faq details > :not(summary) { color: var(--ink-soft); font-size: 14.5px; padding: 0 0 16px; }
.v3-faq details p + p { margin-top: 9px; }
@media (prefers-reduced-motion: reduce) { .v3-faq summary::after { transition: none; } }

/* ── Buy box ───────────────────────────────────────────────
   The single loudest element on the page, and the only one that gets a
   green top edge plus a lift. Everything above it stays quiet so this
   reads as the destination. */
.v3-buy {
  width: 100%; max-width: 520px; margin: 0 auto;
  background: var(--card); border: 1px solid var(--line);
  border-top: 4px solid var(--green);
  border-radius: 20px; padding: 26px 22px;
  box-shadow: var(--shadow-lift);
  display: flex; flex-direction: column; gap: 13px; align-items: center; text-align: center;
}
.v3-buy__amount {
  font-family: var(--head); font-weight: 800;
  font-size: clamp(38px, 7vw, 52px); line-height: 1;
  letter-spacing: -.04em; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.v3-buy__list {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 9px;
  text-align: left; width: 100%; font-size: 14.5px; color: var(--ink);
}
.v3-buy__list li { display: flex; gap: 11px; align-items: flex-start; }
.v3-buy__list li::before {
  content: ""; flex: none; width: 18px; height: 18px; margin-top: 2px;
  border-radius: 50%;
  background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230d7a37' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 12l4 4 8-9'/%3E%3C/svg%3E") center/11px no-repeat;
}
.v3-buy .v3-btn { max-width: none; width: 100%; }
/* The closed state must not look like the open one. No accent edge, no lift:
   nothing here is purchasable and the box should say so before the copy does. */
.v3-buy--closed { border-top-color: var(--line-2); box-shadow: var(--shadow); }
@media (min-width: 640px) { .v3-buy { padding: 32px 30px; } }

/* ── Link rows ─────────────────────────────────────────────
   /v3/links only. A linktree is a stack of destinations, not an argument, so
   each row is one tap target: what it is, what it costs, and an arrow. The
   arrow is a CSS background rather than inline SVG, the same way the sheet
   draws its checkmarks, so the page ships no markup for decoration. */
.v3-links { display: grid; gap: 12px; width: 100%; max-width: 560px; margin: 0 auto; }
.v3-link {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px; border-radius: 16px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--ink); box-shadow: var(--shadow);
  transition: border-color .2s var(--ease), transform .2s var(--ease);
}
.v3-link:hover { transform: translateY(-2px); border-color: var(--green); text-decoration: none; color: var(--ink); }
/* The one row carrying the accent edge, for whatever is being led with. Same
   restraint as .v3-card--accent: one per page, or it stops meaning anything. */
.v3-link--primary { border-color: rgba(22, 163, 74, .45); border-top: 3px solid var(--green); }
.v3-link img { width: 64px; height: auto; border-radius: 8px; flex: 0 0 auto; }
.v3-link__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.v3-link__k { font-family: var(--mono); font-size: 10.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--green-deep); }
.v3-link__t { font-family: var(--head); font-weight: 800; font-size: 16px; color: var(--ink); }
.v3-link__d { font-size: 13px; color: var(--ink-soft); }
.v3-link__d strong { color: var(--ink); }
.v3-link__arrow {
  margin-left: auto; flex: none; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid var(--line-2); background: var(--green-wash) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230d7a37' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E") center/15px no-repeat;
}

.v3-avatar { width: 96px; height: 96px; border-radius: 50%; object-fit: cover; border: 2px solid var(--green); box-shadow: 0 0 0 6px var(--green-wash); margin: 0 auto; }
.v3-social { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
.v3-social a { font-size: 13px; color: var(--ink-soft); padding: 8px 14px; border-radius: 999px; border: 1px solid var(--line); background: var(--card); }
.v3-social a:hover { border-color: var(--green); text-decoration: none; color: var(--ink); }

/* /v3/tools names each tool in an h2, because those headings sit at the same
   level as the section headings below them and that outline is worth keeping.
   Without this they render at section size inside a card. */
.v3-card h2 { font-size: 18px; line-height: 1.3; }

/* The slim footer's one row of links. */
.v3-foot__slim { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
.v3-foot__slim a { color: var(--ink-soft); font-size: 13px; }
.v3-foot__slim a:hover { color: var(--ink); }

/* ── Testimonials ──────────────────────────────────────────*/
.v3-quotes { display: grid; gap: 14px; }
@media (min-width: 768px) { .v3-quotes { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); } }
.v3-quote {
  margin: 0; background: var(--card); border: 1px solid var(--line);
  border-radius: 16px; padding: 20px;
  display: flex; flex-direction: column; gap: 12px; box-shadow: var(--shadow);
}
.v3-quote blockquote { margin: 0; color: var(--ink); font-size: 15px; line-height: 1.55; }
.v3-quote figcaption { font-size: 12.5px; color: var(--ink-faint); margin-top: auto; font-family: var(--mono); }

/* ── Footer ────────────────────────────────────────────────*/
.v3-foot {
  background: var(--card); border-top: 1px solid var(--line);
  padding: 38px 0 34px; font-size: 14px; color: var(--ink-faint);
}
/* Carbon footer, per the brand guide. --card resolves dark here, so the
   background rule above already lands on the dark tone; this only needs to
   close the seam so the footer reads as one block with the page end. */
.v3-foot--dark { border-top-color: rgba(255, 255, 255, .1); }
.v3-foot__cols { display: grid; gap: 22px; }
/* Four columns since the socials column landed (2026-08-23). The middle step
   matters: going straight from stacked to four at 640px leaves each column
   about 140px and wraps "Second Brain Kit, free" and "X / Twitter". */
@media (min-width: 640px) { .v3-foot__cols { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .v3-foot__cols { grid-template-columns: 1.3fr 1fr 1fr 1fr; } }
.v3-foot__col { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.v3-foot__col a { color: var(--ink-soft); }
.v3-foot__col a:hover { color: var(--ink); }
.v3-foot__brand { font-family: var(--head); font-weight: 800; font-size: 16px; color: var(--ink); }
.v3-foot__brand:hover { text-decoration: none; color: var(--green-deep); }
.v3-foot__note { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); }
.v3-foot__copy {
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--ink-faint); text-align: center;
}

/* ── Reveal on scroll ──────────────────────────────────────
   Visible by default. Only hidden once the .js class proves a script ran, so
   a dead script never leaves the page blank. */
.v3-rv { opacity: 1; transform: none; }
.js .v3-rv {
  opacity: 0; transform: translateY(16px);
  transition: opacity .55s var(--ease), transform .55s var(--ease);
}
.js .v3-rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .v3-rv { opacity: 1; transform: none; transition: none; }
}

/* The compressed homepage platforms row (2026-08-23). */
.v3-connect-row { color: var(--ink-soft); line-height: 2; }
.v3-connect-row a { color: var(--ink); font-weight: 600; white-space: nowrap; }
.v3-connect-row a:hover { color: var(--green-deep); }

/* ── Embedded checkout overlay (hwr-embed.js) ──────────────
   Renders only after a buy click on a page where the key file armed
   HWR_EMBED_OPEN. Stripe's iframe owns everything inside .hwr-embed-mount. */
.hwr-embed-overlay{position:fixed;inset:0;background:rgba(10,12,10,.72);z-index:1000;display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;padding:32px 12px}
.hwr-embed-panel{position:relative;background:#fff;border-radius:12px;width:100%;max-width:480px;padding:12px}
.hwr-embed-close{position:absolute;top:6px;right:10px;border:0;background:none;font-size:26px;line-height:1;cursor:pointer;color:#444}
.hwr-embed-mount{min-height:320px}
