/* ============================================================================
   AETHER — Public site (marketing · pricing · self-serve renewal).
   The public face of the Control Plane. Warm Hearth system, editorial.
   ============================================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }
/* `scroll-behavior: smooth` + a STICKY nav (see `.nav`) needs scroll-padding, or an
   in-page jump lands content under the bar. MEASURED, because the damage is uneven and
   the obvious claim ("every heading is hidden") is false: nav = 65px; a default section
   pads 72px, so #platform/#lines/#why/#pricing/#trust/#docs cleared it — BY 7px. The
   sections carrying inline `padding-top:0` did not: #apps put its first ink at y=0,
   entirely behind the bar. So one anchor was broken outright and the rest were one
   padding edit away from joining it. 92px gives every target the same clearance. */
/* ⚠ The 92px above is HISTORY: it was measured against a 65px bar, and the bar
   is 78px since the nav padding went to 22px. `scroll-padding-top` is now derived
   from `--sitehead-h` in `site-nav.css` (loaded after this sheet, by both halves
   of the site) so the two cannot disagree again. Only the behaviour stays here. */
html { scroll-behavior: smooth; }

/* ---- Cross-document view transitions -------------------------------------------
   MOVED to `site-nav.css` (2026-09-03). The block used to say it lived here because
   this is "the one stylesheet every page links" — that was true of the fifteen
   hand-authored pages and of nothing else. The eighteen pages rendered from the
   design drop link `site-pages.css` and never linked this file, so the feature was
   opted IN on fifteen pages and absent on eighteen. Both ends must opt in, which
   made every crossing between the two halves — including Platform → Capabilities,
   the first click on the site — the un-transitioned one, while Pricing → Trust
   transitioned. `site-nav.css` is the sheet both halves genuinely link. */

/* The ONE sub-scale tier. Hearth's scale bottoms out at --text-xs (12px), but this site
   has a real tier below it: app-store badge fine print, ribbons, superscripts and mono
   chip labels — chrome whose whole job is to sit under the reading line, and which at
   12px would compete with the body copy it annotates. That tier existed already; what it
   did not have was a NAME, so it had drifted across FOUR values (9 / 9.5 / 10 / 10.5)
   that no reader can tell apart. One token, one value, still deliberately off-scale.
   In rem like the Hearth steps, so it scales with a raised browser default too. */
:root { --text-micro: 0.625rem; }  /* 10px */

/* ---- TYPE SCALE (2026-08-23) -----------------------------------------------------
   Every font-size in this KIT — this stylesheet, site-v2.css, all 17 pages and the JS
   that renders into them — now resolves from the Hearth scale in hearth-tokens.css.
   Exactly one px literal survives, and it is named at the bottom of this comment
   (--text-xs 12 · sm 14 · base 16 · md 18 · lg 20 · xl 24 · 2xl 30 · 3xl 36 · 4xl 48 ·
   5xl 60). It did not before, and the census is the argument: 74 px literals across 23
   distinct values, of which only 19 declarations sat on the scale the design system
   already shipped. Twelve of those values lived between 11px and 17px.

   That is not a hierarchy — it is noise shaped like signal. MEASURED on this page before
   the pass: 17 distinct rendered sizes with TEN adjacent pairs closer than 1px. A reader
   cannot see the difference between 12, 12.5, 13 and 13.5, so four sizes did the
   communicative work of one while costing four times the maintenance, and any new rule
   had 23 precedents to choose from — which is why the count kept growing.

   Tokens, not new px literals, for two reasons beyond tidiness: a future change to the
   scale propagates here instead of being re-typed, and the tokens are in rem, so the
   type now honours a reader who has raised their browser's default font size. Sizes were
   snapped to the NEAREST step and every move is <= 2px; where a selector carried two
   sizes for a responsive step-down, the step-down was preserved rather than flattened
   (see the note at the 560 tier — two of them were nearly lost).

   ⚠ THE TWO REMAINING px LITERALS ARE DELIBERATE, not misses. `.store i` (9px) is the
   "Download on the" line inside an app-store badge, where 9px is the platform convention
   the badge is recognised by, and `.plan__rib` / `.pcard__title .badge` / `.price-src`
   (10px) are ribbon and superscript micro-labels. The scale bottoms out at 12px, so
   putting these on it would mean +20% to +33% on elements whose whole job is to sit
   under the reading line. They stay off-scale ON PURPOSE; do not "finish the job" here
   without redrawing those three components.

   ⚠⚠ THE STYLESHEET WAS THE SMALLER HALF. An inline style beats every selector in this
   file, and the markup was carrying more of them than the CSS ever did: 238 `font-size`
   declarations across the 17 pages and 3 JS files, in 22 distinct values including
   10.5 / 15.5 / 9.5 / 27 — values that appear nowhere in here. All 238 are converted.
   ⚠ Two traps, both of which produced a WRONG answer before a runtime probe corrected it:

     · An audit that greps a page for `hearth-tokens.css` can match the FILENAME INSIDE A
       COMMENT. motion-lab.html scored two hits and links no stylesheet at all — it copies
       a token subset inline, on purpose, to stay self-contained. Its conversion therefore
       resolved to nothing and collapsed the whole page to the inherited 16px. Converting
       a literal to a token moves the failure from "wrong value" to "NO value", so the
       check that matters is what `var(--text-xs)` RESOLVES to, never whether a file
       mentions it. (Fixed by extending that page's copied subset, as it already does for
       colour.) Every page now either links the chain or defines the steps inline.
     · Snapping can flatten a deliberate step-down when two sizes land on one rung. Check
       it with grouped selectors EXPANDED — keyed on the selector string, a grouped rule
       and its individual twin read as different selectors and the check passes while the
       regression ships. That is precisely how a 26px -> 22px phone step-down nearly died.

   ⚠ The ONE remaining px literal is `.metric .v` in site-v2.css (42px), documented at its
   own line: it is display type sitting exactly between --text-3xl and --text-4xl, so
   moving it is a 6px design decision, not a cleanup. The hero console mock on index.html
   was likewise only judged safe to put on the scale by RENDERING it, not by arguing it. */
