/* ============================================================
   Lambertiana — page layer on top of the FUTURE design system.
   Loaded after future/styles.css. Authors against the semantic
   tokens only; no raw ramp values, no new colours.

   Structure follows the FUTURE "Studio landing page" template:
   ink hero → ruled paper bands → ink statement band → ink footer.
   ============================================================ */

html { scroll-behavior: smooth; scroll-padding-top: 96px; }
body { overflow-x: hidden; }

/* ── Paper ramp override — cool porcelain, not warm oat ───────
   Standing rule from Mario (2026-07-28): no cream/beige/warm-oat
   backgrounds, ever — the linen field reads as AI-generated. The
   vendored FUTURE tokens stay byte-faithful for re-pull diffs, so
   the whole ramp is re-pointed here at the page layer instead.
   Loaded after future/styles.css, same specificity, later wins.
   Every component that references the ramp follows automatically,
   on both pages. */
:root {
  --paper-000: #FFFFFF;
  --paper-100: #F6F7F8;
  --paper-200: #ECEEF0;
  --paper-300: #DFE2E5;
  --paper-400: #C8CDD2;
}

/* ── Nav ──────────────────────────────────────────────────────
   Loro Labs' composition — a nav that floats as an inset island
   rather than spanning as a band, brand left, links centred,
   action right — rendered in FUTURE's grammar: square corners,
   1px hairline, glass, no shadow, uppercase labels, no icons.

   It flips scope once, at the hero's bottom edge: ink glass over
   the hero, paper glass past it. Toggling data-surface rescopes
   every custom property the subtree resolves through, which is
   the documented scope-flip trap — .fut-scope-flip on the island
   is the system's own remedy and is why this has no transition.

   The system's readme reaches for a two-nav CSS-only trick here
   because scroll listeners "proved unreliable in preview". That
   is a preview-sandbox constraint, not a browser one, so this
   uses one fixed island and an 8-line scroll listener instead:
   the nav then stays visible mid-hero, which the two-nav trick
   cannot do. */
.site-nav {
  position: fixed; top: 16px; left: 0; right: 0; z-index: 50;
  padding-inline: var(--gutter-lg); pointer-events: none;
}
/* No scrim above the island. A gradient in --canvas painted paper over
   the ink bands as they passed under the nav, which was worse than the
   problem it solved. A floating island simply has page around it — that
   is the Loro read — so the fix is to make the bar itself opaque enough
   that nothing is legible THROUGH it, and let content pass beside it. */
.site-nav__island {
  pointer-events: auto;
  max-width: var(--container-max); margin-inline: auto;
  display: flex; align-items: center; gap: var(--space-6);
  height: 60px; padding-inline: var(--space-5);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  background: rgba(246,247,248,.65);
  backdrop-filter: blur(var(--blur-glass));
  -webkit-backdrop-filter: blur(var(--blur-glass));
}
/* /mario's island still declares the ink scope, so its buttons are
   --inverse (paper chip on dark). Painting that island paper made
   them paper-on-paper and invisible: the scope in the markup is the
   contract, so honour it here. */
.site-nav__island[data-surface="ink"] { background: rgba(16,17,18,.42); }
/* Paper glass over the paper hero; opaque paper past it — the bar
   crosses the ink bands below the fold, and at any transparency the
   copy underneath stayed readable through it. Blur for edge quality. */
.site-nav.is-scrolled .site-nav__island {
  background: var(--paper-100); border-color: var(--border-subtle);
}
/* flex: 0 1 auto + min-width:0, not flex:none — at 320px an unshrinkable
   brand pushed the hamburger clean off the viewport, and it is the only
   navigation control on mobile. */
