/* ============================================================
   DP|TG — THE OPENING (v5 mechanic, DP|TG skin)
   Dark canvas, v1's type voice (Archivo expanded caps, blue
   accent, brass hairlines). Artboard 1440x810 scaled to fit;
   children use design-pixel coordinates, v5 technique.
   ============================================================ */

:root {
  /* The threshold is always dark, whatever the site theme — the gate is
     a cinema going down before the film. These never flip. */
  --gate-bg:  #0b0d10;
  --gate-ink: #f3f5f7;
  --gate-mut: #98a2ad;

  /* Themed surface. Dark is the default; [data-theme="light"] overrides. */
  --bg:     #0b0d10;
  --bg-2:   #12161b;
  --panel:  #161b21;
  --ink:    #f3f5f7;
  --mut:    #98a2ad;
  --line:   rgba(255, 255, 255, 0.10);
  --blue:   #58a8d3;
  --brass:  #c6b27b;
  --shadow: 0 26px 46px rgba(0, 0, 0, 0.55);
  --glow:   rgba(88, 168, 211, 0.07);

  --ease-hero: cubic-bezier(1, 0.01, 0.02, 1);
  --ease-snap: cubic-bezier(1, -0.045, 0, 1.03);
  --t-ui: 0.35s;
}

/* Light: the brochure's own world — white canvas, ink type, blue and
   brass deepened so small text still clears contrast on paper. */
:root[data-theme="light"] {
  --bg:     #f8f8f7;
  --bg-2:   #f0efe8;
  --panel:  #ffffff;
  --ink:    #242525;
  /* 0.70 not 0.62, and brass a shade deeper: at the lighter values the
     lead, nav, stat labels and layer numbers all landed at ~4.2-4.4:1,
     just under AA on this canvas. */
  --mut:    rgba(36, 37, 37, 0.70);
  --line:   rgba(36, 37, 37, 0.13);
  --blue:   #2e6787;
  --brass:  #6b5c32;
  --shadow: 0 20px 44px rgba(36, 37, 37, 0.13);
  --glow:   rgba(79, 151, 190, 0.07);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  background: var(--bg);
  overflow: hidden;               /* the opening owns the viewport… */
  font-family: "Archivo", system-ui, sans-serif;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}
/* …until you are through it, when the site becomes a normal page. */
html.landed, html.landed body { height: auto; overflow: visible; }
html.landed { overflow-x: clip; }   /* clip, not hidden — hidden kills sticky */

:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 3px; }

/* ---- header (real DOM, above the stage) -------------------- */

/* Opaque band: the retracted door slivers pass BEHIND this, so the gate
   reads as starting below the header rather than running up through it. */
#hd {
  position: fixed; inset: 0 0 auto 0; z-index: 20;
  height: 76px;
  display: flex; align-items: center;
  padding-inline: clamp(20px, 3.4vw, 56px);
  background: var(--bg);
  opacity: 0; transform: translateY(-12px);   /* JS reveals at HERO */
}

.brand { display: flex; flex-direction: column; gap: 3px; text-decoration: none; color: var(--ink); }
.brand b {
  font-size: 21px; font-weight: 700; letter-spacing: 0.02em;
  font-variation-settings: "wdth" 110;
}
.brand .bar { color: var(--blue); font-weight: 400; padding-inline: 1px; }
.brand .sub {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--mut); white-space: nowrap;
}

/* centred nav — requested: items centre-aligned, not right */
.nav {
  position: absolute; left: 50%; transform: translateX(-50%);
  display: flex; gap: clamp(22px, 3vw, 44px);
}
.nav a {
  color: var(--mut); text-decoration: none;
  font-size: 13px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  transition: color var(--t-ui) ease;
}
.nav a:hover { color: var(--ink); }

/* theme toggle */
.tt {
  margin-left: auto;
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  background: none; border: 1px solid var(--line); border-radius: 50%;
  color: var(--mut); cursor: pointer;
  transition: color var(--t-ui) ease, border-color var(--t-ui) ease;
}
.tt:hover { color: var(--ink); border-color: var(--ink); }
.tt svg { width: 17px; height: 17px; fill: currentColor; }
.tt .i-sun { display: none; }
:root[data-theme="light"] .tt .i-sun { display: block; }
:root[data-theme="light"] .tt .i-moon { display: none; }

.cta {
  margin-left: 18px;
  background: var(--blue); color: var(--bg);
  text-decoration: none; font-size: 13px; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 12px 22px; border-radius: 999px;
  transition: transform var(--t-ui) var(--ease-snap), background var(--t-ui) ease;
}
.cta:hover { background: color-mix(in srgb, var(--blue) 82%, var(--ink)); }
.cta:active { transform: scale(0.96); }

/* ---- stage -------------------------------------------------- */

/* Re-binding the surface tokens here pins the whole threshold to the dark
   palette, whichever theme the site is in — one rule instead of touching
   every descendant. */
.stage {
  --bg:  var(--gate-bg);
  --ink: var(--gate-ink);
  --mut: var(--gate-mut);
  --blue: #58a8d3;
  --brass: #c6b27b;

  position: absolute; top: 50%; left: 50%; z-index: 10;
  width: 1440px; height: 810px;
  transform: translate(-50%, -50%) scale(calc(var(--s, 1) * var(--z, 1)));
  transform-origin: 720px 400px;
  background: var(--bg);
  color: var(--ink);
  overflow: hidden;
}

.L { position: absolute; will-change: transform, opacity; }

/* the dark world behind the gate — a faint warm heart of light */
#void {
  inset: 0;
  background:
    radial-gradient(720px 480px at 720px 400px, rgba(230, 178, 108, 0.13), transparent 62%),
    radial-gradient(1100px 700px at 720px 430px, rgba(88, 168, 211, 0.07), transparent 70%),
    var(--bg);
}

/* The door dissolved into light: coloured vertical ribbons that converge
   on the centre, flare, then burst outward onto the site. Positions and
   colours are assigned in main.js; dead until the entry fires them. */
#ribbons { inset: 0; opacity: 0; pointer-events: none; }
#ribbons i {
  position: absolute; top: -8%; bottom: -8%;
  width: 8px; margin-left: -4px;
  border-radius: 5px;
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 13%, #000 87%, transparent 100%);
          mask-image: linear-gradient(180deg, transparent 0%, #000 13%, #000 87%, transparent 100%);
  will-change: transform, opacity;
}

/* the light burst on entry — dead until the fly-through fires it */
#burst {
  inset: 0;
  background: radial-gradient(circle at 720px 405px,
    rgba(240, 205, 140, 0.95) 0%,
    rgba(120, 180, 220, 0.4) 34%,
    transparent 64%);
  mix-blend-mode: screen;
  opacity: 0;
  transform-origin: 720px 405px;
  pointer-events: none;
}

/* ---- the layer stack (CSS 3D) ------------------------------ */