body { font-family: var(--font-sans); background: var(--hearth-canvas); color: var(--hearth-text); line-height: 1.6; -webkit-font-smoothing: antialiased; }
a { color: inherit; text-decoration: none; }
/* On the nav's measure (1140 − 2×40 = a 1060px column), so the wordmark in the
   masthead sits on the same vertical as the first heading under it. It was
   1200/28 — a 1144px column — which put content 42px wider than its own chrome
   on every hand-authored page. */
.wrap { max-width: 1140px; margin: 0 auto; padding: 0 40px; }
.eyebrow { font-family: var(--font-label, var(--font-mono)); font-size: var(--text-xs); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--accent-text); }
/* .serif, .mono and .mark moved to site-sheet.css (2026-09-03e): the intake
   sheet needs them and this file is not loaded on the generated pages. */

/* mark + wordmark */
.wm { font-family: 'Syne', var(--font-display); font-weight: 600; letter-spacing: .2em; text-transform: uppercase; }

/* nav */
/* `.nav`'s own sticky/background/border now live in `site-nav.css`, beside the
   generated half's `.sitehead`, on one shared selector — they were identical
   declarations in two sheets, which is how the two halves drifted apart in the
   first place. Only what is genuinely this half's own is left below. */
/* `.nav__in` / `.nav__links` / `.nav__cta` are DEFINED IN `site-nav.css`, on the
   same rules as the generated half's `.sitehead__*`. They lived here as a second,
   independent copy and that is exactly how the two halves drifted to four container
   widths and three bar heights. Only `.nav__brand` stays — the generated half has no
   counterpart for it, so there is nothing it can disagree with.
   ⚠ Do not re-add nav geometry to this file. */
.nav__brand { display: flex; align-items: center; gap: 11px; }
.nav__brand .mark { width: 34px; height: 34px; } .nav__brand .mark svg { width: 34px; height: 34px; }
.nav__brand .wm { font-size: var(--text-md); }

/* ⚠ MEASURED 2026-09-03, and worth knowing before editing this rule: most of it
   NEVER APPLIES. `hearth-components.css` declares `.hearth .btn` — specificity
   (0,2,0) against this rule's (0,1,0) — and `<body class="hearth">` is on every
   page, so the component sheet wins on font-size, font-weight, gap, padding and
   BORDER-RADIUS **regardless of load order**. The pill this line asks for has
   never rendered anywhere on the public site; what ships is `--radius-md`. Only
   the properties hearth-components does not set (justify-content, transition,
   white-space) actually take effect here.
   Left as-is deliberately: nothing is INCONSISTENT (both page families lose to
   the same sheet, so nothing is displaced), and deciding whether the apex's
   buttons are pills or soft rectangles restyles every button on the site — a
   design call, filed in the tracker's §7 [CODE] 2026-09-03d, not a bug fix. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-family: var(--font-sans); font-weight: 600; font-size: var(--text-sm); border-radius: var(--radius-full); padding: 10px 18px; border: 1px solid transparent; cursor: pointer; transition: all .16s; white-space: nowrap; }
.btn svg { width: 17px; height: 17px; }
.btn-primary { background: var(--accent-solid-bg); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { filter: brightness(1.05); transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn-ghost { background: transparent; color: var(--hearth-text); border-color: var(--hearth-border-strong); }
.btn-ghost:hover { background: var(--hearth-sunken); }
.btn-lg { padding: 13px 24px; font-size: var(--text-base); }
.btn-sm { padding: 8px 14px; font-size: var(--text-sm); }
.btn-block { width: 100%; }

/* hero */
.hero { position: relative; overflow: hidden; padding: 70px 0 40px; }
.hero__bg { position: absolute; inset: 0; background:
  radial-gradient(70% 60% at 88% -5%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%),
  radial-gradient(50% 60% at 0% 100%, color-mix(in srgb, var(--viz-2) 9%, transparent), transparent 60%); pointer-events: none; }