.site-nav__brand {
  display: flex; align-items: baseline; gap: var(--space-3);
  text-decoration: none; color: var(--text-primary);
  flex: 0 1 auto; min-width: 0; overflow: hidden;
}
.site-nav__mark { white-space: nowrap; }
.site-nav__mark {
  font-family: var(--font-display); font-weight: var(--weight-medium);
  font-size: 21px; letter-spacing: -.01em;
}
.site-nav__role {
  font-size: 10px; font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-tertiary);
}
.site-nav__links {
  display: flex; align-items: center; gap: var(--space-6);
  margin-inline: auto;
}
.site-nav__link {
  font-size: var(--size-label); font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-secondary); text-decoration: none;
  padding: var(--space-1) 0; position: relative;
}
.site-nav__link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 2px; background: var(--accent); opacity: 0;
}
.site-nav__link:hover { color: var(--text-primary); }
.site-nav__link[aria-current="true"] { color: var(--text-primary); }
.site-nav__link[aria-current="true"]::after { opacity: 1; }
.site-nav__action { flex: none; }

/* Skip link — the site had none. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--surface-inverse); color: var(--text-inverse);
  padding: var(--space-3) var(--space-4);
  font-size: var(--size-label); letter-spacing: var(--track-label);
  text-transform: uppercase; font-weight: var(--weight-semibold);
  text-decoration: none;
}
.skip:focus { left: 0; }

/* ── Hero ─────────────────────────────────────────────────────
   Shared shell. Both pages use it, and they are NOT the same
   surface: /mario keeps the original full-bleed INK hero, the
   advisory homepage inverts to the porcelain field below. So the
   base stays ink — repainting it here silently turned /mario's
   hero white while its ink-scope tokens kept rendering near-white
   type on it. Paint belongs on the modifier, never on the base. */
.hero {
  position: relative; min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--ink-900); color: var(--paper-100);
}
.hero__texture, .hero__scrim { position: absolute; inset: 0; pointer-events: none; }
.hero__texture {
  background:
    repeating-linear-gradient(135deg, rgba(244,241,234,.035) 0 1px, transparent 1px 14px),
    radial-gradient(120% 100% at 72% 18%, #26282C 0%, var(--ink-900) 62%);
}
.hero__scrim { background: var(--scrim-bottom); }

/* ── Hero, advisory homepage — the porcelain field ────────────
   Full-viewport cool paper. The texture is the finish: a 135° ink
   hatch drifting over cool radial lifts (white at top right, cool
   grey pooling bottom left). No photography, no glow blobs — the
   helix is the image. */
.hero--field { background: var(--paper-100); color: var(--ink-900); }
.hero--field .hero__texture {
  background:
    radial-gradient(90% 80% at 70% 12%, #FFFFFF 0%, rgba(255,255,255,0) 55%),
    radial-gradient(120% 90% at 12% 92%, rgba(200,205,210,.5) 0%, rgba(200,205,210,0) 58%),
    var(--paper-100);
}
/* The hatch rides its own layer so only IT drifts — animating
   background-position on .hero__texture would slide the radial
   lifts too. */
.hero--field .hero__texture::after {
  content: ""; position: absolute; inset: 0 -360px -360px 0;
  /* .045, not .03: this is the structure the glass plates refract,
     so it has to survive a 10px blur and still read as lines. */
  background: repeating-linear-gradient(135deg, rgba(16,17,18,.045) 0 1px, transparent 1px 14px);
  animation: hatch-drift 90s linear infinite;
}
/* -336.6px ≈ 34 repeats of the 14px period projected onto the 135°
   axis (34·14/√2), so the loop closes without a visible phase jump. */
@keyframes hatch-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-336.6px, -336.6px, 0); }
}

/* ── Field glass ──────────────────────────────────────────────
   Three large frosted sheets laid over the field at shallow
   angles. The blur is doing real work: the hatch drifting under
   them is the structure that refracts, which is what separates
   glass from a painted gradient — hence the hatch runs BELOW
   this layer, never above it.

   Deliberately not soft: hairline edges, flat planes, no radius,
   no glow. Depth comes from the overlaps, where two plates stack
   and the tint doubles. They drift slowly out of phase so the
   refraction keeps moving without anything visibly sliding. */