#stack3d {
  left: 640px; top: 170px; width: 800px; height: 640px;
  perspective: 1500px; perspective-origin: 50% 45%;
}
.srot {
  position: absolute; left: 206px; top: 74px;
  width: 540px; height: 486px;
  transform-style: preserve-3d;
}
/* One card per product family: photo plus its own caption. Laid out
   2x2 on a gently tilted plane, so all four read at once. */
.pcard {
  position: absolute;
  left: calc(var(--gx) * 290px);
  top:  calc(var(--gy) * 260px);
  width: 250px;
  transform-style: preserve-3d;
}
.pcard img {
  display: block; width: 250px; height: 182px;
  object-fit: cover; border-radius: 12px;
  box-shadow: 0 26px 46px rgba(0, 0, 0, 0.55),
              inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}
.pcard b {
  display: block; margin-top: 13px;
  font-size: 13px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.pcard span {
  display: block; margin-top: 3px;
  font-size: 11.5px; color: var(--mut);
}

/* ---- the title line, full width below the header ----------- */

#titleline {
  left: 56px; top: 118px; width: 1328px;
  font-variation-settings: "wdth" 112;
  font-weight: 640; font-size: 42px; line-height: 1;
  letter-spacing: 0.01em; text-transform: uppercase;
  white-space: nowrap;
}
#titleline i {
  font-style: normal; font-weight: 400;
  color: var(--brass); padding-inline: 14px;
}
#titleline::after {
  content: ""; position: absolute; left: 0; top: 76px;
  width: 100%; height: 1px; background: var(--brass); opacity: 0.35;
}

/* ---- left block — v1's voice ------------------------------- */

#title {
  left: 56px; top: 222px; width: 600px;
  font-variation-settings: "wdth" 112;
  font-weight: 640; font-size: 62px; line-height: 1.02;
  letter-spacing: 0.005em; text-transform: uppercase;
}
#title .t-blue { color: var(--blue); }
#lead {
  left: 58px; top: 500px; width: 470px;
  font-size: 17px; line-height: 1.6; color: var(--mut);
}

/* ---- ENTER — a 3D arrow pointing into the site ------------- */
/* The button block is 240x150 centred on (720, 405). Three chevrons
   lie almost flat and step away along Z, so the arrow reads as
   pointing INTO the screen; they flow inward on a slow loop. */

#enter {
  left: 600px; top: 330px; width: 240px; height: 150px;
  display: grid; justify-items: center; align-content: center; gap: 16px;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.a3d { position: relative; width: 100px; height: 76px; perspective: 520px; }
.a3d i {
  position: absolute; left: 50%; top: 54%;
  width: 54px; height: 54px;
  border-left: 7px solid var(--ink); border-bottom: 7px solid var(--ink);
  border-radius: 3px;
  transform: translate(-50%, -50%) rotateX(62deg) rotate(135deg)
             translateZ(calc(var(--i) * -30px)) scale(calc(1 - var(--i) * 0.13));
  opacity: calc(1 - var(--i) * 0.32);
  transition: border-color var(--t-ui) ease;
  animation: a3d-flow 2.1s calc(var(--i) * -0.7s) infinite ease-in-out;
}
.a3d i:nth-child(1) { --i: 0; }
.a3d i:nth-child(2) { --i: 1; }
.a3d i:nth-child(3) { --i: 2; }

@keyframes a3d-flow {
  0%, 100% { margin-top: 6px; }
  50%      { margin-top: -6px; }
}

.enter-label {
  font-size: 12px; font-weight: 600; letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--mut);
  transition: color var(--t-ui) ease;
}
#enter:hover .a3d i, #enter.armed .a3d i { border-color: var(--blue); }
#enter:hover .enter-label, #enter.armed .enter-label { color: var(--ink); }

/* ---- the gate — metro platform screen doors ---------------- */

.door { width: 800px; height: 880px; top: -35px; }
.door img { display: block; width: 100%; height: 100%; }
#doorL { left: -40px; }
#doorR { left: 680px; }

/* blue LED door-edge strip — DOM so it can blink before opening */
.led {
  position: absolute; top: 30px; bottom: 96px; width: 5px;
  background: var(--blue);
  box-shadow: 0 0 12px rgba(88, 168, 211, 0.85), 0 0 34px rgba(88, 168, 211, 0.4);
  animation: led-blink 1.35s steps(1) 1;
}
#doorL .led { right: 10px; }
#doorR .led { left: 10px; }

@keyframes led-blink {
  0% { opacity: 0.2; } 22% { opacity: 1; } 34% { opacity: 0.2; }
  52% { opacity: 1; } 64% { opacity: 0.2; } 82% { opacity: 1; }
}

/* The bloom at the instant you break through. Above everything, briefly. */
#flash {
  position: fixed; inset: 0; z-index: 30;
  background: radial-gradient(circle at 50% 46%,
    #ffffff 0%, rgba(214, 234, 248, 0.9) 26%, rgba(120, 180, 220, 0.35) 58%, transparent 78%);
  opacity: 0; pointer-events: none;
  will-change: opacity;
}

.nojs { position: fixed; inset: auto 0 0 0; padding: 16px; text-align: center; color: var(--mut); background: var(--bg); }

/* ---- THE LANDING — section 01, dark ------------------------ */

/* Sits UNDER the stage during the fly-through so the zoom arrives
   into it through the parting doors. */
/* Fixed while you are still travelling toward it; a normal document
   once you have arrived. */
#site {
  position: fixed; inset: 0; z-index: 1;
  background: var(--bg);
  transform-origin: 50% 46%;
  will-change: transform, opacity;
}
html.landed #site { position: relative; inset: auto; will-change: auto; }

/* The hero is a photographic band: the real Lucknow plant behind a scrim,
   with light type over it in BOTH themes — the same reasoning as the gate
   staying dark. Rebinding the ink tokens here keeps every child readable
   without per-element overrides. */
.hero {
  --ink: var(--gate-ink);
  --mut: var(--gate-mut);

  position: relative;
  height: 100vh; min-height: 560px;
  display: flex; align-items: center;
  padding-top: 76px;
  color: var(--ink);
  background: var(--gate-bg);
  overflow: clip;
}
/* Only .wrap wants position here. Including .h-next in this selector gave
   it specificity 0-2-0 with position:relative, which beat its own
   position:absolute (0-1-0) further down — so the scroll cue stayed in
   flow as a second flex item and squeezed the headline column. That is
   what broke the hero copy to one word per line, at every width. */
.hero > .wrap { position: relative; z-index: 2; }

.hero-bg {
  position: absolute; inset: -8% 0 -8% 0;   /* slack for the parallax drift */
  background: url("assets/hero-factory-sm.webp") center 42% / cover no-repeat;
  will-change: transform;
}
@media (min-width: 901px) {
  .hero-bg { background-image: url("assets/hero-factory.webp"); }
}

