/* ============================================================================
   bto-type.css — THE ABOUT PAGE'S TYPE + MEASURE SYSTEM

   This is the ROLLOUT of svc-type.css (bto-spylt/src/svc-type.css) onto the
   static pages. That file's header says why it was scoped to `.svc-page`:
   "for right now we will work on the services pages and then we will do the
   rest on the other pages as well." This is the "rest of the pages" half.

   FOUNDER, 2026-08-06: "the about section doesn't look like our website ...
   use the exact background font in every style that our website has."

   ── THE ROOT CAUSE, AND IT IS NOT THAT SOMEONE STYLED IT BADLY ────────────
   site-unify.css was written to make the static pages match the services page,
   and its own header records the target it measured:

       THREE faces, each with one job:
         Antonio       display + card interiors + micro-tags   (61 nodes)
         ProximaNova   body prose only                         (51 nodes)
         Neue Montreal chrome only — logo, nav, buttons        (10 nodes)

   That was the services page BEFORE 2026-08-06. svc-type.css then cut services
   to TWO faces and retired ProximaNova outright ("it duplicates what Neue
   Montreal already does, and Neue Montreal adds a real Bold that ProximaNova
   has no file for"). About never got that pass, so it is faithfully matching a
   services page that no longer exists. The page is not wrong; it is STALE.

   ── WHAT WAS ACTUALLY MEASURED (live DOM, 1440x900, both pages, not guessed)
                          SERVICES (target)        ABOUT (before)
     families             2  Antonio 81 / NM 289   5  NM 174 · ProximaNova 51 ·
                                                      Antonio 33 · Archivo 6 ·
                                                      Times 2
     shell                1320 @ 60px gutter       1350 @ 0 — and the header bar
                          (9 wrappers agree)       is 1320, so chrome and body
                                                   disagreed by 30px
     h1                   72px / lh 1.02           90px / lh 0.95
     section head         40px                     51.84px
     measure ceiling      34.0em, hard             67–82em in the timeline

   🐛 THE FIRST READ OF THE MEASURE WAS WRONG AND THE MISTAKE IS WORTH KEEPING.
   The first census reported "412 characters" on a bare <p> and called it the
   worst number on the page. That was the paragraph's TOTAL CHARACTER COUNT, not
   its line length — a 412-character paragraph inside a 34em column is perfectly
   readable, and `.bto-prose p` measured 34.1em, i.e. already correct. Measure is
   BOX WIDTH / FONT-SIZE and nothing else. Re-measured that way, the body copy
   was fine and the real blowout was somewhere else entirely:

       82.0em  .bto-tl__kicker      1076px @ 13.12px
       70.8em  li                   1076px @ 15.2px
       67.3em  .bto-tl__lead        1076px @ 16px
       43.0em  .bto-tl__title       1076px @ 25px
       38.4em  .bto-support          692px @ 18px   (mild)
       37.2em  .bto-static__lead     744px @ 20px   (mild)

   Every one of the four TOO-WIDE rows is inside #about-journey — the timeline.
   Capping the prose (the obvious-looking fix) would have changed nothing that
   was broken and broken something that was fine.

   ── WHAT THIS FILE DOES NOT DO ────────────────────────────────────────────
   ⚠ IT TOUCHES NO COLOUR. The grounds already match services exactly —
   #F0EEEB canvas · #13181B ink · #CCD5DA panel — and `.bto-panel::before`
   (bto-static.css:228) bleeds them edge to edge from `inset: 0 calc(50% - 50vw)`,
   which is relative to the panel's own box and therefore SURVIVES the shell
   change from 1350 to 1320. Verified, not assumed.
   ⚠ Services also runs a navy #003A6C ground that About has none of. NOT
   introduced here: there is no navy token — #003A6C is what `--bg-inset-dark`
   BECOMES in dark theme, so hardcoding it as a ground breaks the theme toggle.
   That is a founder call, not a rollout detail.
   ⚠ It touches no copy, no markup, and no other sheet. Purely additive.

   SCOPE: `body.bto-static`, which is on About, Contact, Founder and Work. Only
   about.html links this file today, so the other three are untouched until
   their <link> is added — that is the opt-in, and it is deliberate.

   LOAD ORDER: LAST in about.html, after bto-footer.css.
   ⚠ NOT wrapped in @layer, on purpose — it has to outrank the Mokko theme
   (mokko/assets/css/style.css) and bootstrap regardless of specificity.

   ⚠ EVERY SELECTOR BELOW IS PREFIXED `body.bto-static` RATHER THAN
   `.bto-static`. That is not stylistic. The incumbents were resolved with CDP
   getMatchedStylesForNode (site-unify.css's own header records that reading the
   cascade off source instead of the live match lost it three separate times),
   and several of them already carry an element in the chain:
       .page-header__title   <- `body .page-header-content .page-header__title`  (0,2,1)
       .content__title       <- `.bto-static .bto-panel.bto-static__sec .content__title` (0,4,0)
       .bto-tl__year         <- `.bto-static .bto-tl .bto-tl__year`              (0,3,0)
   The `body` element bumps each rule below one notch past its incumbent without
   a single !important. Match the chain, don't out-shout it.
   ========================================================================== */

