/* ==========================================================================
   bto-static.css — body rhythm for the two NEW static pages (about, contact).
   Loaded ONLY by about.html and contact.html, after panel-fixes.css and before
   palette.css, so palette still lands last exactly as it does on work.html.

   RULES THIS FILE FOLLOWS, deliberately:
   · ZERO new colour values. Every colour is an existing token from palette.css
     (--fg-ink / --fg-lead / --fg-body / --fg-mute / --bg-hairline / --accent-base).
     Nothing here invents a hue, and nothing re-declares what a token already does.
   · ZERO !important.
   · Section heads reuse the site's OWN component (.ms-ah-wrapper.custom-style2 +
     .content__title.hero-title.title.up-text) as used on site/index.html, rather
     than a new heading system.
   · Everything is scoped under .bto-static so it cannot reach the locked pages.

   This is spacing and measure only — the typographic scale, the faces and the
   palette all come from the locked system. Layout art direction for these two
   pages (imagery, panel treatment, the close) is still the Creative Director's,
   and is deliberately NOT invented here.
   ========================================================================== */

.bto-static .bto-static__body { padding: 0 0 8vh; }

/* --- page opening ------------------------------------------------------- */
/* MEASURED 2026-08-02: the sticky header bar's bottom edge is y=80 (desktop) /
   y=66 (≤575). work.html's own h1 starts at y=54, i.e. the locked page already
   runs its title under the header — a pre-existing defect, reported, NOT fixed
   here because work.html is locked. These two pages add an eyebrow ABOVE the
   h1, which would put an unreadable line fully under the bar, so they clear it.
   Scoped to .bto-static, so work.html is untouched. */
.bto-static .page-header-content { padding-top: 104px; }
.bto-static .page-header-content .bto-eyebrow { margin: 0 0 10px; }

@media (max-width: 575px) {
  .bto-static .page-header-content { padding-top: 88px; }
}

/* The H1 is Antonio 90px from the locked system. It is set in two lines by an
   explicit <br> because the copy was written to split (Editorial A1). */
.bto-static .page-header__title { max-width: 20ch; }

.bto-static .bto-static__lead {
  max-width: 60ch;
  margin: 26px 0 0;
  font-size: 20px;
  line-height: 1.55;
  color: var(--fg-lead);
}

/* --- sections ----------------------------------------------------------- */
.bto-static .bto-static__sec {
  padding: 7vh 0 0;
  border-top: 1px solid var(--bg-hairline);
  margin-top: 7vh;
}
.bto-static .bto-static__sec:first-of-type { border-top: 0; }

.bto-static .bto-prose { max-width: 62ch; }
.bto-static .bto-prose p {
  margin: 0 0 18px;
  font-size: 18px;
  line-height: 1.6;
  color: var(--fg-body);
}
.bto-static .bto-prose p:last-child { margin-bottom: 0; }

.bto-static .bto-support {
  max-width: 62ch;
  margin: 0 0 28px;
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-lead);
}

/* --- labelled rows (About: who is on it · what we don't take on) --------- */
.bto-static .bto-rows { margin: 0; padding: 0; list-style: none; max-width: 74ch; }
.bto-static .bto-rows > li {
  padding: 20px 0;
  border-top: 1px solid var(--bg-hairline);
  display: grid;
  grid-template-columns: 15rem 1fr;
  gap: 24px;
}
.bto-static .bto-rows > li:last-child { border-bottom: 1px solid var(--bg-hairline); }
.bto-static .bto-row__label {
  margin: 0;
  font-size: 15px;
  line-height: 1.4;
  color: var(--fg-ink);
  font-weight: 600;
}
.bto-static .bto-row__line {
  margin: 0;
  font-size: 17px;
  line-height: 1.55;
  color: var(--fg-body);
}

