/* ════════════════════════════════════════════════════════════════════════
   Ampinity — design system (design-system.md). Cinematic, engineering-led,
   calm and warm. Near-black base, one connective-thread accent that swaps by
   sector. Materiality from hairlines + light, not heavy shadow. Crisp radii.
   Boldness spent in exactly one place: the connective thread.
   ════════════════════════════════════════════════════════════════════════ */

*,*::before,*::after { box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body {
  margin:0;
  background:var(--ink-900);
  color:var(--on-ink-hi);
  font-family:var(--font-text);
  font-size:var(--t-body);
  line-height:1.55;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  /* clip (not hidden): keeps overflow-y as visible so <body> never becomes a
     scroll container — otherwise it coerces to overflow-y:auto and breaks the
     root scroll-snap on the homepage film. */
  overflow-x:clip;
}

/* ── Uniform scrollbar ───────────────────────────────────────────────────────
   The page scrollbar lives on the root (<html>) so it's the same on every page.
   `overflow-y:scroll` keeps it always present — even on short pages — so the bar
   never appears/disappears between pages and centred content never shifts side
   to side. Themed to the dark UI: a slim rounded thumb on a transparent track,
   the accent on hover. The ::-webkit rules also tidy every inner scroll area
   (mobile nav, spec tables, legal TOC) for one consistent look; Firefox uses
   scrollbar-width / -color. Snap still works (the root stays the scroller). */
html{overflow-y:scroll;scrollbar-width:thin;scrollbar-color:var(--ink-600) transparent;}
::-webkit-scrollbar{width:12px;height:12px;}
::-webkit-scrollbar-track{background:transparent;}
::-webkit-scrollbar-thumb{background:var(--ink-600);border-radius:999px;border:3px solid transparent;background-clip:padding-box;}
::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--accent) 55%,var(--ink-600));background-clip:padding-box;border:3px solid transparent;}
::-webkit-scrollbar-corner{background:transparent;}

img,svg,video,canvas { display:block; max-width:100%; height:auto; }
a { color:inherit; text-decoration:none; }
:focus-visible { outline:2px solid var(--focus); outline-offset:2px; border-radius:var(--r-sm); }
::selection { background:var(--accent); color:var(--ink-900); }

/* ── Skip link (a11y) ── */
/* Hidden by moving UP (not off-screen left) so it can never widen the document. */
.skip-link {
  position:fixed; left:var(--s-4); top:-60px; z-index:var(--z-modal);
  background:var(--accent); color:var(--ink-900); padding:var(--s-3) var(--s-5);
  font:600 var(--t-caption)/1 var(--font-text); transition:top var(--dur) var(--ease-standard);
}
.skip-link:focus { top:var(--s-4); }

/* ── Layout ── */
.container { width:100%; max-width:var(--container-max); margin-inline:auto; padding-inline:var(--gutter); }
.container--wide { max-width:var(--container-wide); }
.section { padding-block:var(--s-10); }
.section--tight { padding-block:var(--s-8); }
.section.on-paper { background:var(--paper-50); color:var(--on-paper-hi); }
.section.on-paper .muted { color:var(--on-paper-mid); }
/* Contrast law (design-system §2): on paper, body text uses dark hi/mid tokens
   and the cyan accent must use its AA-compliant deep variant — never bright cyan. */
.section.on-paper .lede,
.section.on-paper p { color:var(--on-paper-mid); }
.section.on-paper h1,.section.on-paper h2,.section.on-paper h3,.section.on-paper h4 { color:var(--on-paper-hi); }
.section.on-paper .eyebrow { color:var(--accent-ink); }
.section.on-paper .eyebrow::before { background:var(--accent-deep); }
.section.on-paper .manifesto p { color:var(--on-paper-mid); }
.section.on-paper .manifesto p.lead,
.section.on-paper .manifesto p.close { color:var(--on-paper-hi); }
.section.on-paper .credo { color:var(--on-paper-hi); }
/* Dark card/panel components keep light-on-dark text even inside .on-paper
   (light) sections — the section's near-black text tokens must NOT bleed into
   a dark card (WCAG 1.4.3: near-black on ink-800 ≈ 1.1:1, illegible). */
.section.on-paper .sector-card h3,
.section.on-paper .house-link .name,
.section.on-paper .leader .name { color:var(--on-ink-hi); }
.section.on-paper .sector-card .line,
.section.on-paper .sector-card p,
.section.on-paper .house-link .n,
.section.on-paper .leader .certain { color:var(--on-ink-mid); }
.muted { color:var(--on-ink-mid); }
.measure { max-width:64ch; }
.measure-sm { max-width:48ch; }

/* ── Typography ── */
.logotype {
  font-family:var(--font-logotype);
  font-weight:700; letter-spacing:0.04em; text-transform:uppercase;
}
.display-2xl{font:600 var(--t-display-2xl)/1.0 var(--font-display);letter-spacing:-0.02em;margin:0;}
.display-xl {font:600 var(--t-display-xl)/1.03 var(--font-display);letter-spacing:-0.02em;margin:0;}
h1,.h1{font:600 var(--t-h1)/1.06 var(--font-display);letter-spacing:-0.015em;margin:0 0 var(--s-4);}
h2,.h2{font:550 var(--t-h2)/1.12 var(--font-display);letter-spacing:-0.01em;margin:0 0 var(--s-4);}
h3,.h3{font:550 var(--t-h3)/1.2 var(--font-display);letter-spacing:-0.005em;margin:0 0 var(--s-3);}
h4,.h4{font:550 var(--t-h4)/1.3 var(--font-display);margin:0 0 var(--s-3);}
p{margin:0 0 var(--s-4);}

/* Title Case — scoped to headings + primary nav only; body copy stays as written.
   The top-level mega-menu labels are <button class="nav-link">, not <a>, so
   .nav-link is required (a bare "nav a" would miss them); .nav a covers the
   mega-panel sub-links. Elements with their own text-transform (.mega-eyebrow,
   .mega-links a .note = uppercase) override this and keep their casing. */
h1,h2,h3,h4,
.h1,.h2,.h3,.h4,
.display-2xl,.display-xl,
.nav-link,
.nav a { text-transform:capitalize; }
.body-lg{font-size:var(--t-body-lg);line-height:1.55;}
.caption{font-size:var(--t-caption);}
strong,b{font-weight:600;}

.eyebrow{
  font-family:var(--font-mono); font-size:var(--t-eyebrow); font-weight:500;
  letter-spacing:0.08em; text-transform:uppercase; color:var(--accent);
  display:inline-flex; align-items:center; gap:var(--s-2); margin:0 0 var(--s-4);
}
.eyebrow::before{content:"";width:24px;height:var(--b-thread);background:var(--accent);display:inline-block;}

.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}

/* ── The connective thread (the one memorable device) ── */
.thread-rule{
  height:var(--b-thread); border:0; margin:var(--s-8) 0;
  background:linear-gradient(90deg,transparent,var(--accent),transparent);
  opacity:.55;
}
[data-accent="graphite"] .thread-rule{background:var(--graphite-base);opacity:.4;}

/* ── Buttons / CTA ── */
.btn{
  --btn-bg:var(--accent); --btn-fg:var(--ink-900);
  display:inline-flex; align-items:center; gap:var(--s-2);
  font:600 var(--t-body)/1 var(--font-text); letter-spacing:-0.01em;
  padding:var(--s-4) var(--s-6); border:var(--b-hairline) solid var(--btn-bg);
  background:var(--btn-bg); color:var(--btn-fg); border-radius:var(--r-sm);
  cursor:pointer; transition:transform var(--dur) var(--ease-standard),
    background var(--dur) var(--ease-standard), color var(--dur) var(--ease-standard);
  text-align:center;
}
.btn:hover{transform:translateY(-1px);}
.btn:active{transform:scale(.99);}
.btn--secondary{ --btn-bg:transparent; --btn-fg:var(--on-ink-hi); border-color:var(--ink-600); }
.btn--secondary:hover{border-color:var(--accent);color:var(--accent);}
.btn--ghost{ --btn-bg:transparent; --btn-fg:var(--accent); border-color:transparent; padding-inline:0; position:relative; }
.btn--ghost::after{content:"";position:absolute;left:0;bottom:-2px;height:var(--b-thread);width:0;background:var(--accent);transition:width var(--dur) var(--ease-standard);}
.btn--ghost:hover{transform:none;}
.btn--ghost:hover::after{width:100%;}
.section.on-paper .btn--secondary{ --btn-fg:var(--on-paper-hi); border-color:var(--paper-200); }
.btn-row{display:flex;flex-wrap:wrap;gap:var(--s-4);align-items:center;}

/* ── Header + mega menu ── */
.site-header{
  position:sticky; top:0; z-index:var(--z-header);
  background:color-mix(in srgb, var(--ink-900) 86%, transparent);
  backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
  border-bottom:var(--b-hairline) solid var(--ink-700);
}

/* ── Utility top bar (above the mega menu): relocated Investors · Careers ── */
.top-bar{border-bottom:var(--b-hairline) solid var(--ink-700);}
.top-bar-list{display:flex;justify-content:flex-end;align-items:center;gap:var(--s-5);
  list-style:none;margin:0;padding-block:6px;min-height:34px;}