/* Angled so the darkest part sits under the copy on the left and the plant
   stays visible on the right. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(100deg,
      rgba(11, 13, 16, 0.95) 0%,
      rgba(11, 13, 16, 0.88) 34%,
      rgba(11, 13, 16, 0.62) 68%,
      rgba(11, 13, 16, 0.48) 100%),
    linear-gradient(180deg, rgba(11, 13, 16, 0.85) 0%, transparent 26%),
    radial-gradient(1000px 640px at 72% 44%, rgba(88, 168, 211, 0.10), transparent 70%);
}
.wrap { max-width: 1200px; margin: 0 auto; width: 100%; padding-inline: clamp(24px, 5vw, 72px); }

.h-eyebrow {
  font-size: 14px; font-weight: 600; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--brass);
  margin-bottom: 26px;
}
.h-display {
  font-variation-settings: "wdth" 112;
  font-weight: 640; font-size: clamp(3rem, 6.4vw, 5.2rem);
  line-height: 1.02; text-transform: uppercase; letter-spacing: 0.005em;
  margin-bottom: 30px;
}
.h-display .t-blue { color: var(--blue); }
.h-lead {
  font-size: clamp(1.25rem, 1.7vw, 1.5rem); line-height: 1.6;
  color: var(--mut); max-width: 660px; margin-bottom: 48px;
}
.h-stats { list-style: none; display: flex; flex-wrap: wrap; }
.h-stats li {
  font-size: 17px; color: var(--mut);
  padding-block: 6px; padding-inline: 26px;
  border-left: 1px solid var(--brass);
}
.h-stats li:first-child { padding-left: 0; border-left: 0; }
.h-stats b { color: var(--ink); font-weight: 680; }

.h-next {
  position: absolute; left: 0; right: 0; bottom: 26px;
  z-index: 2;                 /* .hero-scrim is z-index 1 */
  text-align: center;
  font-size: 10.5px; font-weight: 500; letter-spacing: 0.26em;
  text-transform: uppercase; color: var(--mut); opacity: 0.7;
}

/* ---- 02 · THE ASSEMBLY ------------------------------------- */
/* The one earned pin on the page: scrolling drives six layers into a
   single berth, each naming itself as it lands. */

.asm {
  position: relative;
  min-height: 100vh;
  display: flex; align-items: center;
  padding-block: 96px;
  background: var(--bg-2);
  border-top: 1px solid var(--line);
  overflow: clip;
}
/* Centred column: statement on top, the berth building in the middle,
   and one caption at a time underneath it. */
.asm-centre {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: clamp(20px, 3vw, 36px);
}
.asm-intro { max-width: 60ch; }
.eyebrow-2.is-centred { justify-content: center; }

.eyebrow-2 {
  display: flex; align-items: center; gap: 14px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--brass);
  margin-bottom: 22px;
}
.eyebrow-2::before { content: ""; width: 34px; height: 1px; background: var(--brass); }

.sec-h {
  font-variation-settings: "wdth" 112;
  font-weight: 640; text-transform: uppercase;
  font-size: clamp(2rem, 3.4vw, 3.1rem); line-height: 1.04;
  letter-spacing: 0.004em;
  margin-bottom: 18px; text-wrap: balance;
}
/* margin-inline:auto matters: with only max-width the 46ch box sat flush
   left inside the 60ch intro, so the centred text read ~50px left of the
   headline's centre. */
.sec-lead {
  font-size: clamp(1rem, 1.2vw, 1.12rem); line-height: 1.6;
  color: var(--mut); max-width: 46ch;
  margin-inline: auto; margin-bottom: 34px;
}

/* Intro centred; below it the captions sit LEFT and the berth builds right. */
.asm-row {
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(24px, 4vw, 64px);
  align-items: center;
}

/* Captions stack in one place; only the current one is visible, so the
   text arrives in step with the layer instead of sitting in a list. */
.asm-caps {
  position: relative;
  height: 150px;
  text-align: left;
}
.asm-cap {
  position: absolute; inset: 0;
  display: grid; justify-items: start; align-content: center; gap: 7px;
  opacity: 0;
}
.asm-cap em {
  font-style: normal; font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: 13px; letter-spacing: 0.16em; color: var(--brass);
}
.asm-cap strong {
  font-variation-settings: "wdth" 112;
  font-size: clamp(1.15rem, 1.8vw, 1.5rem); font-weight: 640;
  letter-spacing: 0.03em; text-transform: uppercase; line-height: 1.15;
}
.asm-cap span { font-size: 15px; color: var(--mut); max-width: 40ch; }
.asm-cap-final strong { color: var(--blue); }

/* The finished berth: one solid upholstered object, thickness of the whole
   stack. Hidden until the layers crossfade into it. */
/* The finished berth. Durable Polymers builds the whole assembly — steel
   frame, cushioning and upholstery — so the payoff is a photograph of the
   real berth in its cabin, not another slab. The plane un-tilts to flat as
   this arrives (see buildAssembly), so the photograph faces the viewer. */
.asm-berth {
  position: absolute; inset: 0;
  border-radius: 16px;
  transform-style: preserve-3d;
  opacity: 0;
  background: url("assets/berth-cabin.webp") center / cover no-repeat;
  box-shadow: 0 36px 64px rgba(0, 0, 0, 0.5);
}
.asm-berth::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -74px; height: 74px;
  transform: rotateX(-90deg); transform-origin: top;
  border-radius: 0 0 16px 16px;
  background: linear-gradient(180deg, #2b3849 0%, #131a23 100%);
}
.asm-berth::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(104deg, rgba(255,255,255,0.16) 0%, transparent 46%);
}

/* the 3D build */
.asm-stage {
  position: relative; width: 100%; height: min(56vh, 470px);
  perspective: 1500px; perspective-origin: 50% 46%;
}
/* No transform here on purpose: a combined rotateX+rotateZ matrix cannot be
   decomposed back into its parts, so GSAP would misread the start value.
   main.js owns this element's transform outright. */
.asm-rot {
  position: absolute; left: 50%; top: 50%;
  width: 400px; height: 268px; margin: -134px 0 0 -200px;
  transform-style: preserve-3d;
}
/* Each layer is a photograph of the real material, shot square-on; the
   3D tilt is applied here, so the images must stay perspective-free. */