/* ══ 1. TOKENS — values copied verbatim from svc-type.css ═══════════════════
   This is a rollout, not a redesign. If a number here ever disagrees with
   svc-type.css, svc-type.css is right and this file is stale. */
body.bto-static {
  --bto-display: "Antonio", "Archivo", sans-serif;
  --bto-text: "Neue Montreal", "Archivo", system-ui, -apple-system, sans-serif;

  /* measure in em, NOT ch. `ch` is the advance width of the ZERO GLYPH, which
     in Neue Montreal is far wider than its average lowercase letter: 68ch
     computed to 674px and rendered 88 REAL characters while every number in the
     stylesheet said the cap was applied. ~2 characters per em holds across our
     faces, so 34em ≈ 68 characters at any size. This trap has now bitten in
     svc-read.css, twice in svc-type.css, and — see §5 — twice more on THIS
     page, where `.bto-support` was capped at 62ch and `.bto-static__lead` at
     60ch and both still ran wide. */
  --bto-measure: 34em;         /* ≈ 68 characters */
  --bto-measure-tight: 27em;   /* ≈ 54, for copy in a half-width column */

  /* the shell. 1320 + 60 is not an imported number — it is OUR header bar
     (bto-header.css:64) and OUR footer's --bf-max, which already agreed with
     each other while the body ran 1350 at zero gutter. Matching the chrome we
     have beats importing a number we do not. */
  --bto-shell: 1320px;
  --bto-gutter: clamp(20px, 4.2vw, 60px);

  /* the body ramp. Floors, not fixed sizes — the existing clamp() values still
     drive the scaling, they just cannot land below what is readable. */
  --bto-body: clamp(15px, 1.05vw, 16px);
  --bto-body-sm: clamp(14px, .95vw, 15px);
  --bto-lh: 1.65;

  /* the five-step ladder, ratio ~1.35, topping at 72px — the founder's pick
     over 56 and 88 when this was settled on services. */
  --d1: clamp(38px, 5vw, 72px);
  --d2: clamp(32px, 3.9vw, 54px);
  --d3: clamp(26px, 2.9vw, 40px);
  --d4: clamp(20px, 2vw, 28px);
  --d5: clamp(16px, 1.5vw, 20px);

  /* 🔴 RETIRE ProximaNova BY REPOINTING site-unify.css's OWN TOKEN (:70),
     not by chasing the 51 nodes that wear it. Exactly the move svc-type.css
     made with --font-paragraph: redefining the property catches every rule that
     consumes it, including the ones a class-level sweep would miss. The
     @font-face at site-unify.css:95 stays declared and simply stops being
     asked for — harmless, and it keeps Contact/Founder/Work rendering exactly
     as they do today until they opt in. */
  --u-prose: "Neue Montreal", "Archivo", system-ui, -apple-system, sans-serif;
}

/* ══ 2. THE BASE FACE ═══════════════════════════════════════════════════════
   The single highest-leverage rule in the file, same as svc-type.css §1.
   Elements that NAME a face explicitly are unaffected and stay display. */
body.bto-static,
body.bto-static input,
body.bto-static button,
body.bto-static textarea,
body.bto-static select { font-family: var(--bto-text); }

/* <html> carried NO font-family at all and computed to **Times**. Nothing
   visible inherits from it (body sets its own), so this is belt-and-braces
   against any future element that lands outside <body>'s subtree — and it makes
   the page's default face greppable instead of a browser fallback.
   `:has()` is already relied on in bto-static.css:258, so the support floor is
   unchanged. Scoped so the locked pages cannot be reached. */
html:has(body.bto-static) { font-family: var(--bto-text); }

/* ══ 3. DISPLAY STAYS ANTONIO ═══════════════════════════════════════════════
   Most of these already name Antonio in their own sheets; this block exists so
   the intent is greppable in ONE place and so a future change edits the token
   rather than six literals. The two that are NOT redundant:

   🔴 `.bto-tl__year` resolved to `var(--font-display, inherit)`
      (bto-about.css:293) and computed to **Archivo** — a fifth family, on a
      48px display numeral, on the one section of the page that is 100%
      placeholder copy. It is display register; it wears the display face.
   🔴 `.bto-stat__amount` computed `inherit`, i.e. it was a 43px display numeral
      running in the body face by accident rather than by choice. */