.top-bar-link{display:inline-flex;align-items:center;gap:var(--s-2);
  font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.04em;
  color:var(--on-ink-mid);transition:color var(--dur) var(--ease-standard);}
.top-bar-link:hover{color:var(--on-ink-hi);}
.tb-gated{font-family:var(--font-mono);font-size:11px;line-height:1;letter-spacing:0.1em;
  text-transform:uppercase;color:var(--on-ink-mid);border:var(--b-hairline) solid var(--ink-700);
  padding:2px 5px;border-radius:var(--r-sm);}
/* The utility links also render inside the off-canvas menu, hidden on desktop.
   Compound selector beats .nav-list{display:flex} (equal specificity, later in
   source) since the element carries both classes. */
.nav-list.nav-list--utility{display:none;}
.header-bar{display:flex;align-items:center;justify-content:space-between;gap:var(--s-5);min-height:64px;}
.brand{display:inline-flex;align-items:center;color:var(--on-ink-hi);}
/* The Ampinity wordmark (white, transparent), trimmed to the glyphs so it sizes
   by its true height in the bar rather than padded dead space. */
.brand-logo{display:block;width:auto;height:auto;max-height:28px;max-width:200px;}
.site-footer .brand-logo{max-height:25px;}
@media (max-width:520px){ .brand-logo{max-height:24px;} }
.nav{display:flex;align-items:center;gap:var(--s-2);}
.nav-list{display:flex;list-style:none;margin:0;padding:0;gap:var(--s-1);}
/* nav-item is static on desktop so its panel positions full-width relative to
   the (positioned, sticky) .site-header — the proper mega-menu drop. */
.nav-item{position:static;}
.nav-link{
  display:inline-flex;align-items:center;gap:6px;padding:var(--s-3) var(--s-3);
  font-size:var(--t-caption);color:var(--on-ink-mid);border-radius:var(--r-sm);
  background:none;border:0;cursor:pointer;font-family:inherit;white-space:nowrap;
  transition:color var(--dur) var(--ease-standard);
}
.nav-link:hover,.nav-link[aria-expanded="true"],.nav-item.is-current .nav-link{color:var(--on-ink-hi);}
.nav-link[aria-expanded="true"]{color:var(--accent);}
.nav-link .caret{width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform var(--dur);}
.nav-link[aria-expanded="true"] .caret{transform:rotate(-135deg) translateY(0);}

/* the connective-thread indicator under the active nav item */
.thread-ind{position:absolute;left:0;bottom:-1px;height:var(--b-thread);width:0;background:var(--thread-base);
  opacity:0;z-index:calc(var(--z-megamenu) + 1);pointer-events:none;
  transition:left var(--dur-slow) var(--ease-cine),width var(--dur-slow) var(--ease-cine),background var(--dur),opacity var(--dur);}
.thread-ind.is-on{opacity:1;}

/* ── Full-width mega panel: intro · links · featured rail ── */
.mega-panel{
  position:absolute;left:0;right:0;top:100%;z-index:var(--z-megamenu);
  background:linear-gradient(180deg,
    color-mix(in srgb, var(--ink-800) 78%, transparent),
    color-mix(in srgb, var(--ink-850) 78%, transparent));
  backdrop-filter:blur(18px) saturate(1.2); -webkit-backdrop-filter:blur(18px) saturate(1.2);
  border-top:var(--b-thread) solid var(--accent);
  border-bottom:var(--b-hairline) solid var(--ink-700);
  box-shadow:0 30px 60px rgba(0,0,0,.5);
  opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-8px);
  transition:opacity var(--dur) var(--ease-standard),transform var(--dur) var(--ease-standard),visibility var(--dur);
}
.nav-item.is-open .mega-panel{opacity:1;visibility:visible;pointer-events:auto;transform:translateY(0);}
.mega-panel-inner{display:grid;grid-template-columns:1.1fr 2fr 1fr;gap:clamp(24px,4vw,56px);padding-block:var(--s-7) var(--s-6);}
@media (max-width:1180px){ .mega-panel-inner{grid-template-columns:1.2fr 2fr;} .mega-feat{display:none;} }

.mega-eyebrow{font-family:var(--font-mono);font-size:var(--t-eyebrow);font-weight:500;letter-spacing:0.12em;text-transform:uppercase;color:var(--accent);margin:0 0 var(--s-4);}
.mega-tagline{font:600 var(--t-h3)/1.12 var(--font-display);letter-spacing:-0.01em;color:var(--on-ink-hi);margin:0 0 var(--s-3);max-width:16ch;}
.mega-blurb{color:var(--on-ink-mid);font-size:var(--t-caption);line-height:1.55;margin:0;max-width:36ch;}

.mega-links{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:0 var(--s-7);align-content:start;}
@media (max-width:680px){ .mega-links{grid-template-columns:1fr;} }
.mega-links a{display:flex;align-items:baseline;gap:var(--s-3);padding:var(--s-3) var(--s-2) var(--s-3) 0;
  border-bottom:var(--b-hairline) solid var(--ink-700);color:var(--on-ink-hi);position:relative;transition:padding var(--dur) var(--ease-standard);}
.mega-links a .nm{font-size:var(--t-body);}
.mega-links a .note{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;text-transform:uppercase;color:var(--on-ink-mid);}
.mega-links a .arw{margin-left:auto;color:var(--accent);opacity:0;transform:translateX(-4px);transition:opacity var(--dur),transform var(--dur);}
.mega-links a::after{content:"";position:absolute;left:0;bottom:-1px;height:1px;width:0;background:var(--accent);transition:width var(--dur);}
.mega-links a:hover,.mega-links a:focus-visible{padding-left:6px;}
.mega-links a:hover .arw,.mega-links a:focus-visible .arw{opacity:1;transform:none;}
.mega-links a:hover::after,.mega-links a:focus-visible::after{width:100%;}

.mega-feat{align-self:stretch;}
.mega-card{display:flex;flex-direction:column;justify-content:flex-end;height:100%;min-height:170px;
  padding:var(--s-5);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);position:relative;overflow:hidden;
  background:radial-gradient(120% 90% at 80% 0%, color-mix(in srgb,var(--accent) 22%, transparent), transparent 60%),linear-gradient(180deg,var(--ink-700),var(--ink-850));
  transition:border-color var(--dur) var(--ease-standard);}
.mega-card:hover{border-color:var(--accent);}
.mega-card .thread-line{position:absolute;left:var(--s-5);right:var(--s-5);top:var(--s-5);height:1px;background:linear-gradient(90deg,var(--accent),transparent);opacity:.7;}
.mega-card .tag{font:550 var(--t-body-lg)/1.25 var(--font-display);color:var(--on-ink-hi);margin:0 0 var(--s-3);max-width:22ch;}
.mega-card .go{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.1em;text-transform:uppercase;color:var(--accent);display:inline-flex;align-items:center;gap:var(--s-2);}
.mega-card .gated-badge{margin-bottom:var(--s-3);align-self:flex-start;}
/* Defence: graphite, no glow. */
.nav-item[data-accent="graphite"] .mega-card{background:linear-gradient(180deg,var(--ink-700),var(--ink-850));}

/* Mobile nav */
.nav-toggle{display:none;}

@media (max-width:1100px){
  .nav-toggle{display:inline-flex;}
  /* Top bar is desktop-only (keeps the header bar = 64px, which the off-canvas
     nav's top:64px / height calc rely on). Investors · Careers move into the menu. */
  .top-bar{display:none;}
  .nav-list.nav-list--utility{display:flex;margin-top:var(--s-5);border-top:var(--b-hairline) solid var(--ink-700);}
  /* Off-canvas menu: hidden via display (not an off-screen transform) so it
     never widens the document and is not focusable while closed.
     NB: .site-header has backdrop-filter, which establishes a containing block
     for this fixed element — so `bottom:0` would resolve against the ~64px
     header and collapse the panel to a sliver. Anchor with top + an explicit
     viewport height instead (dvh handles mobile browser chrome; vh fallback). */
  .nav{position:fixed;top:64px;left:0;right:0;height:calc(100vh - 64px);height:calc(100dvh - 64px);
    background:var(--ink-900);flex-direction:column;align-items:stretch;
    padding:var(--s-5) var(--gutter);overflow-y:auto;z-index:var(--z-overlay);display:none;}
  .nav.is-open{display:flex;animation:nav-in var(--dur) var(--ease-standard);}
  @keyframes nav-in{from{opacity:0;transform:translateX(8px);}to{opacity:1;transform:none;}}
  .nav-list{flex-direction:column;gap:0;}
  .nav-item{border-bottom:var(--b-hairline) solid var(--ink-700);}
  .nav-link{width:100%;justify-content:space-between;padding:var(--s-4) 0;font-size:var(--t-body-lg);}
  .thread-ind{display:none;}
  /* Accordion: just the link list (intro + featured collapse away). */
  .mega-panel{position:static;transform:none;opacity:1;visibility:visible;pointer-events:auto;display:none;
    border:0;border-left:var(--b-thread) solid var(--accent);background:transparent;box-shadow:none;}
  .nav-item.is-open .mega-panel{display:block;}
  .mega-panel-inner{display:block;padding:0 0 var(--s-4) var(--s-4);}
  .mega-intro,.mega-feat{display:none;}
  .mega-links{grid-template-columns:1fr;}
  .mega-links a{border-bottom:var(--b-hairline) solid var(--ink-800);}
}