.hero__panels { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.hero__panel {
  position: absolute;
  border: 1px solid rgba(16,17,18,.14);
  /* Low fill on purpose. At .6 white the plate goes opaque, the hatch
     dies inside it and the whole thing reads as fog. The tell for
     glass is the SAME structure continuing through the plate, only
     blurred and lifted — so the fill stays thin and the blur does
     the work. */
  background: linear-gradient(140deg,
    rgba(255,255,255,.40), rgba(255,255,255,.05) 46%, rgba(200,205,210,.20));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.8);
  backdrop-filter: blur(10px) saturate(1.08);
  -webkit-backdrop-filter: blur(10px) saturate(1.08);
  animation: panel-float 30s ease-in-out infinite alternate;
}
.hero__panel--a {
  left: -10vw; top: -10vh; width: 64vw; height: 56vh;
  transform: rotate(-9deg);
}
.hero__panel--b {
  right: -12vw; top: 14vh; width: 58vw; height: 50vh;
  transform: rotate(7deg);
  animation-duration: 38s; animation-delay: -12s;
}
.hero__panel--c {
  left: 4vw; bottom: -16vh; width: 78vw; height: 46vh;
  transform: rotate(-4deg);
  animation-duration: 34s; animation-delay: -22s;
}
/* Translate only — rotating a backdrop-filtered plate re-samples the
   whole backdrop every frame and the edges crawl. */
@keyframes panel-float {
  from { translate: -1.2% -0.8%; }
  to   { translate: 1.2% 0.8%; }
}

/* Top padding clears the fixed nav island: 16px offset + 60px tall
   + 36px of air. */
.hero__meta {
  position: relative; width: 100%; max-width: var(--container-max);
  margin: 0 auto; padding: 112px var(--gutter-lg) 0;
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: var(--space-6);
}
.hero__eyebrow { display: flex; align-items: center; gap: var(--space-4); }
.hero__eyebrow::before {
  content: ""; width: 44px; height: 1px; background: var(--accent); flex: none;
}
.hero__eyebrow span { color: var(--text-primary); }

/* margin-top:auto pushes the headline to the bottom of the type
   field — the system is explicit that it is never centred. */
.hero__type {
  position: relative; width: 100%; max-width: var(--container-max);
  margin: auto auto 0; padding: 0 var(--gutter-lg) var(--space-8);
}
.hero__display {
  margin: 0; font-family: var(--font-display); font-weight: var(--weight-regular);
  font-size: clamp(60px, 10.4vw, 168px);
  line-height: .9;
  /* The template ships -.022em here, which is past the system's own
     hard floor for a didone. Pinned to the token instead. */
  letter-spacing: var(--track-display-1);
  max-width: 11ch; text-wrap: balance;
}
.hero__lower {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  align-items: flex-end; column-gap: var(--space-9); row-gap: var(--space-6);
  margin-top: var(--space-7);
}
.hero__lede {
  font-size: var(--size-body-lg); line-height: 1.5;
  color: var(--text-secondary); flex: 1 1 30ch; max-width: 42ch;
}
/* wrap: .fut-btn is white-space:nowrap, so a row that does not fit cannot
   shrink — it overflows instead, and body{overflow-x:hidden} then clips the
   last button off the screen rather than showing the break. */
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); flex: 0 0 auto; }

/* ── Hero glass helix ─────────────────────────────────────────
   The brand tree as a sculpture in motion: seven glass slabs
   spiralling up a drawn 1px spindle over a turning plinth, the
   whole thing in perpetual rotation. Slabs taper to an ultramarine
   crown. Real glass — backdrop-filter samples the warm field
   through each pane; copy always paints over the scene.

   Wrapper chain, because transform is one property:
     .hero__scene   perspective
     .helix         pointer sway (rotateX/rotateZ vars) + scale
     .helix__unwind scroll-driven extra rotateY (var from JS)
     .helix__intro  one-shot settle turn on load
     .helix__spin   the perpetual rotateY
     .helix__step   places a slab on the spiral (angle/height/radius)
     .helix__drop   entry: falls onto its seat, staggered
     .helix__pane   the glass itself + bob + sheen */