body.bto-static .page-header__title,
body.bto-static .content__title,
body.bto-static .svc-sec-eyebrow,
body.bto-static .bto-tl .bto-tl__year,
body.bto-static .bto-stat__amount,
body.bto-static .p2-cta { font-family: var(--bto-display); }

/* ══ 4. THE HEADING LADDER ══════════════════════════════════════════════════
   About carried 90 · 51.84 · 48 · 43.2 · 25 with no relationship between them.
   Services runs five steps that do relate. Same ladder, same line-heights.

   ⚠ LINE-HEIGHT MOVES WITH THE SIZE, ALWAYS. The h1's incumbent lh was 0.95,
   set for 90px type. Left alone at 72px it opens a gap the lockup cannot hold.
   Every rung below names its own.

   ⚠ `.bto-slab` (the amber slab word inside the heads) is DELIBERATELY ABSENT.
   CDP resolves its font-size to `inherit ← *`, so it already follows whichever
   head contains it and moves 90→72 and 51.84→40 for free. svc-type.css §8 had
   to name its descendants because THOSE carried their own size class; this one
   does not, and naming it would only risk pinning a child to the wrong rung. */

/* the hero. Incumbent: `.page-header-content .page-header__title` 90px (0,2,0)
   + `body .page-header-content .page-header__title` lh .95 (0,2,1). */
body.bto-static .page-header-content .page-header__title {
  font-size: var(--d1);
  line-height: 1.02;
}

/* the ten section heads. Incumbent:
   `.bto-static .bto-panel.bto-static__sec .content__title` clamp(34px,3.6vw,62px)
   / lh .94 (0,4,0). At 1440 that resolved to 51.84px against services' 40. */
body.bto-static .bto-panel.bto-static__sec .content__title {
  font-size: var(--d3);
  line-height: 1.12;
}

/* `.bto-bigstate` is A9's deliberate one-off "big statement" head ("Why there
   is no client list here."). It stays BIGGER than a normal section head — that
   was the point of it — but it becomes a RUNG (d2, 54px) instead of an
   unrelated number. Specificity (0,5,1) clears its own incumbents at
   bto-about.css:79/91/99, including the two inside media queries; it is listed
   after the general rule above so it also wins the tie on order. */
body.bto-static .bto-panel.bto-static__sec .content__title.bto-bigstate {
  font-size: var(--d2);
  line-height: 1.06;
}

/* the two display NUMERALS. Both are large, both anchor a scannable block, and
   both were off-ladder — the year at clamp(2rem,3.4vw,3rem) = 48px, the stat at
   clamp(28px,3vw,44px) = 43.2px. Same rung so a "2023" and a "1,400" read as
   the same kind of object, which they are. */
body.bto-static .bto-tl .bto-tl__year,
body.bto-static .bto-stat__amount {
  font-size: var(--d3);
  line-height: 1;
}

/* the timeline entry heads. Incumbent was the bare `h3, .text-lg` theme rule at
   var(--text-lg, 1.44em) = 25px, i.e. it had no rule of its own at all. Note
   this rung goes UP, 25 → 28: it is the only size on the page that increases,
   because a 43em-wide 25px heading was reading as body copy rather than a head.
   The measure cap in §5 is what makes that legible; the size alone would not. */
body.bto-static .bto-tl .bto-tl__title {
  font-size: var(--d4);
  line-height: 1.18;
}

/* ══ 5. THE READABILITY FLOOR ═══════════════════════════════════════════════
   `max()` floors, never fixed sizes, so anything already larger is untouched
   and the existing clamps keep scaling. Reading copy only — see the carve-out.

   🔴 THE FIRST VERSION OF THIS RULE INFLATED THE MICRO-TAGS AND IT SHIPPED
   BEFORE THE PROBE CAUGHT IT. `.bto-tl__pill` went 10.88px → 16px and
   `.bto-tl__kicker` 13.12px → 16px. Both are UPPERCASE with real tracking
   (2.56px and 4.48px) — they are labels, not sentences, and svc-type.css §4
   had already made exactly this carve-out for `.svw-screen-k`: "a genuine
   uppercase .16em-tracked label, which is the one small size condensed type
   still does well". A floor is for copy you READ; a tag you SCAN does not get
   one. `.bto-tl__chip` is excluded on the same grounds (14.4px, a tag).

   🔴 AND THE FLOOR BOOTSTRAPPED ITSELF. `max(var(--bto-body), 1em)` resolves
   `1em` against the PARENT's font-size — and §4/§5 of this very sheet had just
   enlarged those parents, so the "floor" read the new inherited size and
   climbed to meet it. That is why the kicker landed on 16px rather than the
   15px `--bto-body-sm` it was nominally given. `1em` inside max() is only safe
   when nothing in the same sheet moves the ancestor; here it was not. Anything
   that must hold a small size is now simply LEFT ALONE rather than floored. */