.hero__in { position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: center; }
.hero h1 { font-family: var(--font-display); font-size: clamp(40px, 5vw, 62px); font-weight: 600; line-height: 1.03; letter-spacing: -.03em; text-wrap: balance; }
.hero h1 .hl { color: var(--accent-text); }
.hero .lede { font-size: var(--text-lg); color: var(--hearth-text-secondary); margin-top: 22px; max-width: 32em; line-height: 1.55; }
.hero__ctas { display: flex; gap: 12px; margin-top: 30px; flex-wrap: wrap; }
.hero__meta { display: flex; gap: 20px; margin-top: 30px; flex-wrap: wrap; font-size: var(--text-sm); color: var(--hearth-text-muted); }
.hero__meta span { display: inline-flex; align-items: center; gap: 7px; }
.hero__meta svg { width: 16px; height: 16px; color: var(--accent-text); }

/* product card */
.pcard { background: var(--hearth-surface); border: 1px solid var(--hearth-border); border-radius: var(--radius-2xl); box-shadow: var(--shadow-lg); overflow: hidden; }
.pcard__bar { display: flex; align-items: center; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--hearth-border-subtle); background: var(--hearth-raised); }
.pcard__bar i { width: 10px; height: 10px; border-radius: 50%; }
.pcard__bar i:nth-child(1){ background: var(--sev-high-fg);} .pcard__bar i:nth-child(2){ background: var(--sev-medium-fg);} .pcard__bar i:nth-child(3){ background: var(--status-healthy-fg);}
.pcard__bar .t { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--hearth-text-muted); margin-left: 6px; }
.pcard__body { padding: 20px; }
.pcard__title { display: flex; align-items: center; gap: 9px; }
.pcard__title .e { font-family: var(--font-display); font-size: var(--text-base); font-weight: 600; }
.pcard__title .badge { margin-left: auto; font-family: var(--font-mono); font-size: var(--text-micro); color: var(--sev-high-fg); background: var(--sev-high-bg); border: 1px solid color-mix(in srgb, var(--sev-high-fg) 22%, transparent); padding: 2px 8px; border-radius: var(--radius-full); }

/* logo strip */
.strip { display: flex; align-items: center; justify-content: center; gap: 46px; flex-wrap: wrap; padding: 36px 0; opacity: .62; }
.strip .lbl { font-size: var(--text-xs); letter-spacing: .14em; text-transform: uppercase; color: var(--hearth-text-muted); }
.strip span { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--hearth-text-muted); }
/* The measured-figures strip that replaced the fictional customer logos. Tighter gap and
   full opacity than the logo strip it inherits from: these are load-bearing numbers meant
   to be read, not a faded row of marks. The unit stays in the muted weight so the figure
   itself carries the emphasis. */
.strip--bench { gap: 30px; opacity: 1; }
.strip--bench span { font-family: var(--font-sans); font-weight: 500; font-size: var(--text-sm); }
.strip--bench b { font-family: var(--font-display); font-weight: 600; font-size: var(--text-md); color: var(--hearth-text); }
.strip--bench .lbl { flex-basis: 100%; text-align: center; }

/* sections */
section { padding: 72px 0; }
.sec-head { max-width: 60ch; margin-bottom: 44px; }
.sec-head h1, .sec-head h2 { font-family: var(--font-display); font-size: clamp(28px, 3.4vw, 40px); font-weight: 600; letter-spacing: -.02em; line-height: 1.1; margin-top: 12px;
  /* `balance` evens the line lengths of a SHORT display string so no section title
     ends on a lonely word. colors_and_type.css sets `pretty` on headings globally —
     that is the body-copy algorithm (it only guards the last line) and it is the
     wrong one here. The hero h1 already had `balance`; these never did. */
  text-wrap: balance; }