/* --- the record: five file counts --------------------------------------- */
/* NO `ch` MAX-WIDTH HERE, deliberately. `ch` resolves against the ELEMENT'S OWN
   font-size — this wrapper inherits body size, not the 44px numerals inside it,
   so `max-width: 78ch` silently bound the row to ~773px. MEASURED: that gave
   135.5px columns while `~50,000` needs 167.4px of advance width, overflowing by
   31.9px and running two figures together at 1440. The row is a data band, not
   prose; it takes the container. Measured with Range.getBoundingClientRect(),
   not by eye — block width is NOT text width. */
.bto-static .bto-stats {
  margin: 0 0 26px;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 24px;
}
.bto-static .bto-stats > li { border-top: 2px solid var(--fg-ink); padding-top: 14px; }
.bto-static .bto-stat__amount {
  margin: 0 0 6px;
  font-size: clamp(28px, 3vw, 44px);
  line-height: 1;
  color: var(--fg-ink);
  font-weight: 700;
}
.bto-static .bto-stat__label {
  margin: 0;
  font-size: 14px;
  line-height: 1.35;
  color: var(--fg-mute);
}

/* --- numbered steps (Contact: what happens next) ------------------------- */
.bto-static .bto-steps { margin: 0; padding: 0; list-style: none; max-width: 70ch; counter-reset: s; }
.bto-static .bto-steps > li {
  padding: 20px 0;
  border-top: 1px solid var(--bg-hairline);
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 20px;
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-body);
}
.bto-static .bto-steps > li:last-child { border-bottom: 1px solid var(--bg-hairline); }
.bto-static .bto-step__n { color: var(--fg-mute); font-variant-numeric: tabular-nums; }

/* --- plain checklist (Contact: what to send) ----------------------------- */
.bto-static .bto-list { margin: 0 0 22px; padding: 0; list-style: none; max-width: 64ch; }
.bto-static .bto-list > li {
  padding: 14px 0;
  border-top: 1px solid var(--bg-hairline);
  font-size: 18px;
  line-height: 1.55;
  color: var(--fg-body);
}
.bto-static .bto-list > li:last-child { border-bottom: 1px solid var(--bg-hairline); }

/* --- the email, large (Contact) — no form is shipped, see the page note --- */
.bto-static .bto-mail {
  display: inline-block;
  margin: 6px 0 0;
  font-size: clamp(28px, 4vw, 56px);
  line-height: 1.05;
  color: var(--fg-ink);
  text-decoration: none;
  border-bottom: 2px solid var(--bg-hairline);
}
.bto-static .bto-mail:hover,
.bto-static .bto-mail:focus-visible { border-bottom-color: var(--accent-base); }

/* --- links + close ------------------------------------------------------ */
.bto-static .bto-static__link {
  display: inline-block;
  margin-top: 22px;
  font-size: 17px;
  color: var(--fg-ink);
  text-decoration: none;
  border-bottom: 1px solid var(--bg-hairline);
  padding-bottom: 2px;
}
.bto-static .bto-static__link:hover,
.bto-static .bto-static__link:focus-visible { border-bottom-color: var(--accent-base); }

.bto-static .bto-static__ctas { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }

/* A [FOUNDER TO FILL] blank is marked in the page so it cannot ship unseen.
   Uses the existing accent token — no new colour. */