body.bto-static .bto-tl .bto-tl__lead,
body.bto-static .bto-static__sec li:not(.bto-tl__pill):not(.bto-tl__chip):not(.bto-tl__item) {
  font-size: max(var(--bto-body), 1em);
  line-height: var(--bto-lh);
}

/* ⚠ `.bto-tl__kicker`, `.bto-tl__pill` and `.bto-tl__chip` deliberately get NO
   size rule — only the measure cap in §6. They keep 13.12 / 10.88 / 14.4px. */

/* ══ 6. THE MEASURE CAP ═════════════════════════════════════════════════════
   The actual fix. Every row below ran 37–82em against services' hard 34.0em
   ceiling, and all four of the worst are in #about-journey, the timeline.

   🔴 TWO OF THESE WERE ALREADY "CAPPED" AND STILL RAN WIDE — `.bto-support` at
   62ch measured 38.4em and `.bto-static__lead` at 60ch measured 37.2em. That is
   the ch-vs-em trap firing for the fourth and fifth time in this codebase, on a
   page where nobody had noticed because the numbers in the source looked
   deliberate. em is the honest unit; see the token block.

   ⚠ `margin-inline: auto` IS NOT SET HERE, deliberately. On services that line
   flipped a grid item from `stretch` to shrink-to-fit and collapsed a column
   900px → 500px, which then broke a headline mid-word ("WE BUILD T / HEM.").
   These blocks keep whatever alignment their parent already gives them; a cap
   alone cannot move a track. If one of them ever needs centring it also needs
   an explicit `width: 100%` — see svc-type.css §9, which paid for that line
   three separate times. */
/* 🔴 `.bto-tl__item` IS EXCLUDED AND MUST STAY EXCLUDED. It looks like a list
   item and it is the timeline CARD — the bordered box that holds a whole
   entry. The first version of this rule capped it at 34em, which is 544px, and
   the card collapsed from filling its column to just over half the dark panel,
   leaving the right half of the section empty. Caught in the screenshot pass,
   not in the numbers: every measure reading came back green because the TEXT
   was fine — it was the container that had been shrunk under it.

   Same class of mistake as `.sva-proc-col` in svc-type.css §6, and the same
   tell: a measure cap belongs on a LINE OF TYPE, never on a box that holds a
   layout. The bullets inside the card are bare `li` in `ul.bto-tl__notes` and
   those are what the cap is actually for. */
body.bto-static .bto-tl .bto-tl__title,
body.bto-static .bto-tl .bto-tl__lead,
body.bto-static .bto-tl .bto-tl__kicker,
body.bto-static .bto-static__sec li:not(.bto-tl__item),
body.bto-static .bto-support,
body.bto-static .bto-static__lead {
  max-width: var(--bto-measure);
}

/* ⚠ These are capped by a `header *, main *, footer *` theme rule resolving to
   `var(--global--spacing-measure)` — an UNDEFINED custom property, so it
   computes to `none`. It looks like a measure system and is inert. Noted so the
   next person does not go looking for where it is set. */

/* ══ 7. THE SHELL ═══════════════════════════════════════════════════════════
   One width down the page, matching the chrome. Both `.container` instances in
   about.html (the hero at :174 and the body at :180) are plain block wrappers —
   neither is a grid or flex track, checked before this rule was written. The
   header and footer carry their own max-width in their own self-contained
   sheets and contain no `.container`, so they are out of reach here.

   ⚠ THE COLOURED GROUNDS STAY FULL-BLEED. `.bto-panel::before` uses
   `inset: 0 calc(50% - 50vw)`, which is measured from the panel's own box — at
   1320 it resolves to -60px per side and still reaches both viewport edges.
   Narrowing the container narrows the COPY, not the colour. */
body.bto-static .container {
  max-width: var(--bto-shell);
  margin-inline: auto;
  padding-inline: var(--bto-gutter);
}

@media (prefers-reduced-motion: reduce) {
  body.bto-static { scroll-behavior: auto; }
}