/* ── Mobile menu: toggle (hamburger ↔ ✕) + persona quick-start ──────────────
   The persona "Where do you fit?" rows and the section labels live inside the
   off-canvas <nav> and are desktop-hidden; they self-route each audience to the
   surface built for its decision (content/personas.php). Accent per row via
   [data-accent] → --accent (§I); graphite (Defence) carries no glow. */
.nav-personas,
.nav-section-label{display:none;}

/* Toggle button (lost its old .nav-link base — styled in full here). Visibility
   is owned by the rules above: display:none on desktop, inline-flex ≤1100px. */
.nav-toggle{align-items:center;gap:var(--s-3);background:none;border:0;cursor:pointer;
  font-family:inherit;font-size:var(--t-caption);color:var(--on-ink-mid);
  padding:var(--s-2) var(--s-2);border-radius:var(--r-sm);
  transition:color var(--dur) var(--ease-standard);-webkit-tap-highlight-color:transparent;}
.nav-toggle:hover,.nav-toggle[aria-expanded="true"]{color:var(--on-ink-hi);}
.nav-toggle-icon{position:relative;display:inline-block;width:18px;height:12px;flex:none;}
.nav-toggle-icon > span,
.nav-toggle-icon::before,
.nav-toggle-icon::after{content:"";position:absolute;left:0;right:0;height:2px;border-radius:2px;
  background:currentColor;transition:transform var(--dur) var(--ease-standard),opacity var(--dur);}
.nav-toggle-icon::before{top:0;}
.nav-toggle-icon > span{top:5px;}
.nav-toggle-icon::after{bottom:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle-icon::before{transform:translateY(5px) rotate(45deg);}
.nav-toggle[aria-expanded="true"] .nav-toggle-icon > span{opacity:0;}
.nav-toggle[aria-expanded="true"] .nav-toggle-icon::after{transform:translateY(-5px) rotate(-45deg);}
.nav-toggle-txt--close{display:none;}
.nav-toggle[aria-expanded="true"] .nav-toggle-txt--open{display:none;}
.nav-toggle[aria-expanded="true"] .nav-toggle-txt--close{display:inline;}

/* Persona rows (rendered only inside the open mobile menu). */
.persona-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--s-2);}
.persona{position:relative;display:flex;align-items:center;gap:var(--s-4);min-height:60px;
  padding:var(--s-3) var(--s-4);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-md);
  background:color-mix(in srgb, var(--ink-800) 50%, transparent);color:var(--on-ink-hi);overflow:hidden;
  transition:border-color var(--dur) var(--ease-standard),background var(--dur),transform var(--dur);}
.persona-rule{position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--accent);
  box-shadow:0 0 10px color-mix(in srgb, var(--accent) 60%, transparent);}
.persona[data-accent="graphite"] .persona-rule{box-shadow:none;}
/* Sentence-case the labels — the global `.nav a{text-transform:capitalize}`
   would otherwise Title-Case "Farm or run agri-business". */
.persona-text{display:flex;flex-direction:column;gap:2px;min-width:0;text-transform:none;}
.persona-label{display:flex;align-items:center;gap:var(--s-2);
  font-size:var(--t-body-lg);font-weight:550;line-height:1.15;color:var(--on-ink-hi);}
.persona-spark{color:var(--ember-base);font-size:0.8em;}
.persona-need{font-size:var(--t-caption);line-height:1.35;color:var(--on-ink-mid);}
.persona-gated{margin-left:auto;align-self:center;font-family:var(--font-mono);font-size:11px;line-height:1;
  letter-spacing:0.08em;text-transform:uppercase;color:var(--on-ink-mid);
  border:var(--b-hairline) solid var(--ink-700);padding:3px 6px;border-radius:var(--r-sm);}
.persona-go{margin-left:auto;color:var(--accent);font-size:var(--t-body-lg);line-height:1;
  transform:translateX(-2px);transition:transform var(--dur) var(--ease-standard);}
.persona-gated + .persona-go{margin-left:var(--s-3);}
.persona:hover,.persona:focus-visible{border-color:color-mix(in srgb, var(--accent) 55%, var(--ink-700));
  background:color-mix(in srgb, var(--accent) 12%, var(--ink-800));}
.persona:hover .persona-go,.persona:focus-visible .persona-go,.persona:active .persona-go{transform:translateX(2px);}
.persona:active{transform:scale(0.99);}
@media (prefers-reduced-motion:reduce){
  .persona,.persona-go,.nav-toggle-icon > span,.nav-toggle-icon::before,.nav-toggle-icon::after{transition:none;}
  .persona:active{transform:none;}
}

@media (max-width:1100px){
  /* Reveal the persona quick-start + its labels inside the off-canvas menu. */
  .nav-personas{display:block;}
  .nav-section-label{display:block;font-family:var(--font-mono);font-size:var(--t-eyebrow);
    letter-spacing:0.14em;text-transform:uppercase;color:var(--on-ink-lo);margin:0 0 var(--s-4);}
  .nav-section-label--browse{margin-top:var(--s-6);padding-top:var(--s-5);
    border-top:var(--b-hairline) solid var(--ink-700);}
}

/* ── Hero (cinematic) ── */
.hero{position:relative;min-height:78vh;display:flex;align-items:flex-end;overflow:hidden;padding-block:var(--s-10) var(--s-9);}
.hero--home{min-height:100vh;}
.hero-canvas{position:absolute;inset:0;z-index:0;background:radial-gradient(120% 90% at 70% 10%, var(--ink-800), var(--ink-900) 60%);}
/* Homepage = scroll-as-film (3d-experience §2): the canvas is a fixed, full-
   viewport backdrop the body scrolls over, so the thread keeps drawing through
   the opening beats instead of being clipped to the first screen. It sits behind
   content (z-index:-1); transparent dark sections reveal it, paper sections
   punctuate it, and the scene fades it out as the establishing beats end. */
.hero--home .hero-canvas{position:fixed;z-index:-1;}
.hero-canvas canvas{width:100%;height:100%;}
.hero-poster{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover;}
.hero .container{position:relative;z-index:1;}
.hero-eyebrow{margin-bottom:var(--s-5);}
.hero h1{max-width:18ch;}
.hero-sub{font-size:var(--t-body-lg);color:var(--on-ink-mid);max-width:60ch;margin-bottom:var(--s-6);}
.hero-grad{position:absolute;inset:0;z-index:0;background:linear-gradient(0deg, var(--ink-900) 6%, transparent 60%);}

/* ── Sector cards ── */
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--s-5);}
.card-grid--3{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));}
.sector-card{
  display:flex;flex-direction:column;gap:var(--s-3);
  padding:var(--s-6);background:var(--ink-800);border:var(--b-hairline) solid var(--ink-700);
  border-radius:var(--r-sm);position:relative;overflow:hidden;
  transition:border-color var(--dur) var(--ease-standard),transform var(--dur) var(--ease-standard);
}
.sector-card::before{content:"";position:absolute;left:0;top:0;height:100%;width:var(--b-thread);background:var(--accent);transform:scaleY(0);transform-origin:top;transition:transform var(--dur-slow) var(--ease-cine);}
.sector-card:hover{border-color:var(--ink-600);transform:translateY(-2px);}
.sector-card:hover::before{transform:scaleY(1);}
.sector-card .kicker{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;color:var(--accent);text-transform:lowercase;}
.sector-card h3{margin:0;}
.sector-card .line{color:var(--on-ink-mid);font-size:var(--t-body);flex:1;}
.sector-card .more{font-size:var(--t-caption);color:var(--accent);display:inline-flex;align-items:center;gap:6px;}

/* ── Detail blocks + bullets ── */
.block{margin-bottom:var(--s-8);}
.block-bullets{list-style:none;margin:var(--s-4) 0 0;padding:0;display:grid;gap:var(--s-3);}
.block-bullets li{position:relative;padding-left:var(--s-5);color:var(--on-ink-mid);}
.block-bullets li::before{content:"";position:absolute;left:0;top:0.6em;width:10px;height:var(--b-thread);background:var(--accent);}
.section.on-paper .block-bullets li{color:var(--on-paper-mid);}

/* ── Spec tables (mono, tabular) ── */
/* Spec tables are engineering "data panels" — always a dark surface with light
   tabular figures, so they stay AA-legible on dark OR paper sections. */
.spec-table-wrap{overflow-x:auto;background:var(--ink-800);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);margin:var(--s-5) 0;}
.spec-table{width:100%;border-collapse:collapse;font-size:var(--t-mono-spec);}
.spec-table caption{text-align:left;color:var(--on-ink-mid);font-family:var(--font-text);font-size:var(--t-caption);padding:var(--s-4);caption-side:top;}
.spec-table th,.spec-table td{padding:var(--s-3) var(--s-4);text-align:left;border-bottom:var(--b-hairline) solid var(--ink-700);white-space:nowrap;}
.spec-table thead th{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;text-transform:uppercase;color:var(--on-ink-mid);background:var(--ink-800);position:sticky;top:0;}
.spec-table tbody th{font-family:var(--font-text);font-weight:500;color:var(--on-ink-hi);}
.spec-table td{font-family:var(--font-mono);font-variant-numeric:tabular-nums;color:var(--on-ink-mid);}
.spec-table tbody tr:hover{background:var(--ink-800);}
.spec-foot{font-size:var(--t-caption);color:var(--on-ink-lo);margin-top:var(--s-3);}