.bto-static .bto-blank {
  background: var(--accent-base);
  color: var(--fg-on-accent, #13181B);
  padding: 0 .28em;
  border-radius: 2px;
  font-style: normal;
}

@media (max-width: 991px) {
  .bto-static .bto-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bto-static .bto-rows > li { grid-template-columns: 1fr; gap: 8px; }
}
@media (max-width: 575px) {
  .bto-static .bto-stats { grid-template-columns: 1fr; }
  .bto-static .bto-steps > li { grid-template-columns: 3rem 1fr; }
}


/* ==========================================================================
   §B · SHARED FOUNDATION — appended 2026-08-05 (Creative Designer, round 1).

   Source: the Creative Director's build spec, section B, as amended by founder
   decision D-4. Everything below is ADDITIVE and INERT: not one rule fires
   until a page opts in with a class it does not carry today. about.html and
   contact.html render byte-identically to before this block existed — verified
   by QA, not assumed.

   The three contracts stated at the top of this file are held throughout:
     · ZERO new colour values — 16 palette tokens, no hex literal in any rule
     · ZERO !important
     · everything scoped under .bto-static, so the locked pages cannot be reached

   Two curves only, per design-system §4b: cubic-bezier(.2,.7,.2,1) and ease.
   ========================================================================== */

/* --- GROUND BLOCKING — the fix for design-system §7 gap 1 ----------------- */
/* Full-bleed grounds inside a 1350px container: the section paints edge to
   edge, the content stays on the spine. */
.bto-static .bto-panel {
  position: relative;
  padding-block: clamp(88px, 9.6vh, 116px) clamp(56px, 7vh, 96px);
}
.bto-static .bto-panel::before {
  content: "";
  position: absolute;
  inset: 0 calc(50% - 50vw);
  z-index: -1;
  background: inherit;
}

/* OVERFLOW GUARD — load-bearing, do not "tidy" this away.
   The ::before above is absolutely positioned and reaches past the container to
   both viewport edges. Right-side overhang of an abspos box DOES create
   scrollable overflow, and `50vw` counts the scrollbar gutter while `50%` does
   not — so on any platform with a classic scrollbar the bleed overshoots and
   the page gains a horizontal scroll. That is a QA failure.

   `overflow-x: clip` is the correct guard and `overflow-x: hidden` is NOT.
   `hidden` makes the element a scroll container, which re-parents every
   `position: sticky` descendant to it — and the static hero pin is native
   sticky (see bto-js/no-smoother.js for the same bug from the other direction).
   `clip` clips without establishing a scroll container, so sticky survives.
   Paired with `overflow-y: visible` explicitly so neither axis is coerced.

   GATED ON :has(.bto-panel), NOT applied outright. `.bto-static` sits on
   <body>, and a non-visible overflow on <body> PROPAGATES to the viewport when
   <html> is visible — a global change to the page's scroll behaviour. That is
   not an inert addition, so it must not fire on a page that ships no bleeding
   panel. With the gate it engages the moment a page adopts ground blocking and
   is silent until then. If :has() were ever unsupported the guard simply does
   not apply: the failure direction is a possible horizontal scrollbar, never
   hidden content. */
.bto-static:has(.bto-panel) {
  overflow-x: clip;
  overflow-y: visible;
}

.bto-static .bto-panel--canvas { background: var(--bg-canvas); }
.bto-static .bto-panel--panel  { background: var(--bg-panel2); }
.bto-static .bto-panel--dark   { background: var(--bg-inset-dark); color: var(--fg-on-dark); }

.bto-static .bto-panel--dark .content__title,
.bto-static .bto-panel--dark .svc-sec-head { color: var(--fg-on-dark); }
.bto-static .bto-panel--dark p,
.bto-static .bto-panel--dark .bto-row__line,
.bto-static .bto-panel--dark .bto-stat__label { color: var(--fg-on-dark-mute); }
.bto-static .bto-panel--dark .svc-sec-eyebrow { color: var(--fill-accent); }
.bto-static .bto-panel--dark .bto-stats { border-top-color: var(--fg-on-dark); }
.bto-static .bto-panel--dark .bto-stats > li { border-top-color: var(--fg-on-dark); }
.bto-static .bto-panel--dark .bto-stat__amount { color: var(--fg-on-dark); }
.bto-static .bto-panel--dark a { color: var(--fg-on-dark); }

/* A section that ships a ground supplies its own rhythm — kill the inherited
   hairline so we do not draw a rule between two coloured panels. */
.bto-static .bto-panel.bto-static__sec {
  border-top: 0;
  margin-top: 0;
  padding-top: clamp(88px, 9.6vh, 116px);
}

/* --- THE SLAB — design-system §4a, the signature device ------------------- */
/* -3deg is the site's ONLY rotation value (site-unify.css:44).
   Law: exactly ONE word per major heading. Never two, never a phrase. */
.bto-static .bto-slab {
  display: inline-block;
  padding: .04em .2em .1em;
  background: var(--fill-accent);
  color: var(--fg-on-accent);
  -webkit-text-fill-color: var(--fg-on-accent);
  border-radius: 0;
  transform: rotate(-3deg);
  -webkit-box-decoration-break: clone;
          box-decoration-break: clone;
}

/* --- SECTION HEADER TRIPLET — design-system §5 --------------------------- */
.bto-static .svc-sec-eyebrow {
  margin: 0 0 clamp(20px, 2.4vh, 28px);
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 500;
  font-size: clamp(11px, .8vw, 14px);
  line-height: 1.3;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-accent);
}
.bto-static .svc-sec-head {
  margin: 0;
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 700;
  font-size: clamp(34px, 3.6vw, 62px);
  line-height: .94;
  letter-spacing: -.05em;
  text-transform: uppercase;
  max-width: 18ch;
  color: var(--fg-heading);
}
.bto-static .svc-sec-support {
  margin: clamp(20px, 2.4vh, 28px) 0 0;
  max-width: 46ch;
  font-size: clamp(17px, 1.3vw, 21px);
  line-height: 1.5;
  color: var(--fg-lead);
}