.sec-head p { font-size: var(--text-md); color: var(--hearth-text-secondary); margin-top: 14px; }

/* ---- the pinned platform claim (tracker §13 row 53, built 2026-08-25m) -----
   Two columns: the claim holds while the evidence passes it. Designed 08-23l after 08-23j
   measured that the OBVIOUS shapes cannot work — 2-up gives −10px of travel, i.e. the pin
   engages for ZERO pixels, and lighter rule-rows give ~+30px.

   ⛔⛔ THE PIN RUNS ON THE EVIDENCE COLUMN'S HEIGHT, SO DO NOT "TIDY" THAT COLUMN. Every
   instinct to make this section shorter — 2-up, slimmer cards, tighter rows — removes the
   reason to pin at all. The `.feat` card is deliberately UNCHANGED here and goes 1-up; the
   height is not a cost being tolerated, it is the mechanism.

   MEASURED ON THIS PAGE 2026-08-25m, not modelled: shipped 3-up column 464px · 1-up at 696px
   1226px · viewport 720px ⇒ pin travel +506px. (08-23l modelled ~+600; the conclusion held,
   the figure was ~19% high — which is why row 53 told the build to re-measure.) */
/* ⛔ The evidence column is FLUID, not the 696px the design modelled: `.wrap` carries 28px of
   padding each side, so a fixed 456+48+696 overflows its own 1200px box. A narrower column
   makes the cards TALLER, so this only ever increases pin travel — but it is measured below
   rather than reasoned about. */
.platform-split { display: grid; grid-template-columns: 456px minmax(0, 1fr); gap: 48px; align-items: start; }
/* ⛔ `top` clears the sticky nav (65px) and matches the 92px scroll-padding an anchor jump uses,
   so a link into this section and the pin come to rest on the same line rather than 27px apart. */
.platform-claim { position: sticky; top: 92px; }
/* The claim is LEFT-aligned here — it ships centred (`sec-head--center`) and a centred column
   beside a left-aligned one reads as a mistake rather than a choice. */
.platform-claim .sec-head { max-width: none; margin-bottom: 0; }
/* 1-up: this is the whole point, see the note above. */
.platform-split .tri--6 { grid-template-columns: minmax(0, 1fr); }

/* ⛔⛔ NON-OPTIONAL. A two-column pin on a phone freezes a heading over its own body copy —
   the claim would sit on top of the cards scrolling under it. Below the breakpoint this is an
   ordinary section: one flow, static claim. `position: static` is what un-pins it; leaving it
   sticky with one column is the exact failure. */
@media (max-width: 860px) {
  .platform-split { grid-template-columns: minmax(0, 1fr); gap: 28px; }
  .platform-claim { position: static; }
  .platform-claim .sec-head { margin-bottom: 0; }
}

/* feature triptych */
/* ---- Card grids are INTRINSIC, not breakpointed (2026-08-23) ---------------------
   Every one of these was `repeat(3, 1fr)` (or 4) with a single `max-width: 920px` rule
   collapsing it to `1fr`. That is one breakpoint doing the work of two, and the band it
   skips is the widest one on a real device: from 920px down to 560px a three-up became
   a stack of THREE FULL-WIDTH CARDS — a 40px icon and fifteen words spread over 860px
   of line. `auto-fit` + `minmax` gives the intermediate two-up for free and keeps going
   to one on a phone, with no breakpoint to maintain.

   The `min()` floors are CHOSEN, not typed: `n = floor((W + gap) / (floor + gap))` over
   this site's 1144px content column, picked so each grid still lands on exactly the
   column count it was designed for at desktop. 300px keeps `.tri`/`.plans`/`.mini` at
   three (a smaller floor would silently promote the homepage to a four-up); 240px keeps
   `.trust-grid` at four. Wrapping the floor in `min(x, 100%)` is the site's standing
   phone rule — it keeps the floor a PREFERENCE instead of becoming an overflow floor
   once the container itself is narrower than x. */