.asm-layer {
  position: absolute; inset: 0;
  border-radius: 14px;
  transform-style: preserve-3d;
  box-shadow: 0 30px 54px rgba(0, 0, 0, 0.45);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
/* The slab's visible thickness. --edge is the material's own average tone
   darkened; `background: inherit` would repeat the whole photograph down
   the 14px edge, which reads as a smear. */
.asm-layer::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -14px; height: 14px;
  transform: rotateX(-90deg); transform-origin: top;
  border-radius: 0 0 14px 14px;
  background: var(--edge, #2a2c31);
}
.asm-layer[data-i="0"] {
  background-image: url("assets/layers/01-steel-frame.webp");
  --edge: #34373a;
  box-shadow: none;   /* the frame is cut out, so a solid shadow would show through it */
}
.asm-layer[data-i="1"] {
  background-image: url("assets/layers/02-mounts.webp");
  --edge: #353638;
  box-shadow: none;   /* rounded plate corners are cut out, same as the frame */
}
.asm-layer[data-i="2"] { background-image: url("assets/layers/03-polyester-core.webp");    --edge: #767571; }
.asm-layer[data-i="3"] { background-image: url("assets/layers/04-pu-foam.webp");           --edge: #2a2c31; }
.asm-layer[data-i="4"] { background-image: url("assets/layers/05-silicone-barrier.webp");  --edge: #66180f; }
.asm-layer[data-i="5"] { background-image: url("assets/layers/06-upholstery.webp");        --edge: #091022; }
/* sheen on the top face */
.asm-layer[data-i="5"]::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(104deg, rgba(255, 255, 255, 0.16) 0%, transparent 42%);
}

@media (max-width: 900px) {
  /* Heavy 3D is desktop-only. Without it the captions cannot stack in one
     place — they become a plain readable list instead. */
  .asm-row { grid-template-columns: minmax(0, 1fr); }
  .asm-stage { display: none; }
  .asm-caps { height: auto; display: grid; gap: 26px; }
  .asm-cap { position: static; opacity: 1; }
}

/* ---- 04 · PROOF -------------------------------------------- */

.pf {
  position: relative;
  padding-block: clamp(80px, 10vw, 140px);
  background: var(--bg-2);
  border-top: 1px solid var(--line);
}
.pf-head { max-width: 620px; margin-bottom: clamp(36px, 4vw, 56px); }

/* The scroll-lit statement: words start dim and light as you pass. */
.pf-lit {
  font-variation-settings: "wdth" 106;
  font-size: clamp(1.3rem, 2.5vw, 2.05rem);
  line-height: 1.42; font-weight: 500;
  max-width: 22ch; margin-bottom: clamp(56px, 7vw, 100px);
  text-wrap: pretty;
}
.pf-lit w { display: inline-block; opacity: 0.18; }
.pf-lit w.on { opacity: 1; }

.pf-fire-line {
  font-size: clamp(1.02rem, 1.25vw, 1.15rem);
  color: var(--mut); max-width: 46ch; margin-bottom: clamp(28px, 3.5vw, 44px);
  padding-left: 16px; border-left: 2px solid var(--brass);
}

.pf-rigs {
  list-style: none;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.8vw, 26px);
  margin-bottom: clamp(56px, 7vw, 104px);
}
.pf-rig figure {
  border-radius: 14px; overflow: hidden;
  background: #f4f5f6;                    /* the instruments are shot on white */
  box-shadow: var(--shadow);
  border: 1px solid var(--line);
  margin-bottom: 16px;
  aspect-ratio: 1;
}
.pf-rig img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pf-rig h3 {
  font-variation-settings: "wdth" 108;
  font-size: clamp(1rem, 1.3vw, 1.2rem); font-weight: 640;
  line-height: 1.2; margin-bottom: 5px;
}
.pf-rig p {
  font-size: 12px; font-weight: 600; letter-spacing: 0.11em;
  text-transform: uppercase; color: var(--brass);
}

.pf-certs {
  display: grid; gap: clamp(30px, 4vw, 48px);
  padding-top: clamp(36px, 4vw, 56px);
  border-top: 1px solid var(--line);
}
.pf-badges {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: clamp(28px, 5vw, 72px);
}
.pf-badges li { display: flex; align-items: center; gap: 16px; }
.pf-badges img { width: 62px; height: 62px; object-fit: contain; flex: none; }
.pf-badges span { display: grid; gap: 2px; font-size: 13px; color: var(--mut); }
.pf-badges b {
  font-variation-settings: "wdth" 112;
  font-size: 15px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink);
}

.pf-close {
  font-variation-settings: "wdth" 108;
  font-size: clamp(1.1rem, 1.6vw, 1.4rem); font-weight: 600;
}
.pf-close b { color: var(--blue); font-weight: 600; }

@media (max-width: 900px) {
  .pf-rigs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pf-lit { max-width: none; }
  .pf-lit w { opacity: 1; }   /* no scrub without the scroll runway */
}
@media (max-width: 560px) {
  /* Two columns all the way down. A single column made each lab photo a
     full-width square and turned this four-item supporting grid into
     ~1700px of scrolling, losing the side-by-side comparison. */
  .pf-rigs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ============================================================
   SHARED CHROME — used by every page except the home threshold,
   which keeps its own #hd. Sub-pages set <html class="landed">
   so the scroll rules above apply from first paint.
   ============================================================ */

.site-head {
  position: sticky; top: 0; z-index: 40;
  height: 76px;
  display: flex; align-items: center;
  padding-inline: clamp(20px, 3.4vw, 56px);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

/* the seven-item nav, shared by home and sub-pages */
.nav-main {
  position: absolute; left: 50%; transform: translateX(-50%);
  display: flex; gap: clamp(14px, 1.9vw, 30px);
}
.nav-main a {
  color: var(--mut); text-decoration: none;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  white-space: nowrap;
  transition: color var(--t-ui) ease;
}
.nav-main a:hover, .nav-main a[aria-current="page"] { color: var(--ink); }
.nav-main a[aria-current="page"] { position: relative; }
.nav-main a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -7px;
  height: 1px; background: var(--brass);
}

.head-end { margin-left: auto; display: flex; align-items: center; gap: 14px; }

.navbtn {
  display: none;
  width: 40px; height: 40px; align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line); border-radius: 10px;
  color: var(--ink); cursor: pointer;
}
.navbtn span { display: block; width: 16px; height: 1.5px; background: currentColor; position: relative; }
.navbtn span::before, .navbtn span::after {
  content: ""; position: absolute; left: 0; width: 16px; height: 1.5px; background: currentColor;
}
.navbtn span::before { top: -5px; } .navbtn span::after { top: 5px; }

/* ---- page hero (every sub-page opens the same way) -------------- */

.page-hero {
  padding-block: clamp(64px, 9vw, 118px) clamp(40px, 5vw, 64px);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(900px 460px at 78% 0%, var(--glow), transparent 68%),
    var(--bg);
}
.page-hero h1 {
  font-variation-settings: "wdth" 112;
  font-weight: 640; text-transform: uppercase;
  font-size: clamp(2.3rem, 5vw, 4rem); line-height: 1.02;
  margin-bottom: 20px; text-wrap: balance;
}
.page-hero .lead-lg {
  font-size: clamp(1.1rem, 1.5vw, 1.3rem); line-height: 1.6;
  color: var(--mut); max-width: 56ch;
}

/* ---- generic content blocks ------------------------------------- */

.band { padding-block: clamp(64px, 8vw, 112px); }
.band + .band { border-top: 1px solid var(--line); }
.band-alt { background: var(--bg-2); }

.cards {
  list-style: none; display: grid; gap: clamp(18px, 2.4vw, 30px);
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
.card {
  padding: clamp(22px, 2.4vw, 32px);
  border: 1px solid var(--line); border-radius: 16px;
  background: var(--panel);
}
.card em {
  font-style: normal; font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: 13px; letter-spacing: 0.14em; color: var(--brass);
  display: block; margin-bottom: 12px;
}
.card h3 {
  font-variation-settings: "wdth" 110;
  font-size: clamp(1.05rem, 1.35vw, 1.25rem); font-weight: 640;
  text-transform: uppercase; letter-spacing: 0.02em; margin-bottom: 10px;
}
.card p { font-size: 15px; line-height: 1.6; color: var(--mut); }

/* ---- timeline (about) ------------------------------------------- */

.tl { list-style: none; display: grid; gap: 0; }
.tl-item {
  display: grid; grid-template-columns: 110px minmax(0, 1fr);
  gap: clamp(16px, 3vw, 40px);
  padding: clamp(20px, 2.4vw, 30px) 0;
  border-top: 1px solid var(--line);
}
.tl-item:last-child { border-bottom: 1px solid var(--line); }
.tl-item > b {
  font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: clamp(1.3rem, 2vw, 1.75rem);
  color: var(--brass); line-height: 1;
}
.tl-item h3 {
  font-variation-settings: "wdth" 110;
  font-size: clamp(1rem, 1.3vw, 1.18rem); font-weight: 640;
  text-transform: uppercase; letter-spacing: 0.02em; margin-bottom: 7px;
}
.tl-item p { color: var(--mut); font-size: 15px; line-height: 1.6; max-width: 62ch; }

/* ---- pull quote --------------------------------------------------- */

.quote { max-width: 62ch; }
.quote p {
  font-variation-settings: "wdth" 106;
  font-size: clamp(1.25rem, 2.3vw, 1.9rem); line-height: 1.4; font-weight: 500;
  margin-bottom: 22px; text-wrap: pretty;
}
.quote cite { font-style: normal; display: grid; gap: 2px; font-size: 14px; color: var(--mut); }
.quote cite b {
  font-variation-settings: "wdth" 112;
  font-size: 15px; font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink);
}

/* ---- contact form ------------------------------------------------- */

.form-grid {
  display: grid; gap: clamp(28px, 5vw, 72px);
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: start;
}
.field { display: grid; gap: 8px; margin-bottom: 18px; }
.field label {
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--mut);
}
.field input, .field textarea, .field select {
  font: inherit; font-size: 15px;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r-input, 10px);
  padding: 13px 15px; width: 100%;
  transition: border-color var(--t-ui) ease;
}
.field textarea { min-height: 132px; resize: vertical; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--blue);
}
.field .hint { font-size: 12.5px; color: var(--mut); text-transform: none; letter-spacing: 0; }
.form-note { font-size: 13px; color: var(--mut); margin-top: 14px; }
.form-msg {
  margin-top: 16px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel);
  font-size: 14.5px; display: none;
}
.form-msg.show { display: block; }
.form-msg.ok { border-color: var(--blue); }