/* Existing heads on about/contact are a flat inherited 90px (design-system §7
   gap 3). Bring them onto the system scale.

   🔴 GATED ON .bto-panel, and the gate is the point. The spec writes this as
   `.bto-static .bto-static__sec .content__title`, but about.html and
   contact.html ALREADY ship 10 elements matching that — so as written it is not
   an additive rule, it is an immediate restyle of two live pages. MEASURED: it
   took every head from a flat 90px to a 62px cap and shortened about.html by
   256px and contact.html by 69px before either page had opted into anything.

   Requiring `.bto-panel` on the ancestor makes it land at exactly the moment a
   page adopts ground blocking — which is when the section-header system is
   wanted anyway — and keeps the two shipping pages byte-identical until then.
   Same end state the spec asked for, sequenced so nothing changes under a page
   that has not been rebuilt yet. */
.bto-static .bto-panel.bto-static__sec .content__title,
.bto-static .bto-panel .content__title {
  font-size: clamp(34px, 3.6vw, 62px);
  line-height: .94;
  letter-spacing: -.05em;
}

/* --- MASK WRAPPER for M1 -------------------------------------------------- */
/* The padding/margin pair is load-bearing: without it descenders clip. */
.bto-static .bto-mask {
  display: block;
  overflow: hidden;
  padding-block: .02em .08em;
  margin-block: -.02em -.08em;
}
.bto-static .bto-mask > * { display: block; }

/* --- PILL BUTTONS — design-system §5 ------------------------------------- */
.bto-static .p2-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: clamp(42px, 3.4vw, 52px);
  padding: 0 clamp(20px, 2vw, 34px);
  border-radius: 40px;
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 500;
  font-size: clamp(12px, .95vw, 15px);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform .22s ease, background-color .22s ease;
}
.bto-static .p2-cta--primary { background: var(--fill-accent); color: var(--fg-on-accent); }
.bto-static .p2-cta--ghost {
  background: transparent;
  color: currentColor;
  border: 1px solid var(--bg-hairline);
}
.bto-static .p2-cta:focus-visible { outline: 3px solid var(--fill-accent); outline-offset: 3px; }
@media (hover: hover) {
  .bto-static .p2-cta--primary:hover { background: var(--fill-accent-press); transform: translateY(-2px); }
  .bto-static .p2-cta--ghost:hover   { transform: translateY(-2px); }
}
.bto-static .p2-cta[disabled],
.bto-static .p2-cta[aria-disabled="true"] { opacity: .55; cursor: not-allowed; transform: none; }

/* --- CHIP — F4 category counts ------------------------------------------- */
.bto-static .p4-head-slab {
  display: inline-block;
  padding: .18em .55em;
  background: var(--fill-accent);
  color: var(--fg-on-accent);
  border-radius: 0;
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 500;
  font-size: clamp(12px, .95vw, 15px);
  letter-spacing: .1em;
  text-transform: uppercase;
}
.bto-static .bto-chip-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 clamp(28px, 3.2vh, 40px); }