.tri { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 22px; }
.feat { background: var(--hearth-surface); border: 1px solid var(--hearth-border); border-radius: var(--radius-xl); padding: 28px 26px; box-shadow: var(--shadow-sm); transition: transform .2s, box-shadow .2s; }
.feat:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.feat__ic { width: 48px; height: 48px; border-radius: 13px; display: grid; place-items: center; margin-bottom: 18px; background: var(--accent-subtle-bg); color: var(--accent-text); }
.feat__ic svg { width: 24px; height: 24px; }
.feat h3 { font-family: var(--font-display); font-size: var(--text-lg); font-weight: 600; margin-bottom: 8px; }
.feat p { font-size: var(--text-sm); color: var(--hearth-text-secondary); }
/* the product-line meta row (12-1b): what a line is sold as and metered on. Deliberately
   quieter than the summary — it is a fact about the contract, not the pitch. */
.feat__meta { margin-top: 12px; font-size: var(--text-xs); color: var(--hearth-text-tertiary, var(--hearth-text-secondary)); line-height: 1.6; }
.feat__meta b { font-weight: 650; color: var(--hearth-text-secondary); }

/* metric band */
.band { background: var(--hearth-surface); border-block: 1px solid var(--hearth-border); }
.band__in { display: grid; grid-template-columns: repeat(4, 1fr); }
.metric { padding: 40px 24px; text-align: center; border-left: 1px solid var(--hearth-border-subtle); }
.metric:first-child { border-left: 0; }
.metric .v { font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 600; letter-spacing: -.01em; color: var(--accent-text); }
.metric .k { font-size: var(--text-sm); color: var(--hearth-text-muted); margin-top: 6px; }

/* pricing */
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 22px; align-items: start; }
.plan { background: var(--hearth-surface); border: 1px solid var(--hearth-border); border-radius: var(--radius-2xl); padding: 28px; box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 14px; position: relative; }
.plan.feat-plan { border-color: var(--accent-border); box-shadow: var(--shadow-md); background: linear-gradient(180deg, var(--accent-subtle-bg), var(--hearth-surface) 36%); }
.plan__rib { position: absolute; top: -12px; left: 28px; font-size: var(--text-micro); font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #fff; background: var(--accent-solid-bg); padding: 4px 12px; border-radius: var(--radius-full); box-shadow: var(--shadow-sm); }
.plan__nm { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; }
.plan__tag { font-size: var(--text-sm); color: var(--hearth-text-muted); margin-top: -8px; }
.plan__price { font-family: var(--font-display); font-size: var(--text-3xl); font-weight: 600; display: flex; align-items: baseline; gap: 8px; padding-bottom: 14px; border-bottom: 1px solid var(--hearth-border-subtle); }
.plan__price span { font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 500; color: var(--hearth-text-muted); }
.plan__feats { display: flex; flex-direction: column; gap: 11px; flex: 1; }
.plan__f { display: flex; align-items: flex-start; gap: 9px; font-size: var(--text-sm); color: var(--hearth-text-secondary); line-height: 1.45; }
.plan__f svg { width: 16px; height: 16px; color: var(--accent-text); flex: none; margin-top: 2px; }

/* renew banner */
.renew { background: linear-gradient(135deg, var(--accent-subtle-bg), var(--hearth-surface)); border: 1px solid var(--accent-border); border-radius: var(--radius-2xl); padding: 32px; display: flex; align-items: center; gap: 24px; flex-wrap: wrap; box-shadow: var(--shadow-sm); }
/* `min(280px, 100%)`, never a bare 280px — see the phone tier at the foot of this file: the
   floor is a WRAP PREFERENCE (drop the CTA to its own row below 280) and must never become an
   overflow floor when the banner itself is narrower than 280. */
.renew__t { flex: 1; min-width: min(280px, 100%); }
.renew__t h3 { font-family: var(--font-display); font-size: var(--text-xl); font-weight: 600; }
.renew__t p { color: var(--hearth-text-secondary); margin-top: 6px; font-size: var(--text-base); }

/* docs/trust mini */
.mini { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 20px; }
.mini a { background: var(--hearth-surface); border: 1px solid var(--hearth-border); border-radius: var(--radius-xl); padding: 22px; display: flex; align-items: center; gap: 14px; transition: background .15s; }
.mini a:hover { background: var(--hearth-sunken); }
.mini .ic { width: 40px; height: 40px; border-radius: 11px; background: var(--hearth-sunken); color: var(--accent-text); display: grid; place-items: center; flex: none; }
.mini h4 { font-size: var(--text-base); font-weight: 600; } .mini p { font-size: var(--text-xs); color: var(--hearth-text-muted); }

/* footer */
footer { border-top: 1px solid var(--hearth-border); padding: 48px 0 36px; margin-top: 40px; }
.foot { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 30px 24px; }
/* The brand sits on its own row above the columns. It used to be the first
   track of a fixed 2fr-1fr-1fr-1fr grid, which fixed the footer at three link
   columns — and the 2026-09-02d IA has six. `auto-fill` lets the column count
   follow the content instead of the content following the grid. */
.foot__brand { grid-column: 1 / -1; }
.foot__brand .wm { font-size: var(--text-md); } .foot__brand p { font-size: var(--text-sm); color: var(--hearth-text-muted); margin-top: 12px; max-width: 30ch; }
.foot__col h5 { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: .08em; color: var(--hearth-text-muted); margin-bottom: 12px; }
.foot__col a { display: block; font-size: var(--text-sm); color: var(--hearth-text-secondary); padding: 4px 0; }
.foot__col a:hover { color: var(--hearth-text); }
.foot__base a { color: var(--hearth-text-muted); text-decoration: underline; text-underline-offset: 2px; }
.foot__base a:hover { color: var(--hearth-text); }
.foot__base { display: flex; align-items: center; gap: 12px; margin-top: 36px; padding-top: 20px; border-top: 1px solid var(--hearth-border-subtle); font-size: var(--text-xs); color: var(--hearth-text-muted); }

/* ---- checkout / provisioning / lead sheet ---------------------------------
   MOVED to site-sheet.css (2026-09-03e), so a page rendered from the design
   drop can host the same intake door without loading this whole stylesheet.
   Every page that links site.css links site-sheet.css beside it — the rules
   did not change, only which file holds them. Do not re-add them here. */

/* ---- §12 re-base additions (license-on-ingestion · all-apps-free) -------- */
/* hero pill eyebrow */
.eyebrow--pill { display: inline-flex; align-items: center; gap: 8px; padding: 7px 15px; border-radius: var(--radius-full); background: var(--hearth-surface); border: 1px solid var(--hearth-border); color: var(--accent-text); }
.eyebrow--pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--status-healthy-fg); flex: none; }