.hero__scene {
  position: absolute; inset: 0; pointer-events: none;
  perspective: 1100px; perspective-origin: 70% 42%;
}
.helix {
  --helix-scale: .92;
  position: absolute; top: 44%; right: clamp(120px, 16vw, 300px);
  width: 0; height: 0;
  transform-style: preserve-3d;
  transform:
    rotateX(calc(-4deg + var(--tilt-y, 0deg)))
    rotateZ(calc(-3deg + var(--tilt-x, 0deg)))
    scale3d(var(--helix-scale, 1), var(--helix-scale, 1), var(--helix-scale, 1));
  will-change: transform;
}
.helix__unwind {
  transform-style: preserve-3d;
  transform: rotateY(var(--unwind, 0deg));
}
.helix__intro {
  transform-style: preserve-3d;
  animation: helix-intro 1.8s cubic-bezier(.16,.84,.28,1) both;
}
.helix__spin {
  transform-style: preserve-3d;
  animation: helix-spin 26s linear infinite;
}
.helix__axis {
  position: absolute; left: -0.5px; top: -190px;
  width: 1px; height: 380px;
  background: linear-gradient(to bottom,
    transparent, rgba(16,17,18,.35) 12%, rgba(16,17,18,.35) 88%, transparent);
}
/* Two flat hairline squares under the bottom slab — a drawn plinth
   that visibly turns with the spin. Rules build structure. */
.helix__plinth {
  position: absolute; left: -120px; top: -120px;
  width: 240px; height: 240px;
  border: 1px solid rgba(16,17,18,.38);
  transform: translateY(170px) rotateX(90deg);
}
.helix__plinth--outer {
  left: -150px; top: -150px; width: 300px; height: 300px;
  border-color: rgba(16,17,18,.18);
}
.helix__step {
  position: absolute; left: 0; top: 0;
  transform-style: preserve-3d;
  /* -64°, not flatter: past ~-75° the slabs read edge-on for most of
     the orbit and the glass disappears into hairlines. */
  transform: rotateY(var(--a)) translateY(var(--y)) translateZ(var(--r)) rotateX(-64deg);
}
.helix__drop {
  transform-style: preserve-3d;
  animation: helix-drop .9s cubic-bezier(.22,.9,.3,1) both;
  animation-delay: var(--d);
}
.helix__pane {
  position: absolute; left: 0; top: 0;
  width: var(--w); height: var(--hh);
  margin-left: calc(var(--w) / -2); margin-top: calc(var(--hh) / -2);
  /* Heavier than the field plates. The helix sits ON the glass field
     and has to stay the darkest thing in the hero after the type,
     or the sculpture dissolves into its own background. */
  background: linear-gradient(150deg,
    rgba(16,17,18,.20), rgba(16,17,18,.07) 45%, rgba(200,205,210,.55));
  border: 1px solid rgba(16,17,18,.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55);
  backdrop-filter: blur(8px) saturate(1.05);
  -webkit-backdrop-filter: blur(8px) saturate(1.05);
  overflow: hidden;
  animation: pane-bob 6s ease-in-out infinite alternate;
  animation-delay: var(--d);
}
/* Specular sweep, staggered off the same per-step delay. */
.helix__pane::after {
  content: ""; position: absolute; inset: -40%;
  background: linear-gradient(115deg,
    transparent 42%, rgba(255,255,255,.5) 50%, transparent 58%);
  transform: translateX(-70%);
  animation: pane-sheen 9s ease-in-out infinite;
  animation-delay: calc(var(--d) + 1.6s);
}
/* Paper-scope accent (#2B39C4): the crown carries the one pigment,
   the way the old tree carried its emissive crown. */