.contact-side { display: grid; gap: 26px; }
.contact-block h4 {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--brass); margin-bottom: 10px;
}
.contact-block p, .contact-block a {
  color: var(--mut); font-size: 15px; line-height: 1.6; text-decoration: none;
  display: block;
}
.contact-block a:hover { color: var(--ink); }

@media (max-width: 860px) {
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  /* 84px, matching .tl-item.has-img below. They disagreed (72 vs 90), so
     headings on picture rows and picture-less rows started 18px apart and
     the timeline zig-zagged down the page. */
  .tl-item { grid-template-columns: 84px minmax(0, 1fr); }
}

/* ---- coming soon ------------------------------------------------- */

.soon {
  min-height: 58vh;
  display: grid; place-content: center; text-align: center; gap: 18px;
  padding-block: clamp(60px, 8vw, 110px);
}
/* Selector must out-rank `.soon p` below, which is (0,1,1) and later in
   the file — it was overriding both the size and the colour, so the
   watermark rendered as 16.8px grey body copy instead of the brass
   display figure on Downloads, Careers and Blog. */
.soon p.soon-mark {
  font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: clamp(3.4rem, 9vw, 7rem); line-height: 1;
  color: var(--brass); opacity: 0.22; max-width: none;
}
.soon h2 {
  font-variation-settings: "wdth" 112;
  font-weight: 640; text-transform: uppercase;
  font-size: clamp(1.6rem, 3vw, 2.4rem);
}
.soon p { color: var(--mut); max-width: 46ch; margin-inline: auto; font-size: 1.05rem; }
.soon .btn { justify-self: center; margin-top: 10px; }

.btn {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--blue); color: var(--bg);
  text-decoration: none; border: 0; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 14px 26px; border-radius: 999px;
  transition: background var(--t-ui) ease, transform var(--t-ui) var(--ease-snap);
}
.btn:hover { background: color-mix(in srgb, var(--blue) 82%, var(--ink)); }
.btn:active { transform: scale(0.97); }
.btn-ghost {
  background: none; color: var(--ink); border: 1px solid var(--line);
}
.btn-ghost:hover { background: none; border-color: var(--ink); }

/* ---- footer ------------------------------------------------------ */

/* The footer is a sibling of <main id="site" hidden>, so hiding the site
   never hid the footer. While the gate is up it was the only element left
   in normal flow — 562px of it, at the top of the document, showing above
   and below the gate band. Sub-pages ship <html class="landed">, so this
   only ever affects the home page before the visitor enters. */
html:not(.landed) .site-foot { display: none; }

.site-foot {
  border-top: 1px solid var(--line);
  background: var(--bg-2);
  padding-block: clamp(52px, 6vw, 80px) 28px;
}
.foot-mark {
  font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: clamp(3rem, 11vw, 9rem); line-height: 0.9;
  letter-spacing: -0.01em;
  /* Brand blue in both themes: the transparent + hairline-stroke treatment
     was invisible on light and dark alike. */
  color: var(--blue);
  margin-bottom: clamp(32px, 4vw, 52px);
  user-select: none;
}
.foot-grid {
  display: grid; gap: clamp(28px, 4vw, 52px);
  /* Explicit counts, not auto-fit: at tablet widths auto-fit resolved to
     three tracks and orphaned the fourth column alone on its own row. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  padding-bottom: clamp(32px, 4vw, 48px);
  border-bottom: 1px solid var(--line);
}
.foot-col h4 {
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--brass); margin-bottom: 16px;
}
.foot-col ul { list-style: none; display: grid; gap: 9px; }
.foot-col a, .foot-col p { color: var(--mut); text-decoration: none; font-size: 14.5px; line-height: 1.55; }
.foot-col a:hover { color: var(--ink); }
.foot-col b { color: var(--ink); font-weight: 640; display: block; }
.foot-bottom {
  padding-top: 22px;
  display: flex; flex-wrap: wrap; gap: 12px 26px; justify-content: space-between;
  font-size: 13px; color: var(--mut);
}

@media (max-width: 1080px) {
  .nav-main { gap: 14px; }
  .nav-main a { font-size: 11.5px; letter-spacing: 0.07em; }
}
@media (max-width: 900px) {
  .navbtn { display: flex; }
  .nav-main {
    position: fixed; inset: 76px 0 auto 0; transform: none;
    flex-direction: column; gap: 0;
    background: var(--bg); border-bottom: 1px solid var(--line);
    padding: 8px clamp(20px, 5vw, 40px) 20px;
    display: none;
  }
  .nav-main.open { display: flex; }
  .nav-main a { padding: 15px 0; font-size: 14px; border-bottom: 1px solid var(--line); }
  .nav-main a[aria-current="page"]::after { display: none; }
  .site-head .cta { display: none; }
}

/* ---- 05 · THE LINE ----------------------------------------- */
/* Six steps, one continuous process. A brass rule draws itself through
   them as the section arrives — no horizontal scroll, all six on screen. */

.ln { position: relative; padding-block: clamp(80px, 10vw, 140px); background: var(--bg); border-top: 1px solid var(--line); }
.ln-head { max-width: 640px; margin-bottom: clamp(40px, 5vw, 68px); }

.ln-rail { position: relative; }
.ln-rail::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: 1px; background: var(--line);
}
.ln-rail::after {
  content: ""; position: absolute; left: 0; top: 0;
  height: 1px; width: var(--draw, 0%); background: var(--brass);
}