/* centered section heads + banded sections */
.sec-head--center { max-width: 62ch; margin-inline: auto; text-align: center; }
.sec-band { background: var(--hearth-surface); border-block: 1px solid var(--hearth-border); }

/* capabilities grid — 6 cards. The rigid `repeat(3, 1fr)` that used to live here is
   GONE, not moved: it would have overridden `.tri`'s auto-fit and quietly excluded this
   one grid from the two-up band above. `.tri` already lands on three columns at desktop
   and reflows on its own, so the modifier has nothing left to say about columns. */

/* pricing — ingestion ceiling subline */
.plan__sub { font-size: var(--text-xs); color: var(--hearth-text-muted); margin-top: -6px; }
.plans__note { text-align: center; margin-top: 24px; font-size: var(--text-sm); color: var(--hearth-text-secondary); }
.plans__note a { color: var(--accent-text); font-weight: 600; }
.plans__note a:hover { text-decoration: underline; }
/* live-pricing chip — shown by site-live.js only when the cards loaded from the live rate card
   (a calm, positive signal; we never flag "mock" on a marketing page). Modelled on .eyebrow--pill. */
.price-src { display: inline-flex; align-items: center; gap: 7px; margin-left: 12px; padding: 4px 11px; border-radius: var(--radius-full); background: var(--hearth-surface); border: 1px solid var(--hearth-border); font-family: var(--font-label, var(--font-mono)); font-size: var(--text-micro); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--status-healthy-fg); vertical-align: middle; }
.price-src__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--status-healthy-fg); flex: none; }