.helix__pane--crown {
  background: linear-gradient(150deg, rgba(43,57,196,.34), rgba(43,57,196,.14));
  border-color: rgba(43,57,196,.60);
}
@keyframes helix-intro {
  from { transform: rotateY(-150deg); }
  to   { transform: rotateY(0deg); }
}
@keyframes helix-spin {
  from { transform: rotateY(0deg); }
  to   { transform: rotateY(360deg); }
}
@keyframes helix-drop {
  from { opacity: 0; transform: translateY(-160px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes pane-bob {
  from { transform: translateY(-4px); }
  to   { transform: translateY(4px); }
}
@keyframes pane-sheen {
  0%, 58%   { transform: translateX(-70%); }
  78%, 100% { transform: translateX(70%); }
}
/* Type entrance: display, lede, actions and rail rise in sequence
   on load. One-shot, entrance grammar only. Scoped to the field
   hero — /mario runs its own reveal pass over the same classes. */
.hero--field .hero__display, .hero--field .hero__lede,
.hero--field .hero__actions, .hero--field .hero__rail-inner {
  animation: hero-rise .8s var(--ease-entrance, ease-out) both;
}
.hero--field .hero__lede { animation-delay: .18s; }
.hero--field .hero__actions { animation-delay: .32s; }
.hero--field .hero__rail-inner { animation-delay: .48s; }
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .helix__intro, .helix__spin, .helix__drop, .helix__pane, .helix__pane::after,
  .hero--field .hero__texture::after, .hero__panel,
  .hero--field .hero__display, .hero--field .hero__lede,
  .hero--field .hero__actions, .hero--field .hero__rail-inner { animation: none; }
  /* Static pose: a three-quarter view so the spiral still reads. */
  .helix__spin { transform: rotateY(40deg); }
}

.hero__rail { position: relative; border-top: 1px solid var(--border-subtle); }
.hero__rail-inner {
  max-width: var(--container-max); margin: 0 auto;
  padding: var(--space-4) var(--gutter-lg) var(--space-5);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-6);
}

/* ── Bands ────────────────────────────────────────────────── */
/* Section rhythm is 96px BETWEEN bands. Two adjacent bands each
   carrying their own 96px would double it, so consecutive paper
   bands drop their top padding and the gap is the previous band's
   bottom padding alone. An ink band is a different surface: its
   edge is the boundary, so it keeps its own internal air and the
   band after it starts fresh. */
.band { padding: var(--section-y) 0; }
.band + .band { padding-top: 0; }
.band--ink { background: var(--ink-900); color: var(--paper-100); padding: 0; }
.band--ink .band__inner { padding: var(--section-y) var(--gutter-lg); }
.band--ink + .band { padding-top: var(--section-y); }
.band__inner {
  max-width: var(--container-max); margin: 0 auto; padding: 0 var(--gutter-lg);
}

/* Unigrid: the 172px column carries the metadata so the main
   column stays one clean measure. */
.grid-unigrid {
  display: grid; grid-template-columns: var(--margin-column) minmax(0, 1fr);
  gap: var(--space-7); margin-top: var(--space-7);
}
.margin-col { display: flex; flex-direction: column; gap: var(--space-5); }
.margin-col p { font-size: var(--size-caption); line-height: var(--lh-caption); color: var(--text-tertiary); }

/* --size-display-3 is a flat 52px, which on a 390px screen turned a
   five-word headline into four lines. Fluid down, unchanged at desktop. */
.band__head {
  margin: 0; font-family: var(--font-display); font-weight: var(--weight-regular);
  font-size: clamp(30px, 5vw, var(--size-display-3)); line-height: var(--lh-display-3);
  letter-spacing: var(--track-display-3); max-width: 16ch; text-wrap: balance;
}
.band__head em { font-style: italic; }
.prose { margin-top: var(--space-5); max-width: var(--measure); display: flex; flex-direction: column; gap: var(--space-4); }
.prose p { font-size: var(--size-body-lg); line-height: var(--lh-body-lg); letter-spacing: var(--track-body-lg); color: var(--text-secondary); }

/* ── Ruled card grids ─────────────────────────────────────── */
.cardgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); margin-top: var(--space-8); }
.cardgrid--work { margin-top: var(--space-7); }

.entry {
  border-top: var(--rule-weight) solid var(--border-strong);
  padding-top: var(--space-3); display: flex; flex-direction: column;
  gap: var(--space-2); min-height: 176px;
  transition: border-color var(--dur-base) var(--ease-out);
}
.entry__top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.entry__index { font-family: var(--font-mono); font-size: var(--size-figure); color: var(--text-accent); font-variant-numeric: tabular-nums; }
.entry__aside { font-family: var(--font-mono); font-size: 11px; color: var(--text-tertiary); }
.entry h3 { margin: var(--space-2) 0 0; font-size: var(--size-h3); font-weight: var(--weight-semibold); letter-spacing: var(--track-h3); }
.entry p { font-size: var(--size-body-sm); line-height: var(--lh-body-sm); color: var(--text-secondary); }