/* ── Stat / figure ── */
.stat{display:flex;flex-direction:column;gap:var(--s-1);}
.stat .figure{font-family:var(--font-mono);font-size:var(--t-h2);color:var(--accent);font-variant-numeric:tabular-nums;}
.stat .label{font-size:var(--t-caption);color:var(--on-ink-mid);text-transform:uppercase;letter-spacing:0.06em;}

/* ── Breadcrumb ── */
.breadcrumb{padding-block:var(--s-4);}
.breadcrumb ol{list-style:none;display:flex;flex-wrap:wrap;gap:var(--s-2);margin:0;padding:0;font-size:var(--t-caption);color:var(--on-ink-mid);}
.breadcrumb li{display:inline-flex;align-items:center;gap:var(--s-2);}
.breadcrumb li:not(:last-child)::after{content:"›";color:var(--on-ink-lo);}
.breadcrumb a:hover{color:var(--accent);}
.breadcrumb [aria-current]{color:var(--on-ink-mid);}

/* ── Glossary tooltip (expand-on-first-use) ── */
abbr.glossary{text-decoration:underline dotted var(--accent-deep);text-underline-offset:3px;cursor:help;}
[data-accent="thread"] abbr.glossary{text-decoration-color:var(--thread-deep);}

/* ── Linking grammar (UP / ACROSS) ── */
.linking{display:grid;gap:var(--s-4);padding:var(--s-6);background:var(--ink-800);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);}
.linking .label{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.08em;text-transform:uppercase;color:var(--on-ink-mid);margin-right:var(--s-3);}
.linking-row{display:flex;flex-wrap:wrap;gap:var(--s-2);align-items:baseline;}
.chip{display:inline-flex;align-items:center;gap:6px;padding:6px var(--s-3);border:var(--b-hairline) solid var(--ink-600);border-radius:var(--r-sm);font-size:var(--t-caption);color:var(--on-ink-mid);transition:border-color var(--dur),color var(--dur);}
.chip:hover{border-color:var(--accent);color:var(--accent);}

/* ── Section spine (the scannable structure) ── */
.spine{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:var(--s-2);}
.spine li{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.04em;text-transform:uppercase;color:var(--on-ink-mid);padding:4px var(--s-3);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);}

/* ── Forms ── */
.form{display:grid;gap:var(--s-5);max-width:42rem;}
.field{display:grid;gap:var(--s-2);}
.field label{font-size:var(--t-caption);color:var(--on-ink-hi);font-weight:500;}
.field .req{color:var(--accent);}
.field input,.field textarea,.field select{
  font:400 var(--t-body)/1.5 var(--font-text);background:var(--ink-800);color:var(--on-ink-hi);
  border:var(--b-hairline) solid var(--ink-600);border-radius:var(--r-sm);padding:var(--s-3) var(--s-4);width:100%;
  transition:border-color var(--dur);
}
.field textarea{min-height:120px;resize:vertical;}
.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--accent);}
.field .help{font-size:var(--t-caption);color:var(--on-ink-mid);}
.field.has-error input,.field.has-error textarea{border-color:var(--danger);}
.field .error{font-size:var(--t-caption);color:var(--danger);}
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden;}
.form-note{padding:var(--s-4) var(--s-5);border-left:var(--b-thread) solid var(--accent);background:var(--ink-800);color:var(--on-ink-mid);font-size:var(--t-caption);}
.form-status{padding:var(--s-4) var(--s-5);border-radius:var(--r-sm);font-size:var(--t-body);}
.form-status[data-ok="1"]{border:var(--b-hairline) solid var(--success);color:var(--success);background:color-mix(in srgb,var(--success) 8%,transparent);}
.form-status[data-ok="0"]{border:var(--b-hairline) solid var(--danger);color:var(--danger);background:color-mix(in srgb,var(--danger) 8%,transparent);}
/* reCAPTCHA. v3 is invisible: hide Google's floating badge (the inline attribution
   note below the form satisfies the reCAPTCHA Terms instead — a cleaner fit for the
   page) and style that note. v2 shows the checkbox widget, given a little spacing. */
.grecaptcha-badge{visibility:hidden;}
.form-recaptcha{margin-top:var(--s-2);}
.form-recaptcha-note{margin:var(--s-3) 0 0;font-size:var(--t-caption);color:var(--on-ink-mid);}
.form-recaptcha-note a{color:var(--on-ink-mid);text-decoration:underline;}
.form-recaptcha-note a:hover{color:var(--accent);}

/* ── Callout / note (naming discipline, firewall, build notes) ── */
.callout{padding:var(--s-5);border-left:var(--b-thread) solid var(--accent);background:var(--ink-800);border-radius:var(--r-sm);color:var(--on-ink-mid);margin:var(--s-5) 0;}
[data-accent="graphite"] .callout{border-left-color:var(--graphite-base);}

/* ── Footer + credo ── */
.site-footer{background:var(--ink-800);border-top:var(--b-hairline) solid var(--ink-700);padding-block:var(--s-9) var(--s-7);margin-top:var(--s-10);}
/* Brand + credo on the left (the closing statement); grouped nav on the right.
   Both grids are valid: an explicit two-track top, and an auto-fit nav with NO
   flexible track mixed into the auto-fit (the prior 1.4fr+auto-fit was invalid
   CSS and collapsed to one column). */
.footer-top{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,2.6fr);gap:var(--s-9);align-items:start;}
.footer-brand .brand{margin-bottom:var(--s-5);}
.credo{font:550 var(--t-h3)/1.3 var(--font-display);color:var(--on-ink-hi);margin:0;max-width:34ch;}
.credo small{display:block;font:400 var(--t-body)/1.6 var(--font-text);color:var(--on-ink-mid);margin-top:var(--s-2);}
.footer-nav{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:var(--s-6);}
.footer-col h2{font-family:var(--font-mono);font-size:var(--t-eyebrow);font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--on-ink-mid);margin:0 0 var(--s-3);}
.footer-col ul{list-style:none;margin:0;padding:0;display:grid;gap:var(--s-2);}
.footer-col a{color:var(--on-ink-mid);font-size:var(--t-caption);}
.footer-col a:hover{color:var(--accent);}
.footer-meta{display:flex;flex-wrap:wrap;justify-content:space-between;gap:var(--s-4);margin-top:var(--s-8);padding-top:var(--s-5);border-top:var(--b-hairline) solid var(--ink-700);color:var(--on-ink-mid);font-size:var(--t-caption);}
.footer-meta a:hover{color:var(--accent);}
@media (max-width:760px){
  .footer-top{grid-template-columns:1fr;gap:var(--s-7);}
}

/* ── 3D / motion control (an unobtrusive footer item; the disable-motion
   control required by 3d-experience.md §4 + Constitution §J) ── */
.footer-motion{font:400 var(--t-caption)/1 var(--font-text);color:var(--on-ink-mid);
  background:none;border:0;padding:0;cursor:pointer;}
.footer-motion:hover{color:var(--accent);}

/* ── Inline icons (components/icon.php): scale with text, inherit colour ── */
.icon{width:1.15em;height:1.15em;display:inline-block;vertical-align:middle;flex:none;}

/* ── Social profile links (components/social.php) ── */
.social{display:flex;flex-wrap:wrap;gap:var(--s-3);list-style:none;margin:0;padding:0;}
.social-link{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);
  color:var(--on-ink-mid);text-decoration:none;
  transition:color var(--dur) var(--ease-standard),border-color var(--dur) var(--ease-standard),background var(--dur) var(--ease-standard);}
.social-link:hover,.social-link:focus-visible{color:var(--accent);}
.social-name{font-size:var(--t-caption);}
/* Footer + contact: icon chips in hairline circles that light up on the accent. */
.social--footer{margin-top:var(--s-5);}
.social--footer .social-link,.social--contact .social-link{
  width:40px;height:40px;border:var(--b-hairline) solid var(--ink-700);border-radius:50%;}
.social--footer .social-link:hover,.social--footer .social-link:focus-visible,
.social--contact .social-link:hover,.social--contact .social-link:focus-visible{
  border-color:var(--accent);background:color-mix(in srgb,var(--accent) 12%,transparent);}
.social--footer .icon,.social--contact .icon{width:18px;height:18px;}

/* ── Reveal-on-scroll motion (compositor-only: transform + opacity) ──
   Only hide reveals once JS confirms it can re-show them: the inline head
   script swaps html.no-js → html.js before first paint. With JS disabled the
   hidden state never applies, so every section reads perfectly (3d-experience
   §4: "fully usable with 3D off / the page must read perfectly with motion off"). */
html.js [data-reveal]{opacity:0;transform:translateY(var(--reveal-y));transition:opacity var(--dur-slow) var(--ease-cine),transform var(--dur-slow) var(--ease-cine);}
[data-reveal].is-in{opacity:1;transform:none;}