.ln-steps {
  list-style: none; display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(10px, 1.4vw, 20px);
  padding-top: clamp(22px, 2.6vw, 34px);
}
.ln-step figure {
  border-radius: 12px; overflow: hidden; aspect-ratio: 4 / 3;
  background: var(--bg-2); border: 1px solid var(--line);
  margin-bottom: 13px;
}
.ln-step img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ln-step b {
  display: block; font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: 12px; letter-spacing: 0.14em;
  color: var(--brass); margin-bottom: 6px;
}
.ln-step h3 {
  font-variation-settings: "wdth" 108;
  font-size: clamp(0.92rem, 1.1vw, 1.05rem); font-weight: 640;
  line-height: 1.2; margin-bottom: 5px;
}
.ln-step p { font-size: 13px; line-height: 1.5; color: var(--mut); }

.ln-stats {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: clamp(18px, 3vw, 48px); margin-top: clamp(40px, 5vw, 64px);
  padding-top: clamp(26px, 3vw, 38px); border-top: 1px solid var(--line);
}
.ln-stats li { font-size: 14.5px; color: var(--mut); }
.ln-stats b {
  display: block; font-variation-settings: "wdth" 118;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem); font-weight: 700;
  color: var(--ink); line-height: 1.1; margin-bottom: 2px;
}

@media (max-width: 1000px) { .ln-steps { grid-template-columns: repeat(3, minmax(0, 1fr)); row-gap: 26px; } }
@media (max-width: 620px)  { .ln-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---- 06 · CLIENT WALL -------------------------------------- */
/* Two rows drifting opposite ways. Every logo sits on a chip at the same
   optical height, which is what stops a ragged raster set looking amateur. */

.cl { padding-block: clamp(72px, 9vw, 124px); background: var(--bg-2); border-top: 1px solid var(--line); overflow: clip; }
.cl-head { max-width: 620px; margin-bottom: clamp(34px, 4vw, 52px); }

.marquee {
  position: relative; display: grid; gap: 14px;
  /* Full-bleed on purpose. The strip is clipped by .cl at the viewport
     edge, but the fades below are anchored to this element — which sat at
     the .wrap padding edge. Everything between the two was a raw sliver of
     chip, hard-cut outside the gradient. Now they coincide. */
  margin-inline: calc(50% - 50vw);
}
.marquee::before, .marquee::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: clamp(40px, 8vw, 120px); z-index: 2;
  pointer-events: none;
}
.marquee::before { left: 0;  background: linear-gradient(90deg, var(--bg-2), transparent); }
.marquee::after  { right: 0; background: linear-gradient(270deg, var(--bg-2), transparent); }

.mq-row { display: flex; gap: 14px; width: max-content; }
.mq-row.a { animation: mq-left 46s linear infinite; }
.mq-row.b { animation: mq-right 52s linear infinite; }
/* Gated: Chrome on Android synthesises :hover on tap and leaves it stuck
   there, so a single tap or a scroll begun on the strip froze both rows
   permanently. Desktop keeps the pause-on-hover affordance. */
@media (hover: hover) and (pointer: fine) {
  .marquee:hover .mq-row { animation-play-state: paused; }
}

@keyframes mq-left  { from { transform: translateX(0); }        to { transform: translateX(-50%); } }
@keyframes mq-right { from { transform: translateX(-50%); }     to { transform: translateX(0); } }

.chip {
  flex: none; width: 168px; height: 92px;
  display: flex; justify-content: center;
  /* Light in both themes: the marks arrive in their owners' colours, and
     a white wall of logos on the dark section is the intended look. */
  background: #fbfbfa; border: 1px solid rgba(21, 24, 27, 0.12); border-radius: 12px;
  padding: 16px;
}
/* The chips are built in JS with width/height attributes, which are a
   presentational hint setting a hard 140px height. max-height:100% could
   not clamp it: the percentage resolves against a grid area the browser
   treats as indefinite, so it computed to none and every mark overflowed
   its chip by 74px — the two marquee rows collided and the logos were cut
   off. Stretching the box gives a definite height to contain against. */
.chip img {
  width: 100%; height: auto; align-self: stretch;
  object-fit: contain;
  opacity: 0.92;
}
/* No brightness(0) invert(1) here any more. That trick only works when
   every mark is supplied on a transparent background; twelve of these
   ship with an opaque plate, so the filter turned each of them into an
   identical solid white rectangle on the dark theme. The chip stays
   light in both themes instead and every logo keeps its own colours. */
.chip:hover img { opacity: 1; }
/* Two marks are supplied light-on-dark by their owners. Stripping their
   background would erase the logo itself, so on the light theme they keep
   a dark chip and read as intended instead of as a black box. */
.chip.chip-dark {
  background: #0f1216; border-color: rgba(255, 255, 255, 0.14);
}

.sectors {
  list-style: none; display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: clamp(32px, 4vw, 48px);
}
.sectors li {
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--mut);
  border: 1px solid var(--line); border-radius: 999px; padding: 9px 18px;
}

@media (prefers-reduced-motion: reduce) {
  .mq-row { animation: none !important; }
  .ln-rail::after { width: 100% !important; }
}

/* ---- closing call to action -------------------------------- */

.cta-band { padding-block: clamp(72px, 9vw, 128px); background: var(--bg); border-top: 1px solid var(--line); text-align: center; }
.cta-band .sec-h { max-width: 20ch; margin-inline: auto; }
.cta-band .sec-lead { margin-inline: auto; }
.cta-row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 12px; }

/* ---- v1's cursor: exact dot, lagging ring ------------------------ */

.cursor { display: none; }