/* Work entries. a.entry hover darkens the rule to accent — nothing
   lifts, nothing scales. The arrow marks an outbound route. */
/* .entry is a column flex container, so a bare inline-flex child is
   stretched to the full column width by the default align-items:
   stretch — which turned every tag into an empty-looking box. */
.entry > .fut-tag { align-self: flex-start; }

a.entry { text-decoration: none; color: inherit; min-height: 128px; }
a.entry:hover { border-top-color: var(--accent); }
a.entry:focus-visible { outline: none; box-shadow: var(--ring-focus); }
.entry--work { min-height: 128px; }
.entry__name { font-family: var(--font-sans); font-size: var(--size-h4); font-weight: var(--weight-semibold); letter-spacing: var(--track-h4); margin-top: var(--space-3); }
.entry__sub { font-size: var(--size-body-sm); color: var(--text-secondary); }
.entry__sub .arrow { color: var(--text-accent); }

/* ── Ink statement band ───────────────────────────────────── */
.statement {
  margin: 0; font-family: var(--font-display); font-weight: var(--weight-regular);
  font-size: clamp(30px, 4.4vw, 58px); line-height: 1.08;
  letter-spacing: var(--track-h1); max-width: 20ch; text-wrap: balance;
}
.statement em { font-style: italic; color: var(--text-accent); }
.colgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); margin-top: var(--space-9); }
.col { border-top: 1px solid var(--border-subtle); padding-top: var(--space-3); }
.col__key { font-size: var(--size-label); font-weight: var(--weight-semibold); letter-spacing: var(--track-label); text-transform: uppercase; }
.col p { margin-top: var(--space-2); font-size: var(--size-body-sm); line-height: var(--lh-body-sm); color: var(--text-secondary); }

/* ── Portrait ─────────────────────────────────────────────── */
.portrait { width: 100%; max-width: 172px; aspect-ratio: 1; object-fit: cover; border: 1px solid var(--border-hairline); }

/* ── Contact ──────────────────────────────────────────────── */
.contact-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-9); align-items: end; }
.contact-actions { display: flex; flex-direction: column; gap: var(--space-3); }
.contact-note { display: flex; flex-direction: column; gap: var(--space-5); }

/* ── Footer ───────────────────────────────────────────────── */
.site-footer { background: var(--ink-900); color: var(--paper-100); padding: var(--section-y-sm) 0; }
.site-footer__inner {
  max-width: var(--container-max); margin: 0 auto; padding: 0 var(--gutter-lg);
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--space-5); flex-wrap: wrap;
}
.site-footer__mark { font-family: var(--font-display); font-size: 32px; letter-spacing: -.01em; }
.site-footer__meta { text-align: right; display: flex; flex-direction: column; gap: var(--space-1); }
.site-footer__meta span { font-size: var(--size-label); font-weight: var(--weight-semibold); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-tertiary); }

/* ── Mobile nav ───────────────────────────────────────────── */
/* Square toggle, drawn with borders — the system supplies no icon set. */
/* 44px: this is the only navigation control on mobile. */
.nav-toggle {
  display: none; width: 44px; height: 44px; flex: none;
  align-items: center; justify-content: center; margin-left: auto;
  background: none; border: 1px solid var(--border-default);
  color: var(--text-primary); cursor: pointer;
}
.nav-toggle span { display: block; width: 15px; height: 1px; background: currentColor; position: relative; }
.nav-toggle span::before, .nav-toggle span::after { content: ""; position: absolute; left: 0; width: 15px; height: 1px; background: currentColor; }
.nav-toggle span::before { top: -5px; } .nav-toggle span::after { top: 5px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after { top: 0; transform: rotate(-45deg); }

.mobile-menu { display: none; }
.mobile-menu.open {
  pointer-events: auto;
  display: flex; flex-direction: column;
  max-width: var(--container-max); margin: -1px auto 0;
  padding: var(--space-2) var(--space-5);
  border: 1px solid var(--border-subtle);
  background: rgba(246,247,248,.97);
  backdrop-filter: blur(var(--blur-glass));
  -webkit-backdrop-filter: blur(var(--blur-glass));
}
/* Full-width 44px rows, hairline-separated: at 18px these were a stack of
   thin text targets, easy to mis-tap and the only nav on mobile. */
.mobile-menu a {
  display: flex; align-items: center; min-height: 44px;
  font-size: var(--size-label); font-weight: var(--weight-semibold);
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--text-primary); text-decoration: none;
}
.mobile-menu a + a { border-top: 1px solid var(--border-hairline); }