/* ── Scroll-as-film (homepage) ── */
.film-beat{min-height:90vh;display:flex;align-items:center;position:relative;}
.film-beat .container{position:relative;z-index:2;}
.beat-meta{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.08em;text-transform:uppercase;color:var(--on-ink-mid);margin-bottom:var(--s-4);}

/* ── House-of-eight chain ── */
.house-chain{display:flex;flex-wrap:wrap;gap:var(--s-2);align-items:stretch;margin-top:var(--s-6);}
.house-link{flex:1 1 140px;min-width:140px;padding:var(--s-5);background:var(--ink-800);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);position:relative;transition:border-color var(--dur),transform var(--dur);}
.house-link:hover{border-color:var(--accent);transform:translateY(-2px);}
.house-link .n{font-family:var(--font-mono);font-size:var(--t-eyebrow);color:var(--on-ink-mid);}
.house-link .name{font:550 var(--t-h4)/1.2 var(--font-display);margin:var(--s-2) 0 4px;}
.house-link .verb{font-family:var(--font-mono);font-size:var(--t-caption);color:var(--accent);}

/* ── Leaders ── */
.leader-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:var(--s-5);}
.leader{padding:var(--s-6);background:var(--ink-800);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);}
.leader .name{font:550 var(--t-h4)/1.2 var(--font-display);margin:0;}
.leader .role{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;text-transform:uppercase;color:var(--accent);margin:4px 0 var(--s-3);}
.leader .certain{color:var(--on-ink-mid);font-size:var(--t-body);}

/* ── Manifesto ── */
.manifesto p{font:400 var(--t-body-lg)/1.7 var(--font-display);color:var(--on-ink-mid);max-width:62ch;margin:0 0 var(--s-5);}
.manifesto p.lead{color:var(--on-ink-hi);font-weight:550;}
.manifesto p.close{font-size:var(--t-h3);color:var(--on-ink-hi);font-weight:600;}

/* ════════════════════════════════════════════════════════════════════════
   Cinematic homepage — slide-per-scroll film (homepage-cinematic.md).
   Full-screen 100vh slides; one idea each; baseline = text + dark-graded
   stills (works with no JS, no video, reduced motion). A persistent cyan
   connective thread ties the film together and takes the active slide's accent.
   ════════════════════════════════════════════════════════════════════════ */
/* Scroll-snap is enabled by JS AFTER load (the .snap-on class). Doing it on the
   root at first paint makes Chrome skip the LCP event (Lighthouse NO_LCP); and
   without JS the page still scrolls normally.

   Base for every film page is MANDATORY — crisp one-slide-per-scroll, like the
   homepage. (is-home-film is folded in here: it is just is-film, same rule.)
   The trailing FAQ rides along as a normal snap rest-point (it has
   scroll-snap-align), so sector pages stay mandatory AND readable. Only pages
   whose body genuinely exceeds the viewport — the Our Team roster and the
   conversion intake forms — carry a snap-relaxed token from PageController and
   relax to PROXIMITY via the html.snap-relaxed.snap-on rule near the is-cine
   block below. That rule is placed AFTER both is-film and is-cine so, at equal
   specificity (0,2,1), source order makes it win on both page families. */
html.is-film.snap-on{scroll-snap-type:y mandatory;}
/* On short viewports a slide's content can exceed the height; relax to
   proximity so mandatory snap can never trap scrolling. */
@media (max-height:680px){ html.is-film.snap-on{scroll-snap-type:y proximity;} }
.film{position:relative;}
.slide{position:relative;min-height:100vh;min-height:100svh;display:flex;align-items:center;
  scroll-snap-align:start;scroll-snap-stop:always;overflow:hidden;}
/* The footer is a snap point too, so snap settles on it cleanly instead of
   pulling back to the last slide. */
html.is-film .site-footer{scroll-snap-align:start;}
/* Sector hub film pages carry a trailing FAQ after the slides. Give it a gentle
   snap rest point (proximity, header-offset) so the page settles at the FAQ top
   on the way down; an expanded FAQ scrolls freely within itself. */
html.is-film .faq{scroll-snap-align:start;scroll-snap-stop:normal;scroll-margin-top:64px;}

/* ── Scroll-snap, app-wide (every non-film page) ────────────────────────────
   The homepage film snaps slide-to-slide (mandatory, above); every other page
   snaps gently to the top of each major section. PROXIMITY, never mandatory, so
   tall sections (spec tables, long bodies) can never trap scrolling. Enabled by
   the same JS `.snap-on` class (added on first interaction; honours
   reduced-motion / 3D-off — see app.js). scroll-padding-top offsets the sticky
   header so a snapped section's top isn't hidden behind it. */
html.snap-on:not(.is-film){scroll-snap-type:y proximity;scroll-padding-top:104px;}
@media (max-width:1100px){ html.snap-on:not(.is-film){scroll-padding-top:64px;} }
html.snap-on:not(.is-film) .hero,
html.snap-on:not(.is-film) .section,
html.snap-on:not(.is-film) .site-footer{scroll-snap-align:start;}
/* Decorative slide background as CSS (not an <img>): keeps the H1 text the sole
   LCP element and avoids an empty-alt full-screen image. */
.slide-bg{position:absolute;inset:0;z-index:0;background-color:var(--ink-900);overflow:hidden;will-change:transform;}
/* Responsive still (<picture><img>), explicit width/height for zero CLS; cover
   the slide. The poster also doubles as the lazy video's poster (app.js). */
.slide-poster{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;}
.slide-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
/* Dark cinematic grade — darker on the text (left) side so white copy always reads. */
.slide-grade{position:absolute;inset:0;z-index:1;background:
  linear-gradient(90deg, rgba(10,11,13,.82) 0%, rgba(10,11,13,.45) 48%, rgba(10,11,13,.12) 100%),
  linear-gradient(180deg, rgba(10,11,13,.55) 0%, rgba(10,11,13,.35) 40%, rgba(10,11,13,.8) 100%);}
.slide-inner{position:relative;z-index:2;width:100%;padding-block:var(--s-9);}
.slide-eyebrow{margin-bottom:var(--s-4);}
.slide-headline{font:600 var(--t-display-xl)/1.03 var(--font-display);letter-spacing:-0.02em;margin:0;max-width:18ch;color:var(--on-ink-hi);}
.slide[data-kind="sector"] .slide-headline,.slide[data-kind="system"] .slide-headline,.slide[data-kind="human"] .slide-headline,.slide[data-kind="connect"] .slide-headline{font-size:var(--t-h1);max-width:20ch;}
.slide-sub{font-size:var(--t-body-lg);color:var(--on-ink-mid);max-width:54ch;margin-top:var(--s-5);}
.slide-link{display:inline-flex;align-items:center;gap:8px;margin-top:var(--s-6);font:600 var(--t-body)/1 var(--font-text);color:var(--accent);}
.slide-link span{transition:transform var(--dur) var(--ease-standard);}
.slide-link:hover span{transform:translateX(4px);}
.slide-ctas{margin-top:var(--s-7);}
.slide-credo{margin-top:var(--s-6);font-size:var(--t-caption);color:var(--on-ink-mid);max-width:50ch;}
.slide-credo strong{color:var(--on-ink-hi);}

/* Per-slide text reveal (compositor-only). Hidden only when JS can re-show it. */
html.js .slide-inner > *{opacity:0;transform:translateY(18px);transition:opacity var(--dur-slow) var(--ease-cine),transform var(--dur-slow) var(--ease-cine);}
.slide.is-active .slide-inner > *{opacity:1;transform:none;}
/* A11y: reveal a non-active slide that receives keyboard focus (its CTA link is
   focusable even at opacity:0), so Tab never lands on an invisible control. */
html.js .slide:focus-within .slide-inner > *{opacity:1;transform:none;}
.slide.is-active .slide-inner > *:nth-child(2){transition-delay:60ms;}
.slide.is-active .slide-inner > *:nth-child(3){transition-delay:120ms;}
.slide.is-active .slide-inner > *:nth-child(4){transition-delay:180ms;}

/* Subtle Ken-Burns on the active slide's still. */
html.js .slide-bg{transform:scale(1.06);transition:transform 7s linear;}
html.js .slide.is-active .slide-bg{transform:scale(1.0);}

/* Scroll cue (slide 00). */
.scroll-cue{position:absolute;left:var(--gutter);bottom:var(--s-7);display:inline-flex;align-items:center;gap:10px;
  font:500 var(--t-eyebrow)/1 var(--font-mono);letter-spacing:0.12em;text-transform:uppercase;color:var(--on-ink-mid);}
.scroll-cue-dot{width:18px;height:28px;border:1.5px solid var(--on-ink-mid);border-radius:10px;position:relative;}
.scroll-cue-dot::after{content:"";position:absolute;left:50%;top:6px;width:3px;height:6px;border-radius:2px;background:var(--accent);transform:translateX(-50%);animation:cue 1.6s ease-in-out infinite;}
@keyframes cue{0%,100%{opacity:0;transform:translate(-50%,0)}50%{opacity:1;transform:translate(-50%,9px)}}