@media (hover: hover) and (pointer: fine) and (min-width: 901px) {
  .cursor { display: block; }
  .cursor-dot, .cursor-ring {
    position: fixed; top: 0; left: 0; z-index: 99;
    pointer-events: none; border-radius: 50%;
    translate: -50% -50%;
  }
  .cursor-dot { width: 6px; height: 6px; background: var(--blue); }
  .cursor-ring {
    width: 34px; height: 34px;
    border: 1px solid var(--blue); opacity: 0.55;
    transition: width 0.25s var(--ease-snap), height 0.25s var(--ease-snap), opacity 0.25s;
  }
  .cursor.is-active .cursor-ring { width: 56px; height: 56px; opacity: 1; }
  .cursor.is-hidden { display: none; }
}

@media (prefers-reduced-motion: reduce) { .cursor { display: none !important; } }

/* ---- 03 · WHAT WE MAKE ------------------------------------- */

.mk {
  position: relative;
  padding-block: clamp(80px, 10vw, 140px);
  background: var(--bg);
  border-top: 1px solid var(--line);
}
.mk-head { max-width: 620px; margin-bottom: clamp(48px, 6vw, 88px); }

.mk-list { list-style: none; display: grid; gap: clamp(64px, 8vw, 128px); }

.mk-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: center;
}
/* even rows mirror, so the eye zig-zags down the page */
.mk-item:nth-child(even) .mk-copy  { order: 2; }
.mk-item:nth-child(even) .mk-media { order: 1; }

.mk-num {
  display: block;
  font-variation-settings: "wdth" 125;
  font-weight: 700; font-size: 15px; letter-spacing: 0.12em;
  color: var(--brass); margin-bottom: 14px;
}
.mk-copy h3 {
  font-variation-settings: "wdth" 112;
  font-weight: 640; text-transform: uppercase;
  font-size: clamp(1.6rem, 2.5vw, 2.3rem); line-height: 1.06;
  margin-bottom: 16px;
}
.mk-copy p { font-size: clamp(1rem, 1.15vw, 1.08rem); line-height: 1.62; color: var(--mut); max-width: 44ch; }
.mk-note {
  margin-top: 14px; padding-left: 16px;
  border-left: 2px solid var(--brass);
  color: var(--ink) !important; font-size: 0.98rem !important;
}
.mk-ask {
  display: inline-flex; align-items: center; gap: 9px;
  margin-top: 26px;
  color: var(--blue); text-decoration: none;
  font-size: 13px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
}
.mk-ask span { transition: transform var(--t-ui) var(--ease-snap); }
.mk-ask:hover span { transform: translateX(5px); }

.mk-media {
  position: relative;
  border-radius: 18px; overflow: hidden;
  background: var(--bg-2);
  box-shadow: var(--shadow);
  aspect-ratio: 10 / 7;
}
.mk-media > img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* 3D blocks: poster first, live viewer swapped in when it is near */
.mk-3d { background: var(--bg-2) center/58% no-repeat; }
.mk-3d .mv-slot { position: absolute; inset: 0; }
.mk-3d model-viewer {
  width: 100%; height: 100%;
  --poster-color: transparent;
  background: transparent;
}
.mk-hint {
  position: absolute; left: 16px; bottom: 14px;
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--mut);
  pointer-events: none;
  transition: opacity var(--t-ui) ease;
}
.mk-3d:hover .mk-hint { opacity: 0; }

.mk-swap {
  position: absolute; right: 14px; bottom: 12px;
  display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end;
}
.mk-swap button {
  font: inherit; font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  padding: 7px 12px; border-radius: 999px; cursor: pointer;
  color: var(--mut); background: color-mix(in srgb, var(--bg) 72%, transparent);
  border: 1px solid var(--line);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  transition: color var(--t-ui) ease, border-color var(--t-ui) ease;
}
.mk-swap button:hover { color: var(--ink); }
.mk-swap button.on { color: var(--ink); border-color: var(--brass); }

@media (max-width: 900px) {
  .mk-item { grid-template-columns: minmax(0, 1fr); }
  .mk-item:nth-child(even) .mk-copy  { order: 0; }
  .mk-item:nth-child(even) .mk-media { order: 0; }
  /* heavy 3D is desktop-only — the poster stands in */
  .mk-3d .mv-slot, .mk-swap, .mk-hint { display: none; }
}

/* ---- reduced motion ---------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .a3d i { animation: none !important; }
}

/* screen-reader-only text (the client list, for people who cannot see the marquee) */
.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---- photographic page hero (capabilities) ---------------------- */
/* Same contract as the home hero: the band stays dark in both themes so
   light type over the photograph is readable either way. */
.page-hero.is-photo {
  position: relative;
  --ink: var(--gate-ink);
  --mut: rgba(237, 240, 242, 0.78);
  color: var(--gate-ink);
  background: var(--gate-bg);
  border-bottom: 0;
  overflow: clip;
  padding-block: clamp(78px, 11vw, 150px) clamp(64px, 8vw, 110px);
}
.page-hero.is-photo .ph-bg {
  position: absolute; inset: 0;
  background: url("assets/net/pu-foaming-plant-1600.webp") center 46% / cover no-repeat;
}
.page-hero.is-photo .ph-scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(100deg, rgba(11,13,16,0.95) 0%, rgba(11,13,16,0.86) 40%, rgba(11,13,16,0.52) 100%),
    linear-gradient(180deg, rgba(11,13,16,0.8) 0%, transparent 30%);
}
.page-hero.is-photo > .wrap { position: relative; z-index: 2; }
.page-hero.is-photo .eyebrow-2 { color: var(--brass); }

/* ---- leadership portraits --------------------------------------- */
/* The portraits are shot on pure black, so the figure is black too: any
   light showing at the edge reads as a white outline around the head. */
.card-person { padding: 0; overflow: clip; }
.card-person figure {
  margin: 0; background: #000; line-height: 0;
}
.card-person img {
  /* height:auto is load-bearing — the width/height attributes are a
     presentational hint that sets an explicit height, and an explicit
     height makes the browser ignore aspect-ratio entirely. */
  display: block; width: 100%; height: auto;
  aspect-ratio: 1 / 1; object-fit: cover; object-position: 50% 18%;
}
.card-person .card-body { padding: clamp(20px, 2.2vw, 30px); }

/* ---- timeline entries that carry a picture ---------------------- */
.tl-item.has-img { grid-template-columns: 110px minmax(0, 1fr) clamp(190px, 23vw, 320px); }
.tl-item figure {
  margin: 0; border-radius: 12px; overflow: clip;
  border: 1px solid var(--line); align-self: start;
  line-height: 0;
}
.tl-item figure img {
  display: block; width: 100%; height: auto;   /* see .card-person img */
  aspect-ratio: 3 / 2;                         /* the sources are 800x533 */
  object-fit: cover;
}
@media (max-width: 860px) {
  .tl-item.has-img { grid-template-columns: 84px minmax(0, 1fr); }
  .tl-item figure { grid-column: 2; margin-top: 14px; max-width: 320px; }
}

/* ---- photo bands ------------------------------------------------ */
/* Real photography from the plants, captioned in place. The caption
   gradient keeps white type readable over any image in both themes. */