/* --- CARD — F4 work grid -------------------------------------------------- */
.bto-static .bto-cardgrid {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(20px, 2.4vw, 40px);
}
@media (min-width: 901px)  { .bto-static .bto-cardgrid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1240px) { .bto-static .bto-cardgrid { grid-template-columns: repeat(3, 1fr); } }

.bto-static .sva-card {
  position: relative;
  overflow: hidden;
  border-radius: 28px;
  border: 1px solid var(--bg-hairline);
  background: var(--bg-card);
  padding: clamp(24px, 3vh, 36px);
  transition: transform .4s cubic-bezier(.2,.7,.2,1), border-color .4s cubic-bezier(.2,.7,.2,1);
}
.bto-static .sva-card > * { position: relative; z-index: 1; }
.bto-static .sva-card::before {
  content: "";
  position: absolute;
  top: -75px;
  right: -75px;
  width: 128px;
  height: 128px;
  border-radius: 50%;
  background: var(--fill-accent);
  transform: scale(0);
  transition: transform .5s ease;
  z-index: 0;
}
@media (hover: hover) {
  .bto-static .sva-card:hover { transform: translateY(-6px); border-color: var(--fill-accent); }
  .bto-static .sva-card:hover::before { transform: scale(13); }
  .bto-static .sva-card:hover .sva-card-name { color: var(--fg-on-accent); }
}

/* --- POSTER + VIDEO — design-system §4e ---------------------------------- */
.bto-static .sva-card-vid { position: relative; display: block; border-radius: 28px; overflow: hidden; }
.bto-static .sva-card-vid img   { position: relative; z-index: 0; width: 100%; display: block; }
.bto-static .sva-card-vid video {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .3s ease;
}
.bto-static .sva-card-vid video.is-on { opacity: 1; }

/* --- INERT FORM — spec §5.1 ---------------------------------------------- */
.bto-static .bto-form { display: grid; gap: clamp(16px, 2vh, 22px); max-width: 52ch; }
.bto-static .bto-form__field { display: grid; gap: 8px; }
.bto-static .bto-form__field label {
  font-family: Antonio, Archivo, sans-serif;
  font-weight: 500;
  font-size: clamp(11px, .8vw, 14px);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-accent);
}
.bto-static .bto-form__field input,
.bto-static .bto-form__field select,
.bto-static .bto-form__field textarea {
  width: 100%;
  padding: 14px 18px;
  border: 1px solid var(--bg-hairline);
  border-radius: 40px;
  background: var(--bg-card);
  color: var(--fg-body);
  font-size: clamp(15px, 1.05vw, 17px);
  opacity: .55;
  cursor: not-allowed;
}
.bto-static .bto-form__field textarea { border-radius: 28px; min-height: 140px; resize: none; }
.bto-static .bto-form__note { margin: 0; max-width: 46ch; }


/* ==========================================================================
   §B2 · MOTION HOOKS — the CSS half of reveals.js + static-panels.js.

   WHY THIS IS HERE AND NOT IN reveals.css
   reveals.css § 1 drives the word scrub, but its selector is
   `html.bto-rv .bto-banner .bto-banner-lead .bto-rv-w` — index.html ONLY.
   Re-pointing reveals.js at `.bto-scrub` therefore splits the paragraph and
   tweens --rv-lit against NO consuming rule: the scrub runs and renders
   nothing, while SplitText's inline `display:inline-block` is free to re-wrap
   the copy. The JS re-point alone does not deliver the effect. This block is
   the missing half, and it belongs in the static sheet because that is the
   scope that owns these pages. reveals.css is untouched.

   HOW THIS CANNOT REPEAT THE PIXY BUG (reveals.css § 0)
   Every collapsed / pre-effect state below keys on a class that JAVASCRIPT
   adds — `.bto-rv-w` (reveals.js) or `.bto-sp-clip` (static-panels.js) — never
   on the author's opt-in class. So:
     JS blocked · file 404 · GSAP missing · script throws · reduced motion
       → the JS class is never added → these rules match nothing
       → the element renders as plain, fully-visible markup.
   There is no state in which this block can hide text or clip a heading.
   Author classes (.bto-scrub / .bto-wipe / .bto-wipe-in / .bto-wipe-centre)
   are inert on their own by design.
   ========================================================================== */