/* 12-3 · provision band (dark, self-serve handoff) */
.provision { background: var(--hearth-inverse-surface, #10202E); color: var(--hearth-inverse-text, #F3ECDF); border-radius: var(--radius-2xl); padding: 32px; display: flex; align-items: center; gap: 24px; flex-wrap: wrap; box-shadow: var(--shadow-md); }
.provision__t { flex: 1; min-width: min(300px, 100%); }
.provision__t h3 { font-size: var(--text-xl); margin: 8px 0 6px; color: inherit; }
.provision__t p { font-size: var(--text-sm); color: color-mix(in srgb, currentColor 78%, transparent); max-width: 56ch; line-height: 1.55; }
.provision__steps { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.provision__steps span { display: inline-flex; align-items: center; gap: 7px; font-size: var(--text-xs); font-weight: 600; padding: 7px 12px; border-radius: var(--radius-full); background: color-mix(in srgb, currentColor 9%, transparent); }
.provision__steps svg { opacity: .55; }
.provision .eyebrow { color: var(--viz-2, #3C6188) !important; }

/* 12-4 · trust regimes + cards */
.regimes { display: flex; flex-wrap: wrap; gap: 9px; margin-bottom: 26px; }
.regime { padding: 7px 14px; border-radius: var(--radius-full); background: var(--hearth-surface); border: 1px solid var(--hearth-border); font-size: var(--text-xs); font-weight: 600; color: var(--hearth-text-secondary); }
.trust-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 16px; }
.trust-card { background: var(--hearth-surface); border: 1px solid var(--hearth-border); border-radius: var(--radius-lg); padding: 18px 20px; }
.trust-card__h { font-size: var(--text-sm); font-weight: 700; color: var(--hearth-text); }
.trust-card__p { font-size: var(--text-sm); color: var(--hearth-text-muted); margin-top: 6px; line-height: 1.5; }

/* 12-5 · app listings + Console */
.apps { background: linear-gradient(135deg, var(--accent-subtle-bg), var(--hearth-surface)); border: 1px solid var(--accent-border); border-radius: var(--radius-2xl); padding: 32px; display: flex; align-items: center; justify-content: space-between; gap: 28px; flex-wrap: wrap; box-shadow: var(--shadow-sm); }
.apps__t { min-width: min(280px, 100%); flex: 1; }
.apps__t h3 { font-size: var(--text-xl); margin: 8px 0 6px; }
.apps__t p { font-size: var(--text-sm); color: var(--hearth-text-secondary); max-width: 52ch; line-height: 1.55; }
.apps__cta { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.store { display: inline-flex; align-items: center; gap: 10px; padding: 11px 18px; border-radius: var(--radius-lg); background: var(--hearth-text); color: var(--hearth-canvas); }
.store:hover { filter: brightness(1.08); }
.store span { display: flex; flex-direction: column; line-height: 1.1; }
.store i { font-size: var(--text-micro); opacity: .7; font-style: normal; text-transform: uppercase; letter-spacing: .04em; }
.store b { font-size: var(--text-sm); font-weight: 700; }

@media (max-width: 920px) {
  /* The five card grids are no longer listed here — they size themselves (see the
     auto-fit block above). Removing them also retires a dead rule this tier had been
     carrying: `.trust-grid` was set to `1fr` on the first line and `1fr 1fr` on the
     last, so the first declaration had never once applied. */
  .hero__in { grid-template-columns: 1fr; }
  .band__in { grid-template-columns: 1fr 1fr; } .metric:nth-child(3) { border-left: 0; }
  .foot { grid-template-columns: 1fr 1fr; }
  /* `.nav__links{display:none}` and the CTA's auto margin at this tier are in
     `site-nav.css` now, stated once for both halves of the site. */
}

/* ---------------------------------------------------------------------------
   PHONES. Reported 2026-08-13 against a 360 px Android: the page scrolled
   sideways and #trust's provision card ran its own text past its rounded right
   edge, where the viewport then clipped it mid-word.

   The 920 tier above is a TABLET breakpoint — it collapses the multi-column
   grids and stops. Everything below it was still sized for a >= 768 canvas:
   28 px page gutters, 32 px card padding and 280/300 px flex floors, which on a
   360 px screen add up to more than the screen. Two rules hold from here down:

     · no fixed length may exceed the narrowest supported viewport (320 px), and
     · a "wrap when the line is narrower than X" floor is written `min(X, 100%)`
       so it stays a PREFERENCE and never becomes an overflow floor when the
       container itself is narrower than X. (That one `min()` is the whole fix
       for the reported card; the rest of this block is what makes the result
       look deliberate rather than merely un-clipped.)

   Verified with the measurement in this session's log: documentElement
   .scrollWidth == clientWidth at 320 / 360 / 412 on every page of this site.
   --------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .wrap { padding: 0 18px; }

  /* nav — the brand may wrap to two lines (it already does); what it may not do
     is hold a fixed width the CTA cluster then pushes off-screen.
     `.nav__in`'s padding at this tier moved to `site-nav.css` with the rest of
     the shared geometry; only the brand's own rules stay. */
  .nav__brand { min-width: 0; gap: 9px; }
  .nav__brand .mark, .nav__brand .mark svg { width: 30px; height: 30px; }
  .nav__brand .wm { font-size: var(--text-base); letter-spacing: .14em; }
  /* the CTA's own tightening at this tier is in `site-nav.css`, for both halves */

  .hero { padding: 46px 0 32px; }
  .hero .lede { font-size: var(--text-md); }

  /* the three wide banner cards: 32 px of padding on each side of a 324 px line
     leaves 260 px of text column, so it comes down with the viewport. */
  .provision, .renew, .apps { padding: 24px 20px; }
  /* Steps down a real rung. Before the type pass this was 26px -> 22px; snapping both
     ends to the nearest scale step would have landed them BOTH on --text-xl and quietly
     deleted the phone step-down, which the 560 tier above exists to provide. Caught only
     by expanding grouped selectors before comparing — keyed on the selector STRING, the
     grouped rule here and the individual rules at 340/358 read as different selectors. */
  .provision__t h3, .apps__t h3 { font-size: var(--text-lg); }
  .renew__t h3 { font-size: var(--text-lg); }

  .metric { padding: 26px 12px; }
  .metric .v { font-size: var(--text-2xl); }
  .metric .k { font-size: var(--text-xs); }

  /* two 130 px columns cannot carry a sentence — the trust cards go single-file
     (the 920 tier's 1fr 1fr is a tablet shape, not a phone one). */
  .trust-grid { grid-template-columns: 1fr; }

  .foot { gap: 22px; }
  .foot__base { flex-wrap: wrap; }
}

/* Small phones (320-400: iPhone SE, Android compact). Only the nav still needs
   room here — everything else above already fits. */
@media (max-width: 400px) {
  .nav__brand .wm { font-size: var(--text-sm); letter-spacing: .12em; }
  /* ditto — `site-nav.css` */
}

/* ---- 12-3b · PROOF band (index #proof) --------------------------------------
   The assurance plane's front door. No entrance animation and no opacity:0 base:
   the visible state IS the base state, so print, PDF, the preview verifier and a
   reduced-motion reader all get the numbers rather than a blank band. */
.pv-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin:6px 0 14px}
.pv-stat{border:1px solid var(--hearth-border);border-radius:14px;padding:16px;background:var(--hearth-raised,#fff)}
.pv-stat b{display:block;font-family:var(--font-mono,'JetBrains Mono',monospace);font-variant-numeric:tabular-nums;font-size: var(--text-xl);line-height:1.1}
.pv-stat span{display:block;font-size: var(--text-xs);color:var(--hearth-text-muted);margin-top:6px;line-height:1.45}
.pv-note{font-size: var(--text-xs);color:var(--hearth-text-muted);line-height:1.6;max-width:82ch}

/* ---- .pghead — the page header the four promoted pages carry ---------------
   The 2026-08-23 IA restructure moved Platform, Pricing, Trust and Apps out of the
   homepage onto pages of their own. Off the homepage they no longer sit under the
   hero, so each needs its own opening — and the site had no shared one: security.html
   and resources.html had each grown a private `.se-head` / `.rx-head` instead. This is
   that pattern, named once, so the fifth page does not invent a sixth spelling.

   Used by apps.html ONLY. The other three promoted pages open with a moved section that
   already carried a complete `.sec-head`, so they promote THAT h2 to h1 rather than
   stacking a second heading above it that says the same thing in different words.

   No entrance animation: the never-blank rule (site-motion.css) applies to the element
   that carries a page's first words more than to anything else on it. */
.pghead { padding: 64px 0 8px; }
.pghead .eyebrow { display: block; margin-bottom: 10px; }
.pghead h1 { font-family: var(--font-display); font-size: clamp(30px, 4.4vw, 46px);
             line-height: 1.08; letter-spacing: -.02em; margin: 0 0 12px; }
.pghead p { color: var(--hearth-text-secondary); max-width: 62ch; font-size: var(--text-base); line-height: 1.6; }
@media (max-width: 720px) { .pghead { padding: 40px 0 4px; } }

/* The nav's current page is marked in `site-nav.css`, for both halves at once. */

/* ---- Skip link (2026-08-23) --------------------------------------------------------------
   Hidden until focused, then it lands over the masthead. NOT `display:none` and NOT
   `visibility:hidden` — both remove it from the accessibility tree and from the tab order, which
   is the one thing it exists to be in. The canonical clip-path recipe keeps it focusable while
   taking it out of the visual flow.

   `top` animates rather than `opacity`, so the never-blank rule cannot bite: the element's
   visible end-state is its base style and nothing here starts at opacity 0. */
/* `.skip-link` and its focus target moved to `site-nav.css` (2026-09-03), which
   BOTH halves of the site load. The generated pages had been carrying their own
   copy inline — `position:absolute; left:-9999px` plus a lifted `:focus` rule,
   and on the homepage in a different colour than on the other fourteen — so the
   site shipped two skip links that behaved and looked differently. This one is
   the better of the two (clip-path stays in the a11y tree where an off-screen
   left:-9999px does not), so it is the one that survives. */