/* ── Reveal ───────────────────────────────────────────────── */
/* 620ms, --ease-entrance, opacity + 16px. Nothing scales or springs.
   No-JS and reduced-motion both land on the revealed state. */
.reveal { opacity: 0; transform: translateY(var(--reveal-distance)); }
.reveal.is-visible { opacity: 1; transform: none; transition: opacity var(--dur-reveal) var(--ease-entrance), transform var(--dur-reveal) var(--ease-entrance); }
.no-js .reveal, .reveal.is-instant { opacity: 1; transform: none; transition: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

/* ── Responsive ───────────────────────────────────────────── */
@media (max-width: 1080px) {
  .cardgrid { grid-template-columns: repeat(2, 1fr); }
  .helix { --helix-scale: .78; top: 47%; right: 12vw; }
}
@media (max-width: 900px) {
  .grid-unigrid { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
  .margin-col { flex-direction: row; flex-wrap: wrap; gap: var(--space-5); }
  .margin-col > * { flex: 1 1 220px; }
  .colgrid { grid-template-columns: 1fr; gap: var(--space-5); margin-top: var(--space-7); }
  .contact-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); align-items: start; }
  .band__head { max-width: none; }
}
@media (max-width: 860px) {
  .site-nav__links, .site-nav__action { display: none; }
  .nav-toggle { display: inline-flex; }
}
@media (max-width: 720px) {
  :root { --gutter-lg: var(--space-5); --section-y: var(--space-10); }
  .site-nav { top: 12px; padding-inline: var(--space-4); }
  .site-nav__island { height: 54px; padding-inline: var(--space-4); }
  .hero__meta { padding-top: 96px; }
  .cardgrid { grid-template-columns: 1fr; gap: var(--space-5); }
  .hero__meta .hero__slot { display: none; }
  /* The eyebrow wraps to two lines on a narrow screen and the display
     headline sat straight underneath it. padding, not margin, so the
     margin-top:auto that pins the headline to the bottom still works. */
  .hero__type { padding-top: var(--space-7); }
  .hero__eyebrow { align-items: flex-start; }
  .hero__eyebrow::before { margin-top: 7px; }
  .hero__display { font-size: clamp(44px, 12.5vw, 76px); max-width: none; }
  .hero__actions { width: 100%; }
  .hero__actions .fut-btn { flex: 1; }
  /* Small screens: the helix shrinks into the upper right, above
     the lede and actions. The display type may pass in front — copy
     paints over the glass, never under it — but body text stays
     clear of the slabs entirely. */
  .helix { --helix-scale: .42; top: 25%; right: 48px; }
  /* Plate sizes are in vw, so on a phone they shrink to the width of
     the content and their corners land mid-copy, reading as stray
     boxes rather than architectural planes. Oversized here so the
     edges overhang and only one deliberate diagonal crosses. */
  .hero__panel--a { left: -34vw; top: -12vh; width: 140vw; height: 56vh; }
  .hero__panel--b { right: -46vw; top: 28vh; width: 130vw; height: 50vh; }
  .hero__panel--c { left: -24vw; bottom: -20vh; width: 160vw; height: 44vh; }
  .site-footer__inner { flex-direction: column; align-items: flex-start; }
  .site-footer__meta { text-align: left; }
  .entry, a.entry { min-height: 0; }
  /* --sm buttons are 32px; on touch they need a real target. */
  .fut-btn--sm { height: 44px; }
  /* The role sub-label costs more width than it earns on a small phone. */
  .site-nav__role { display: none; }
  /* body-lg is 19px — a lot of line-breaks in a 342px measure. */
  .prose p { font-size: var(--size-body); line-height: 1.62; }
}