/* --- M4 · word colour scrub, light grounds -------------------------------- */
/* Same two tokens and the same color-mix form as reveals.css § 1, so the
   theme toggle survives and no new colour enters the system. --rv-lit carries
   its own unit ("0%".."100%") — substituted straight into the percentage slot,
   never wrapped in calc(). reveals.js tweens it in that exact form. */
.bto-static .bto-scrub .bto-rv-w {
  color: color-mix(in srgb,
                   var(--fg-ink) var(--rv-lit, 100%),
                   var(--fg-mute));
}

/* --- M4 · word colour scrub, GROUND C ------------------------------------- */
/* On the dark panel the light-ground pair inverts and would be unreadable, so
   the mix travels --fg-on-dark-mute → --fg-on-dark instead. Both clear AA on
   ink AND on navy (8.83/5.69 and 15.44/9.95, palette.css:191-192), so this
   endpoint pair survives the theme flip exactly as the light one does, and
   every intermediate frame sits between the two. */
.bto-static .bto-panel--dark .bto-scrub .bto-rv-w {
  color: color-mix(in srgb,
                   var(--fg-on-dark) var(--rv-lit, 100%),
                   var(--fg-on-dark-mute));
}

/* --- M2e / M3 · clip wipes driven by static-panels.js --------------------- */
/* Collapsed pre-states. `.bto-sp-clip` is added by static-panels.js one
   statement before the tween and removed on completion, mirroring reveals.js's
   `.bto-rv-wipe` contract exactly. Gated additionally on html.bto-rv (the
   inline <head> script at about.html:18 / contact.html:18) so a page without a
   working JS engine never reaches a collapsed state.

   The polygons overshoot the box (-25%/125% vertical, -5%/105% horizontal) for
   the reason reveals.css § 2 documents: Mokko sets line-height .9 on these
   heads, so glyphs are taller than the content box and a clip at exactly 100%
   would shave ascenders and descenders permanently. */
html.bto-rv .bto-static .bto-sp-clip--in {
  clip-path: inset(0 100% 0 0);
  will-change: clip-path;
}
html.bto-rv .bto-static .bto-sp-clip--centre {
  clip-path: polygon(50% -25%, 50% -25%, 50% 125%, 50% 125%);
  will-change: clip-path;
}

/* --- REDUCED MOTION — non-negotiable (design-system §3) ------------------- */
@media (prefers-reduced-motion: reduce) {
  .bto-static .sva-card,
  .bto-static .sva-card::before,
  .bto-static .sva-card-vid video,
  .bto-static .p2-cta { transition: none; }
  .bto-static .sva-card-vid video { display: none; }

  /* End state outright, never animated toward it — a reduced-motion reader
     sees the same finished page as everyone else, not the pre-effect page.
     reveals.js returns before creating a split, so `.bto-rv-w` never exists
     and the paragraph simply keeps its own colour; these two lines make the
     lit end explicit so the resting appearance matches the animated one. */
  .bto-static .bto-scrub { color: var(--fg-ink); }
  .bto-static .bto-panel--dark .bto-scrub { color: var(--fg-on-dark); }

  /* Belt-and-braces: static-panels.js branches before adding these classes,
     but if a future edit ever adds one, the element still renders unclipped. */
  html.bto-rv .bto-static .bto-sp-clip--in,
  html.bto-rv .bto-static .bto-sp-clip--centre {
    clip-path: none;
    will-change: auto;
  }
  .bto-static [style*="clip-path"] { clip-path: none; }
}