.photo-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 14px; margin-top: 36px;
}
.photo-grid figure {
  position: relative; margin: 0;
  border-radius: 12px; overflow: clip;
  background: var(--panel); border: 1px solid var(--line);
}
.photo-grid img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; aspect-ratio: 4 / 3;
}
.photo-grid figure.wide { grid-column: span 2; }
.photo-grid figure.tall img { aspect-ratio: 3 / 4; }
.photo-grid figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: 16px 16px 12px;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: #fff;
  background: linear-gradient(180deg, transparent, rgba(11, 13, 16, 0.78));
}
@media (max-width: 900px) {
  .photo-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 620px) {
  .photo-grid { grid-template-columns: 1fr; }
  .photo-grid figure.wide { grid-column: auto; }
}

/* ============================================================
   MOBILE
   The phone build is not the desktop build shrunk. The threshold
   never runs below 768px (see main.js SMALL) — the visitor lands
   straight on the hero — so everything below is about the site
   itself reading well in one hand.
   ============================================================ */

@media (max-width: 900px) {
  /* The brand sub-line is set in 0.28em tracking and cannot wrap, so on a
     phone it pushed past the right edge and was clipped mid-word. The
     DP|TG mark alone carries the identity at this size. */
  .brand .sub { display: none; }

  /* .site-head already drops its CTA here; the home page uses #hd, which
     was never covered by that rule, so its bar stayed overcrowded. */
  #hd .cta { display: none; }

  /* Comfortable touch targets — 40px was under the 44px guideline. */
  .tt { width: 44px; height: 44px; }
  .navbtn { width: 44px; height: 44px; }
  .head-end { gap: 10px; }

  /* The mark is the link home from every page, but its box was only as
     tall as the type — 22px. The header is 76px, so the padding is free. */
  .brand { padding-block: 11px; }

  /* The hero was locked to exactly 100vh. Once the headline wraps to more
     lines on a narrow screen the copy overran that box and collided with
     the scroll label pinned to the bottom. Let it grow instead. */
  .hero {
    height: auto;
    min-height: 100svh;
    align-items: flex-start;
    padding-block: calc(76px + clamp(40px, 12vw, 96px)) clamp(56px, 14vw, 104px);
  }
  .h-display { font-size: clamp(2.05rem, 8.4vw, 3.4rem); margin-bottom: 22px; }
  .h-lead {
    font-size: clamp(1rem, 4vw, 1.15rem);
    margin-bottom: 32px; max-width: 46ch;
  }
  .h-eyebrow { font-size: 11.5px; letter-spacing: 0.2em; margin-bottom: 18px; }

  /* Five stats in a single flex row became five cramped columns with
     hairlines between them; stacked pairs read far better. */
  .h-stats { gap: 6px 0; }
  .h-stats li {
    font-size: 14px; padding-inline: 14px; padding-block: 4px;
  }
  .h-stats li:first-child { padding-left: 0; }

  /* Absolutely positioned at the foot of a now auto-height hero, this
     label sat on top of the lead copy. It is decorative. */
  .h-next { display: none; }

  .chip { width: 138px; height: 76px; padding: 12px; }
  .marquee { gap: 10px; }
  .mq-row { gap: 10px; }
  .sectors li { font-size: 11.5px; padding: 8px 14px; }

  /* Every one of these was only as tall as its own text — the footer links
     at 16px, the spec-sheet links at 17px, the phone and email on /contact/
     at 24px, against a 44px guideline. The padding grows the hit area
     without moving the type off its baseline. Calling and mailing are the
     two things this site exists to make easy, so they matter most. */
  .foot-col ul a { display: block; padding-block: 14px; }
  .mk-ask { padding-block: 14px; }
  .contact-block a { padding-block: 10px; }
}

@media (max-width: 620px) {
  .page-hero h1 { font-size: clamp(1.95rem, 8.6vw, 2.6rem); }
  .page-hero .lead-lg { font-size: clamp(1rem, 4vw, 1.1rem); }
  .sec-h { font-size: clamp(1.6rem, 7.4vw, 2.2rem); }

  /* auto-fit with a 270px minimum forces a horizontal scrollbar once the
     wrap padding is subtracted on the narrowest phones */
  .cards { grid-template-columns: minmax(0, 1fr); }

  .chip { width: 118px; height: 66px; padding: 10px; }
  .quote p { font-size: clamp(1.1rem, 5.4vw, 1.45rem); }
  .foot-grid { grid-template-columns: minmax(0, 1fr); gap: 30px; }
  .foot-bottom { flex-direction: column; gap: 8px; }
}

/* Nothing may introduce a sideways scroll on a phone. */
@media (max-width: 900px) {
  html.landed, html.landed body { overflow-x: clip; }
  .wrap { padding-inline: clamp(18px, 5.4vw, 32px); }
  img, video, model-viewer { max-width: 100%; }
}

/* ---- forms on touch devices ------------------------------------- */
/* iOS Safari zooms the whole page when a field smaller than 16px takes
   focus, and never zooms back out. 15px was enough to trigger it on every
   input on the enquiry form. */
@media (max-width: 900px) {
  .field input, .field textarea, .field select { font-size: 16px; }
  .btn { padding: 15px 26px; }              /* 42px tall was under the 44px target */
  .form-grid { grid-template-columns: minmax(0, 1fr); gap: 34px; }
}

/* ---- mobile-only Contact link ----------------------------------- */
/* Desktop reaches the enquiry form through the header CTA. That CTA is
   dropped on phones, which left no route to /contact/ from the menu at
   all, so the menu carries its own link below 900px. */
.nav-contact { display: none; }
@media (max-width: 900px) {
  .nav-contact { display: block; }
  /* Without flex:none the burger was squeezed to ~30px by the brand block
     and fell under the 44px touch target. */
  .navbtn { flex: none; }
  .brand { min-width: 0; }
}

/* Two-up photo rows. This was an inline grid-template-columns, which no
   media query can override — the phone rules below could never collapse
   these to one column. */
.photo-grid.is-duo { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 620px) {
  .photo-grid.is-duo { grid-template-columns: 1fr; }
}

/* ---- footer columns on smaller screens -------------------------- */
@media (max-width: 1000px) { .foot-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .foot-grid { grid-template-columns: minmax(0, 1fr); } }

/* ---- stats row on the narrowest phones -------------------------- */
/* The brass border-left is a separator between items on one line, and only
   :first-child is exempt — so every item that began a new wrapped row drew
   a stray rule and indented 26px against nothing. Flex-wrap gives CSS no
   way to know which item starts a row; a two-column grid does. */
@media (max-width: 620px) {
  .h-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 4px 0; }
  .h-stats li:nth-child(odd) { border-left: 0; padding-left: 0; }
}

/* ---- the open menu in landscape --------------------------------- */
/* Seven links in a fixed panel anchored below the header: on a phone held
   sideways that is taller than what is left of the screen, and the panel
   could not scroll, so the last links were simply unreachable. dvh tracks
   the browser chrome as it collapses; vh is the fallback. */
@media (max-width: 900px) {
  .nav-main.open {
    max-height: calc(100vh - 76px);
    max-height: calc(100dvh - 76px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
}