/* Section rail (homepage + sector films) now reuses the shared right-side rail
   — .cine-rail / .cine-rail-line / .cine-rail-fill / .cine-dot (further down,
   in the cinematic scaffold) — so it looks and sits exactly like About and the
   cinematic pages: same dots, labels, accent fill, same right-edge position.
   Driven by initFilm() (app.js), which lights the active .film-dot (also a
   .cine-dot) and advances the fill. The old left-edge "connective thread" line
   is retired. On narrow screens reserve a right gutter so slide copy never runs
   under the fixed rail (mirrors .cine-content's gutter on the cinematic pages). */
@media (max-width:760px){ html.is-film .slide-inner{padding-right:clamp(36px,9vw,44px);} }

/* ════════════════════════════════════════════════════════════════════════
   Cinematic vehicle pages (vehicles-autorun.md). Reuse the film engine; these
   sections can exceed 100vh (spec tables, model copy), so they grow rather than
   clip — mandatory snap still settles on each section start.
   ════════════════════════════════════════════════════════════════════════ */
.film--sector .slide{height:auto;overflow:visible;}
.film--sector .slide-inner{padding-block:var(--s-9);width:100%;}
.film--sector .slide--specs{align-items:flex-start;}

/* Model-beside-product: cinematic shot left, product right (stacks on mobile). */
.model-grid{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(24px,5vw,72px);align-items:center;width:100%;}
.model-shot{position:relative;aspect-ratio:16/9;border-radius:12px;overflow:hidden;border:var(--b-hairline) solid var(--ink-700);background:var(--ink-800);box-shadow:0 30px 60px rgba(0,0,0,.45);}
.model-shot img{width:100%;height:100%;object-fit:cover;display:block;}
.model-shot--placeholder{display:flex;align-items:center;justify-content:center;background:linear-gradient(160deg,var(--ink-700),var(--ink-850));}
.model-shot-tag{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.12em;text-transform:uppercase;color:var(--on-ink-mid);border:var(--b-hairline) dashed var(--ink-600);padding:6px 12px;border-radius:var(--r-sm);}

/* Foreground product gallery — the "3D slide": angle frames crossfade inside the
   .model-shot box, driven by drag / arrows / dots / arrow-keys (initProductGallery
   in app.js). A FOREGROUND product viewer, never a section background. */
.model-gallery{cursor:grab;touch-action:pan-y;outline:none;}
.model-gallery:active{cursor:grabbing;}
.model-gallery:focus-visible{box-shadow:0 0 0 2px var(--accent),0 30px 60px rgba(0,0,0,.45);}
.model-gallery-frame{position:absolute;inset:0;margin:0;opacity:0;transition:opacity .45s var(--ease-standard);will-change:opacity;}
.model-gallery-frame.is-current{opacity:1;}
.model-gallery-frame img{width:100%;height:100%;object-fit:cover;display:block;-webkit-user-select:none;user-select:none;}
.model-gallery-arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:3;width:38px;height:38px;border-radius:50%;
  border:var(--b-hairline) solid rgba(255,255,255,.18);background:rgba(10,11,13,.5);color:var(--on-ink-hi);
  font-size:20px;line-height:1;cursor:pointer;display:grid;place-items:center;backdrop-filter:blur(4px);
  transition:background var(--dur) var(--ease-standard);}
.model-gallery-arrow:hover{background:rgba(10,11,13,.8);}
.model-gallery-arrow--prev{left:10px;}
.model-gallery-arrow--next{right:10px;}
.model-gallery-dots{position:absolute;left:0;right:0;bottom:10px;z-index:3;display:flex;gap:7px;justify-content:center;}
.model-gallery-dot{width:7px;height:7px;border-radius:50%;border:none;padding:0;cursor:pointer;background:rgba(255,255,255,.4);
  transition:background var(--dur) var(--ease-standard),transform var(--dur) var(--ease-standard);}
.model-gallery-dot.is-current{background:var(--accent);box-shadow:0 0 8px var(--accent);transform:scale(1.25);}
.model-gallery-hint{position:absolute;top:9px;right:10px;z-index:3;font-family:var(--font-mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--on-ink-mid);background:rgba(10,11,13,.45);padding:3px 7px;border-radius:99px;pointer-events:none;
  transition:opacity var(--dur) var(--ease-standard);}
.model-gallery.is-touched .model-gallery-hint{opacity:0;}
/* Cut-out mode: a transparent product (background removed) shown WHOLE on a clean
   studio panel — soft radial backdrop + a grounding drop shadow under the vehicle. */
.model-gallery--cutout{background:radial-gradient(120% 100% at 50% 16%, #1b2228 0%, var(--ink-850) 58%, var(--ink-900) 100%);}
.model-gallery--cutout .model-gallery-frame{padding:clamp(14px,3.5%,34px);box-sizing:border-box;}
.model-gallery--cutout .model-gallery-frame img{object-fit:contain;filter:drop-shadow(0 16px 20px rgba(0,0,0,.5));}
@media (prefers-reduced-motion:reduce){ .model-gallery-frame{transition:none;} }
.model-name{font:600 var(--t-h1)/1.05 var(--font-display);letter-spacing:-0.015em;margin:0;color:var(--on-ink-hi);}
.model-tagline{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.08em;text-transform:uppercase;color:var(--accent);margin:var(--s-2) 0 var(--s-4);}
.model-specs{list-style:none;margin:0 0 var(--s-4);padding:0;display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-5);}
.model-specs li{font-size:var(--t-body-lg);color:var(--on-ink-hi);font-variant-numeric:tabular-nums;position:relative;}
.model-specs li + li::before{content:"·";position:absolute;left:calc(-1 * var(--s-3) - 2px);color:var(--on-ink-mid);}
.model-note{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;text-transform:uppercase;color:var(--on-ink-mid);margin:0 0 var(--s-4);}
@media (max-width:900px){ .model-grid{grid-template-columns:1fr;gap:var(--s-6);} .model-shot{order:-1;} }

/* Mission & vision. */
.mv-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:clamp(24px,4vw,56px);margin-top:var(--s-5);}
.mv-lead{font:550 var(--t-h3)/1.2 var(--font-display);color:var(--on-ink-hi);margin:var(--s-2) 0;}

/* Spec table inside a snap section (dark slide). */
.slide-spec-table{width:100%;margin-top:var(--s-5);background:color-mix(in srgb,var(--ink-900) 72%,transparent);border:var(--b-hairline) solid var(--ink-700);border-radius:var(--r-sm);overflow:auto;}
.spec-links{margin-top:var(--s-6);}
.spec-links .pill{display:inline-block;padding:6px var(--s-4);border:var(--b-hairline) solid var(--ink-600);border-radius:999px;color:var(--on-ink-hi);font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.06em;text-transform:uppercase;transition:border-color var(--dur),color var(--dur);}
.spec-links .pill:hover{border-color:var(--accent);color:var(--accent);}

/* ── Utilities ── */
.stack-6 > * + *{margin-top:var(--s-6);}
.stack-4 > * + *{margin-top:var(--s-4);}
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:var(--s-7);}
.pill-list{display:flex;flex-wrap:wrap;gap:var(--s-2);list-style:none;margin:0;padding:0;}
.text-center{text-align:center;}
.lede{font-size:var(--t-body-lg);color:var(--on-ink-mid);}
.gated-badge{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:0.08em;text-transform:uppercase;color:var(--graphite-base);border:var(--b-hairline) solid var(--graphite-deep);padding:4px var(--s-3);border-radius:var(--r-sm);display:inline-block;}

/* ════════════════════════════════════════════════════════════════════════
   prefers-reduced-motion — all transforms + scroll-scrub disabled; reveals
   become a simple ≤120ms opacity fade; the thread renders final and still.
   Also applied when the user forces "3D off" (html.no-motion).
   ════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:120ms!important;scroll-behavior:auto!important;}
  html.js [data-reveal],[data-reveal]{opacity:1;transform:none;transition:opacity 120ms linear;}
  .sector-card::before{transition:none;transform:scaleY(1);}
  /* Film: static stills, instant text, no parallax/Ken-Burns/autoplay/snap. */
  html.is-film{scroll-snap-type:none;}
  html.js .slide-inner > *{opacity:1;transform:none;}
  html.js .slide-bg{transform:none;transition:none;}
  .scroll-cue-dot::after{animation:none;}
}
html.no-motion [data-reveal]{opacity:1;transform:none;}
html.no-motion .sector-card::before{transform:scaleY(1);}
html.no-motion .hero-canvas canvas{display:none;}
/* "3D / motion off" also calms the film: static stills, instant text, no snap. */
html.no-motion.is-film{scroll-snap-type:none;}
html.no-motion .slide-inner > *{opacity:1;transform:none;}
html.no-motion .slide-bg{transform:none;transition:none;}
html.no-motion .scroll-cue-dot::after{animation:none;}

/* ── FAQ ───────────────────────────────────────────────────────────────────
   Visible <details> accordion rendered after page content, mirroring the
   FAQPage JSON-LD. No JS: native disclosure, fully crawlable + accessible.
   Not a scroll-snap target (no scroll-snap-align), so it sits in normal flow
   after the cinematic sections, exactly like the footer. */
.faq .faq-title{margin:var(--s-3) 0 var(--s-6);}
.faq-list{max-width:760px;display:flex;flex-direction:column;gap:var(--s-3);}
.faq-item{border:1px solid var(--ink-700);border-radius:12px;background:var(--ink-850);}
.faq-q{cursor:pointer;list-style:none;padding:var(--s-4) var(--s-5);font-weight:600;
  color:var(--on-ink-hi);display:flex;justify-content:space-between;align-items:center;gap:var(--s-4);}
.faq-q::-webkit-details-marker{display:none;}
.faq-q::after{content:"+";color:var(--accent);font-size:1.25em;line-height:1;flex:none;}
.faq-item[open] .faq-q::after{content:"\2013";}
.faq-q:hover{color:var(--accent);}
.faq-q:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:8px;}
.faq-a{padding:0 var(--s-5) var(--s-5);color:var(--on-ink-mid);}
.faq-a p{margin:0;max-width:64ch;}

/* ── Insights article (long-form guide; reading-first, not a snap film) ─────── */
/* Optional persona hero banner — decorative; the title text stays the LCP element.
   Full-bleed, graded so the bottom melts into the near-black page and a soft left
   vignette echoes the brand "left third dark" grammar. Absent → header on plain dark. */
.article-hero{position:relative;width:100%;height:clamp(240px,42vw,440px);overflow:hidden;background:var(--ink-900);}
.article-hero-bg{position:absolute;inset:0;background-size:cover;background-position:center;background-color:var(--ink-900);}
.article-hero-fade{position:absolute;inset:0;
  background:
    radial-gradient(120% 80% at 16% 50%, rgba(10,11,13,.55), transparent 58%),
    linear-gradient(180deg, rgba(10,11,13,.45) 0%, rgba(10,11,13,0) 26%, rgba(10,11,13,.55) 76%, var(--ink-900) 100%);}
.article-head--hero{padding-top:var(--s-6);}
@media (max-width:640px){.article-hero{height:clamp(180px,52vw,300px);}}
.article-title{margin-top:var(--s-3);}
.article-dek{margin-top:var(--s-4);}
.article-meta{display:flex;flex-wrap:wrap;gap:var(--s-5);margin-top:var(--s-4);
  color:var(--on-ink-mid);font-size:.875rem;letter-spacing:.02em;}
.article-takeaways{margin-top:var(--s-6);max-width:760px;}
.article-grid{display:grid;grid-template-columns:230px minmax(0,1fr);gap:var(--s-8);align-items:start;}
@media (max-width:900px){.article-grid{grid-template-columns:1fr;}}
.article-toc{position:sticky;top:104px;}
.article-toc ol{list-style:none;padding:0;margin:var(--s-3) 0 0;display:flex;flex-direction:column;gap:var(--s-2);}
.article-toc a{color:var(--on-ink-mid);text-decoration:none;font-size:.9rem;line-height:1.4;}
.article-toc a:hover{color:var(--accent);}
@media (max-width:900px){.article-toc{position:static;}}
.article-body h2{margin-top:var(--s-7);}
.article-body h3{margin-top:var(--s-5);}
.article-body p{margin:var(--s-4) 0;color:var(--on-ink-mid);}
.article-list{margin:var(--s-4) 0;padding-left:1.2em;display:flex;flex-direction:column;gap:var(--s-2);color:var(--on-ink-mid);}
/* Use the column width instead of stranding the right gutter (the body carried a
   64ch `measure` cap inside a much wider grid column). The body now fills its
   column; prose + bullet lists keep a readable measure, while the comparison
   tables span the full column so the data uses the horizontal space. */
.article-body{max-width:none;}
.article-body p,
.article-body .article-intro-p,
.article-body .article-list{max-width:78ch;}
.article-table-wrap{overflow-x:auto;margin:var(--s-5) 0;max-width:none;}
/* Long-form reading width: keep the header + body in a tidy column so the leftover
   space reads as a balanced page margin rather than a wide, lopsided right gutter,
   while the body column itself widens (prose to 78ch, comparison tables full-width). */
.article-head > .container,
.article-wrap > .container{max-width:1180px;}
.article-table{width:100%;border-collapse:collapse;font-size:.95rem;}
.article-table caption{text-align:left;color:var(--on-ink-mid);margin-bottom:var(--s-3);}
.article-table th,.article-table td{text-align:left;padding:var(--s-3) var(--s-4);
  border-bottom:1px solid var(--ink-700);vertical-align:top;}
.article-table th{color:var(--on-ink-hi);font-weight:600;}
.article-table td{color:var(--on-ink-mid);}
.article-related{margin-top:var(--s-8);border-top:1px solid var(--ink-700);padding-top:var(--s-5);}
.article-related ul{list-style:none;padding:0;margin:var(--s-3) 0 0;display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-6);}
.article-related a{color:var(--accent);text-decoration:none;}
.article-cta{margin-top:var(--s-7);}

/* ── Further reading (product/service → Insights guide back-links) ──────────── */
.further-reading .fr-title{margin:var(--s-3) 0 var(--s-6);}
.fr-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:var(--s-4);}
.fr-card{display:flex;flex-direction:column;gap:var(--s-2);padding:var(--s-5);
  border:1px solid var(--ink-700);border-radius:12px;background:var(--ink-850);
  text-decoration:none;transition:border-color .2s ease,transform .2s ease;}
.fr-card:hover{border-color:var(--accent);transform:translateY(-2px);}
.fr-card:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.fr-kicker{font-size:.75rem;text-transform:uppercase;letter-spacing:.08em;color:var(--accent);}
.fr-name{color:var(--on-ink-hi);font-weight:600;line-height:1.3;}
.fr-desc{color:var(--on-ink-mid);font-size:.9rem;line-height:1.45;}
.fr-go{color:var(--accent);font-size:.875rem;margin-top:var(--s-2);}
@media (prefers-reduced-motion:reduce){.fr-card{transition:none;}.fr-card:hover{transform:none;}}
.insights-grid{margin-top:var(--s-7);}

/* Utilities — extracted from former inline style="" attributes so the CSP can
   drop 'unsafe-inline' for styles (see Core\Security + Core\Styles). */
.u-jc-center{justify-content:center;}
.u-mi-auto{margin-inline:auto;}
.u-mt-4{margin-top:var(--s-4);}
.u-mt-5{margin-top:var(--s-5);}
.u-mt-6{margin-top:var(--s-6);}
.u-mt-7{margin-top:var(--s-7);}
.section--center{min-height:60vh;display:flex;align-items:center;}

/* ════════════════════════════════════════════════════════════════════════
   Cinematic scaffold — the shared scroll-snap "beat" chrome behind the sector
   films (energy, ai, agritech, defence, labs, lease, ongoing-projects,
   leadership, conversion). Prefix-agnostic rules live here as .cine-* and are
   applied alongside each sector's .{prefix}-* class in its view template;
   sector stylesheets keep only genuinely sector-specific rules plus the few
   divergent overrides (e.g. Defence's matte "firewall"), which load after
   app.css and win at equal specificity. The accent swaps per sector via
   [data-accent] (tokens.css), so no per-sector colour overrides are needed.
   (About keeps its own legacy film-pattern stylesheet and opts out of .cine-*.)
   Off-grid micro-spacing is snapped to the --s- grid (fact gap 14→16px=--s-4,
   fact row padding 10→12px=--s-3, dot 7→8px=--s-2 — a deliberate ≤2px tidy-up);
   the 26×28 dot hit-area and 6px rail offset stay verbatim as component sizes. */

/* Root scroll-snap — switched on app-wide by initScrollSnap() (.snap-on).
   MANDATORY by default for crisp beat-to-beat scrolling, matching the film
   hubs. Only pages whose body genuinely exceeds the viewport — the leadership
   "Our Team" roster (~9 cards) and the conversion intake forms — get a
   snap-relaxed token from PageController and fall back to PROXIMITY via the
   override below. (A trailing FAQ does NOT relax the page: it has
   scroll-snap-align and reads fine as a snap section under mandatory.) */
html.is-cine.snap-on{scroll-snap-type:y mandatory;}
html.is-cine .site-footer{scroll-snap-align:start;}
/* ── snap-relaxed override (PROXIMITY) ──────────────────────────────────────
   PageController tags the Our Team roster and the conversion pages with
   snap-relaxed. This rule is specificity (0,2,1) —
   identical to the is-film and is-cine defaults — so it cannot out-rank them on
   specificity; it wins purely on SOURCE ORDER. It MUST sit after BOTH default
   blocks (is-film ~line 557, is-cine just above) so it overrides mandatory on
   film AND cine pages alike. */
html.snap-relaxed.snap-on{scroll-snap-type:y proximity;}
/* Short-viewport safety for the still-mandatory cinematic pages (the relaxed
   ones are already proximity above). Placed last so it always applies. */
@media (max-height:680px){
  html.is-cine.snap-on{scroll-snap-type:y proximity;}
}

/* Beat shell */
.cine-beat{position:relative;min-height:100vh;min-height:100svh;display:flex;align-items:center;
  padding-block:var(--s-9);overflow:hidden;scroll-snap-align:start;scroll-snap-stop:always;}
.cine-bg{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center;background-color:var(--ink-900);}
.cine-grade{position:absolute;inset:0;z-index:1;
  background:radial-gradient(120% 90% at 16% 100%, rgba(0,0,0,.5), transparent 55%),
             linear-gradient(90deg, rgba(10,11,13,.9) 0%, rgba(10,11,13,.55) 45%, rgba(10,11,13,.2) 100%);}
.cine-beat-inner{position:relative;z-index:2;width:100%;}

/* Typography */
.cine-eyebrow{font-family:var(--font-mono);font-size:var(--t-eyebrow);letter-spacing:.18em;text-transform:uppercase;
  color:var(--accent);margin:0 0 var(--s-4);}
.cine-h1{font:600 var(--t-display-xl)/1.03 var(--font-display);letter-spacing:-.02em;margin:0 0 var(--s-4);color:var(--on-ink-hi);max-width:16ch;}
.cine-h2{font:600 var(--t-h1)/1.05 var(--font-display);letter-spacing:-.02em;margin:0 0 var(--s-4);color:var(--on-ink-hi);max-width:20ch;}
.cine-sub{font-size:var(--t-body-lg);line-height:1.5;color:var(--on-ink-mid);margin:0;max-width:48ch;}
.cine-body{font-size:var(--t-body);line-height:1.6;color:var(--on-ink-mid);margin:0;max-width:54ch;}

/* Picture-beside-service (two-column; stacks picture-first on mobile) */
.cine-beat-inner--split{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  gap:clamp(24px,4vw,64px);align-items:center;}
.cine-pic{position:relative;}
.cine-pic img{width:100%;height:auto;aspect-ratio:4/3;object-fit:cover;display:block;
  border-radius:var(--r-md);border:var(--b-hairline) solid var(--ink-700);background:var(--ink-800);
  box-shadow:0 24px 60px rgba(0,0,0,.45);}
.cine-service-name{font-family:var(--font-mono);font-size:var(--t-fine);letter-spacing:.12em;text-transform:uppercase;
  color:var(--on-ink-mid);margin:0 0 var(--s-2);}
.cine-service-line{margin-bottom:var(--s-4);}

/* Facts */
.cine-facts{margin:var(--s-5) 0 0;max-width:54ch;}
.cine-fact{display:grid;grid-template-columns:minmax(120px,12ch) 1fr;gap:var(--s-4);padding:var(--s-3) 0;
  border-top:var(--b-hairline) solid var(--ink-700);}
.cine-fact dt{font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.08em;text-transform:uppercase;color:var(--accent);}
.cine-fact dd{margin:0;color:var(--on-ink-hi);font-size:var(--t-detail);line-height:1.4;}

/* Link */
.cine-link{display:inline-flex;align-items:center;gap:8px;margin-top:var(--s-5);
  font:600 var(--t-body)/1 var(--font-text);color:var(--accent);text-decoration:none;}
.cine-link span{transition:transform var(--dur) var(--ease-standard);}
.cine-link:hover span{transform:translateX(4px);}

/* Connect */
.cine-ctas{margin-top:var(--s-7);}
.cine-credo{margin-top:var(--s-6);font-size:var(--t-caption);color:var(--on-ink-mid);line-height:1.6;max-width:52ch;}
.cine-cue{z-index:3;}

/* Progress rail — fixed, right; real in-page anchors (work without JS) */
.cine-rail{position:fixed;right:clamp(10px,2.4vw,30px);top:50%;transform:translateY(-50%);z-index:var(--z-sticky);
  display:flex;flex-direction:column;align-items:center;}
.cine-rail-line{position:absolute;top:6px;bottom:6px;width:1px;background:var(--ink-700);}
.cine-rail-fill{position:absolute;top:6px;width:1px;height:0;background:var(--accent);box-shadow:0 0 8px var(--accent);
  transition:height var(--dur-slow) var(--ease-standard),background var(--dur-slow) var(--ease-standard);}
.cine-dot{position:relative;width:26px;height:28px;display:flex;align-items:center;justify-content:center;text-decoration:none;}
.cine-dot i{width:var(--s-2);height:var(--s-2);border-radius:50%;background:var(--ink-600);border:1px solid var(--ink-700);
  transition:transform var(--dur) var(--ease-standard),background var(--dur) var(--ease-standard),border-color var(--dur) var(--ease-standard),box-shadow var(--dur) var(--ease-standard);}
.cine-dot.is-current i{background:var(--accent);border-color:var(--accent);box-shadow:0 0 10px var(--accent);transform:scale(1.25);}
.cine-dot-label{position:absolute;right:32px;white-space:nowrap;font-family:var(--font-mono);font-size:var(--t-micro);letter-spacing:.1em;
  text-transform:uppercase;color:var(--on-ink-mid);opacity:0;transform:translateX(6px);
  transition:opacity var(--dur) var(--ease-standard),transform var(--dur) var(--ease-standard);pointer-events:none;}
.cine-dot:hover .cine-dot-label,.cine-dot:focus-visible .cine-dot-label,.cine-dot.is-current .cine-dot-label{opacity:1;transform:none;}

/* Reveal — first beat ships .is-active so it paints at once; with no JS the
   html.js gate never applies, so all content is visible. */
html.js .cine-content{opacity:0;transform:translateY(var(--reveal-y));
  transition:opacity var(--dur-slow) var(--ease-cine),transform var(--dur-slow) var(--ease-cine);}
html.js .cine-beat.is-active .cine-content{opacity:1;transform:none;}
/* A11y: a non-active beat is opacity:0 yet still holds focusable CTAs — reveal it
   when keyboard focus lands inside so a Tab never targets an invisible link. */
html.js .cine-beat:focus-within .cine-content{opacity:1;transform:none;}

/* Responsive */
@media (max-width:880px){
  .cine-beat-inner--split{grid-template-columns:1fr;gap:var(--s-6);}
}
@media (max-width:760px){
  .cine-rail{right:10px;}
  .cine-dot-label{display:none;}
  /* Reserve a gutter so wrapped content never runs under the fixed rail. */
  .cine-content{padding-right:clamp(40px,10vw,48px);}
}

/* Motion off */
@media (prefers-reduced-motion:reduce){
  html.is-cine{scroll-snap-type:none;}
  .cine-content{opacity:1!important;transform:none!important;}
  .cine-rail-fill{transition:none;}
}
html.no-motion.is-cine{scroll-snap-type:none;}
html.no-motion.is-cine .cine-content{opacity:1;transform:none;}

/* ════════════════════════════════════════════════════════════════════════
   Back-to-top — a fixed control bottom-right with a circular scroll-progress
   ring (the ring fills as you descend the page). Reveals once the page is
   scrolled past the first viewport; clicking returns to the top (smooth, or
   instant under reduced-motion / 3D-off) and moves focus to the document top.
   Positioned bottom-right, clear of the centred right section rail (.cine-rail).
   A pure JS enhancement (app.js initToTop): hidden + non-focusable until shown,
   so it costs nothing and never traps a tab stop without JS. ════════════════ */
.to-top{position:fixed;right:clamp(16px,3vw,28px);bottom:clamp(16px,3vw,28px);
  width:48px;height:48px;display:grid;place-items:center;border-radius:50%;
  background:color-mix(in srgb,var(--ink-800) 84%,transparent);
  border:var(--b-hairline) solid var(--ink-700);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  color:var(--on-ink-hi);z-index:var(--z-sticky);cursor:pointer;
  opacity:0;visibility:hidden;transform:translateY(10px) scale(.94);pointer-events:none;
  transition:opacity var(--dur) var(--ease-standard),transform var(--dur) var(--ease-cine),
             border-color var(--dur) var(--ease-standard),box-shadow var(--dur) var(--ease-standard),
             visibility 0s linear var(--dur);}
.to-top.is-visible{opacity:1;visibility:visible;transform:none;pointer-events:auto;transition-delay:0s;}
.to-top:hover{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),0 12px 32px rgba(0,0,0,.5);transform:translateY(-2px);}
.to-top:focus-visible{outline:2px solid var(--focus);outline-offset:3px;}
.to-top-arrow{position:relative;z-index:1;width:20px;height:20px;color:var(--on-ink-hi);
  transition:transform var(--dur) var(--ease-cine);}
.to-top:hover .to-top-arrow{transform:translateY(-2px);}
.to-top-ring{position:absolute;inset:0;width:100%;height:100%;transform:rotate(-90deg);overflow:visible;}
.to-top-track{fill:none;stroke:var(--ink-700);stroke-width:2;}
.to-top-progress{fill:none;stroke:var(--accent);stroke-width:2;stroke-linecap:round;
  filter:drop-shadow(0 0 4px var(--accent));transition:stroke-dashoffset var(--dur) linear;}
/* Defence keeps its no-glow firewall — drop the ring glow on the graphite accent. */
[data-accent="graphite"] .to-top-progress{filter:none;}
@media (max-width:760px){ .to-top{width:44px;height:44px;} }
@media (prefers-reduced-motion:reduce){
  .to-top,.to-top:hover{transform:none;transition:opacity var(--dur) linear,visibility 0s linear var(--dur);}
  .to-top-arrow,.to-top-progress{transition:none;}
}
html.no-motion .to-top,html.no-motion .to-top:hover{transform:none;}
html.no-motion .to-top-progress{transition:none;}
