/* ==========================================================================
   Eldyne — components
   Naming: block__element--modifier. Each block is self-contained so a CMS
   can render any component from a single template partial.
   ========================================================================== */

/* Nav ------------------------------------------------------------------ */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  min-height: var(--nav-h);            /* min-, not fixed: survives 200% text zoom */
  display: flex; align-items: center;
  background: var(--nav-bg);
  /* Translucent material: content scrolls under it rather than behind an
     opaque bar, and the light top edge catches like real glass. */
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
  transition: background var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
/* Scroll-edge effect instead of a 1px divider (Apple skill §12) */
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 18px; pointer-events: none;
  background: linear-gradient(180deg, var(--bg) 0%, transparent 100%);
  opacity: 0; transition: opacity var(--dur) var(--ease);
}
.nav.is-scrolled::after { opacity: .9; }
@media (prefers-reduced-transparency: reduce) {
  .nav { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.nav__inner { display: flex; align-items: center; gap: var(--s-4); flex: 0 1 auto; min-width: 0; padding-block: .5rem; }
.nav__brand { display: inline-flex; align-items: center; gap: .6rem; font-weight: 600; letter-spacing: .12em; font-size: var(--t--1); }
.nav__brand:hover { color: inherit; }
.nav__mark { width: 22px; height: 22px; }
.nav__nav { margin-left: auto; }
.nav__list { display: flex; gap: var(--s-4); font-size: var(--t--1); margin: 0; padding: 0; list-style: none; }
.nav__link { color: var(--ink-2); padding-block: .5rem; position: relative; }
.nav__link:hover, .nav__link[aria-current="page"] { color: var(--ink); }
.nav__link[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--rose); border-radius: var(--r-pill);
}
.nav__toggle { display: none; width: 44px; height: 44px; margin-left: auto; margin-right: -10px; border-radius: var(--r-2); }
.nav__toggle:active { transform: scale(.94); transition: transform var(--press) var(--ease-out); }
.nav__toggle span {
  display: block; width: 20px; height: 1.5px; background: var(--ink); margin: 5px auto;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

@media (max-width: 900px) {
  .nav__toggle { display: block; }
  .nav__inner { gap: 0; }
  .nav__nav { margin-left: 0; }
  .nav__list {
    position: fixed;
    top: var(--nav-h); left: 0; right: 0; bottom: auto;
    height: 100vh; height: calc(100dvh - var(--nav-h));
    flex-direction: column; gap: 0;
    /* Opaque base first. --nav-bg is ~74% alpha and relied entirely on
       backdrop-filter; where that is unsupported the page showed through. */
    background: var(--bg);
    padding: var(--s-4) var(--gutter) calc(var(--s-6) + env(safe-area-inset-bottom));
    font-size: var(--t-2);
    overflow-y: auto;                  /* five 62px links did not fit a landscape phone */
    overscroll-behavior: contain;
    transform-origin: top right;       /* anchored to the toggle (Apple skill §7) */
    transform: translateY(-6px) scale(.985);
    opacity: 0; pointer-events: none;
    visibility: hidden;                /* keeps the links out of the tab order when closed */
    transition: opacity var(--response) var(--ease-out),
                transform var(--response) var(--ease-out),
                visibility 0s linear var(--response);
  }
  @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .nav__list {
      background: color-mix(in srgb, var(--bg) 97%, transparent);
      -webkit-backdrop-filter: saturate(180%) blur(30px);
      backdrop-filter: saturate(180%) blur(30px);
    }
  }
  .nav__list.is-open {
    opacity: 1; transform: none; pointer-events: auto; visibility: visible;
    transition-delay: 0s;
  }
  @media (prefers-reduced-transparency: reduce) {
    .nav__list { background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
  .nav__link { display: block; padding-block: 1rem; border-bottom: 1px solid var(--line); }
  .nav__link[aria-current="page"]::after { display: none; }
  .nav:has(.nav__list.is-open) { background: var(--bg); }
  .nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
}

/* Buttons & links ------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .8rem 1.25rem; border-radius: var(--r-pill);
  background: var(--ink); color: var(--bg);
  font-size: var(--t--1); font-weight: 500;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), transform 200ms var(--ease);
}
.btn:hover { background: var(--rose); color: #fff; }
/* Feedback on pointer-down, instantly (Apple skill §1) */
.btn:active { transform: scale(.97); transition-duration: var(--press); }
.nav__link, .link, .pillar__go, .nav__toggle { -webkit-tap-highlight-color: transparent; }
.btn--ghost { background: transparent; color: var(--ink); box-shadow: inset 0 0 0 1px var(--line); }
.btn--ghost:active { transform: scale(.97); transition: transform var(--press) var(--ease-out); }
.btn--ghost:hover { background: transparent; color: var(--rose); box-shadow: inset 0 0 0 1px var(--rose); }
.link { color: var(--ink); border-bottom: 1px solid var(--line); padding-bottom: 2px; transition: border-color var(--dur) var(--ease); }
.link:hover { color: var(--ink); border-bottom-color: var(--rose); }

/* Media (photo / video placeholders) ----------------------------------- */
.media {
  position: relative; overflow: hidden;
  background: var(--bg-2);
  aspect-ratio: 16 / 9;
  border-radius: var(--r-3);
}
.media--portrait { aspect-ratio: 4 / 5; }
.media--square { aspect-ratio: 1; }
/* A 21:9 crop of a 16:9 source lands on the sky. Bias the window downward
   so the subject, not the haze, survives the crop. */
.media--wide { aspect-ratio: 21 / 9; }
.media--wide > img { object-position: 50% 68%; }
.media--full { aspect-ratio: auto; position: absolute; inset: 0; }
.media > img, .media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* A real src needs no JS and is never hidden. Only a slot still waiting on
   its file fades in, once site.js has confirmed it is running. */
html.js .media > img[data-src] { opacity: 0; transition: opacity var(--dur-slow) var(--ease); }
html.js .media > img.is-loaded, .media > img.is-loaded { opacity: 1; }
.media > img.is-loaded ~ .media__caption--placeholder { display: none; }
.media > img.is-loaded ~ .media__art { display: none; }
.media__caption {
  position: absolute; left: 1rem; right: 1rem; bottom: .9rem;
  font-size: var(--t--1); color: #B13855;
  text-shadow: none;
}
/* A slot with no photograph yet reads as an intentional duotone panel.
   It must never contain editor instructions — those live in HTML comments. */
.media--empty::after {
  content: ""; position: absolute; inset: 0;
  background:
    repeating-linear-gradient(135deg, var(--hatch) 0 2px, transparent 2px 9px),
    linear-gradient(160deg, var(--empty-tint) 0%, transparent 55%);
  box-shadow: inset 0 0 0 1px var(--line);
  border-radius: inherit;
  pointer-events: none;
}
/* Placeholder scenes. Replace with real photography / video via the CMS.
   Each scene is a restrained gradient so the layout reads without assets. */
.media[data-scene="relay"]   { background: radial-gradient(120% 80% at 70% 60%, #4A4A4A 0%, #3D3D3D 45%, #2A2A2A 100%); }
.media[data-scene="track"]   { background: linear-gradient(180deg, #2A2A2A 0%, #3D3D3D 60%, #4A4A4A 100%); }
.media[data-scene="map"]     { background: radial-gradient(90% 70% at 50% 50%, #3D3D3D 0%, #2A2A2A 100%); }
.media[data-scene="field"]   { background: linear-gradient(180deg, #4A4A4A 0%, #A87F8A 40%, #6E1418 100%); }
.media[data-scene="dawn"]    { background: linear-gradient(180deg, #3D3D3D 0%, #6E1418 45%, #C4647A 100%); }
.media[data-scene="paper"]   { background: linear-gradient(180deg, #FFFFFF 0%, #ECECEC 100%); }
.media[data-scene="studio"]  { background: radial-gradient(100% 80% at 50% 40%, #FFFFFF 0%, #ECECEC 100%); }
.media[data-scene="dusk"]    { background: linear-gradient(180deg, #2A2A2A 0%, #4A4A4A 50%, #A87F8A 100%); }
.media__art { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Journey rail (homepage) ---------------------------------------------
   One row per chapter: a short rule that fills as you move through that
   chapter, with the name set horizontally beside it. */
.rail {
  /* On the right. The chapter copy is left-aligned and capped at 24-44ch,
     so the right side is always clear — on the left the rail crossed the
     headline every time a chapter handed over to the next. */
  position: fixed; right: 0; left: auto;
  top: 50%; transform: translateY(-50%);
  z-index: 20; pointer-events: none;
  padding-right: clamp(.9rem, 2.5vw, 2.25rem);
  opacity: 0; visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility 0s linear var(--dur);
}
.rail.is-ready { opacity: 1; visibility: visible; transition-delay: 0s; }
.rail__list { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.rail__stop { display: block; }
/* Each stop is a link to its chapter, so the rail is navigation and not
   just a read-out. The padding is the touch target; the rail itself stays
   click-through so it never eats a scroll over the page behind it. */
.rail__link {
  pointer-events: auto;
  display: flex; align-items: center; justify-content: flex-end; gap: .7rem;
  flex-direction: row-reverse;
  padding: .5rem 0 .5rem .75rem;
  color: var(--ink-3); text-decoration: none; cursor: pointer;
  transition: color var(--response) var(--ease);
}
.rail__link:hover { color: var(--ink); }
.rail__link:hover .rail__name { opacity: 1; }
.rail__link:hover .rail__bar { width: 40px; }
.rail__link:active { transform: translateX(2px); transition: transform var(--press) var(--ease); }
.rail__link:focus-visible {
  outline: 2px solid var(--brand-rose); outline-offset: 4px; border-radius: var(--r-1);
  color: var(--ink);
}
.rail__link:focus-visible .rail__name { opacity: 1; }
.rail__bar {
  position: relative; display: block;
  width: 22px; height: 2px; border-radius: 2px;
  background: var(--line);
  transition: width var(--response) var(--ease), background var(--response) var(--ease);
}
.rail__fill {
  position: absolute; inset: 0; display: block;
  background: var(--brand-rose); border-radius: inherit;
  transform: scaleX(0); transform-origin: right center;
  /* scroll-driven, so no transition here either */
}
.rail__name {
  font-size: var(--t--1); letter-spacing: var(--track-caps);
  text-transform: uppercase; white-space: nowrap;
  opacity: .45;
  transition: opacity var(--response) var(--ease);
}
.rail__stop.is-on .rail__link { color: var(--ink); }
.rail__stop.is-on .rail__bar { width: 40px; }
.rail__stop.is-on .rail__name { opacity: 1; }
@media (max-width: 1200px) { .rail__name { display: none; } }
@media (max-width: 900px) { .rail { display: none; } }

/* Chapters (pinned scroll sections) ----------------------------------- */
/* Height and the pin must use the SAME unit or the scrub drifts as the
   mobile URL bar collapses. Shortened from 240vh so copy arrives early. */
.chapter { position: relative; height: 180vh; height: 180svh; }
.chapter--short { height: 130vh; height: 130svh; }
.chapter__pin {
  position: sticky; top: 0; height: 100vh; height: 100svh;
  overflow: hidden; display: grid; align-items: end;
}
.chapter__media { position: absolute; inset: 0; }
.chapter__media .media { position: absolute; inset: 0; aspect-ratio: auto; }
.chapter__scrim {
  position: absolute; inset: 0;
  /* Was a hardcoded #0E0F11 that matched no token and no page background. */
  /* The copy block spans roughly 55%-95% of the pin, and one chapter uses a
     WHITE scene. So the scrim has to be fully committed BEFORE the copy
     starts, or light text lands on a light panel at ~2:1. Clean above 34%
     (where the artwork lives), decisive below 55%. */
  /* Measured: the copy block starts between 21% and 59% of the pin depending
     on viewport height, not 55% as the old stops assumed. Anything above the
     old 34% stop sat on a fully transparent scrim — on the white "studio"
     chapter that put near-white text on near-white at about 1.1:1. */
  background: linear-gradient(180deg,
    rgba(var(--scrim), 0) 0%,
    rgba(var(--scrim), .10) 18%,
    rgba(var(--scrim), .55) 34%,
    rgba(var(--scrim), .88) 50%,
    rgba(var(--scrim), .97) 100%);
}
.chapter__copy {
  position: relative; z-index: 2;
  padding-bottom: clamp(3rem, 9vh, 7rem);
  display: grid; gap: var(--s-2);
}
.chapter__year {
  font-size: clamp(3.5rem, 13vw, 13rem); line-height: .9; letter-spacing: -0.05em;
  font-weight: 400; color: var(--ink); font-variant-numeric: tabular-nums;
}
.chapter__line { font-size: var(--t-3); line-height: var(--lh-snug); letter-spacing: var(--track-head); font-weight: 500; max-width: 24ch; text-wrap: balance; }
.chapter__meta { color: var(--ink-2); max-width: 44ch; }

/* Scroll-scrubbed transforms driven by --p (0 → 1) set in JS */
.chapter__media { --p: 0; }
.chapter__media .media {
  transform: scale(calc(1.05 - .05 * var(--p)));
  /* No transition: this is scroll-driven, so it must land on the exact value
     for the current scroll position. A transition makes it chase and lag. */
  transition: none;
  will-change: transform;
}
/* The caption used to sit at bottom:5%, directly over the bottom-aligned
   chapter copy — that collision is why text looked half-hidden. It now sits
   at the top of the frame, well clear of the copy. */
.chapter__media .media__caption {
  left: 50%; right: auto; bottom: auto;
  top: calc(var(--nav-h) + 1.25rem);
  transform: translateX(-50%);
  color: #F4F2F2;
  background: rgba(var(--scrim), .55);
  padding: .4rem .9rem; border-radius: var(--r-pill);
}
.chapter__media .anim { top: calc(var(--nav-h) + 5vh); bottom: 56%; }
@media (max-width: 900px) {
  .chapter__media .media__caption { left: 5%; right: 5%; }
  .chapter__media .anim { top: calc(var(--nav-h) + 4vh); bottom: 48%; }
}
/* Visible by default. Only once site.js confirms it is running (html.js)
   does the scrub take over — and it now reaches full opacity at p=0.12
   rather than p=0.33, so copy appears almost immediately. */
.chapter__copy { --p: 1; }
html.js .chapter__copy {
  --p: 0;
  opacity: calc(min(1, var(--p) * 8));
  transform: translateY(calc((1 - min(1, var(--p) * 8)) * 20px));
  transition: none;          /* scroll-driven — see .chapter__media .media */
  will-change: opacity, transform;
}
.chapter--open .chapter__pin { align-items: center; }
.chapter--open .chapter__copy, html.js .chapter--open .chapter__copy { opacity: 1; transform: none; text-align: center; justify-items: center; padding-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .chapter { height: auto; }
  .chapter__pin { position: relative; height: auto; min-height: 80svh; }
  .chapter__media .media { transform: none; }
  .chapter__copy, html.js .chapter__copy { opacity: 1; transform: none; }
}

/* Statistics that count up -------------------------------------------- */
.stat { display: grid; gap: .35rem; }
.stat__value { font-size: var(--t-6); line-height: 1; letter-spacing: -0.035em; font-weight: 400; font-variant-numeric: tabular-nums; }
.stat__value small { font-size: .4em; letter-spacing: 0; color: var(--ink-2); margin-left: .15em; white-space: nowrap; }
.stat__label { color: var(--ink-2); font-size: var(--t--1); max-width: 22ch; }

/* Pillars ----------------------------------------------------------- */
.pillars { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-2); }
.pillar {
  position: relative; display: grid; align-content: end;
  min-height: 72svh; padding: var(--s-4); overflow: hidden; color: #F3F1EE;
  border-radius: var(--r-3);
}
.pillar .media { position: absolute; inset: 0; aspect-ratio: auto; }
.pillar__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(16,16,18,.10) 30%,
    rgba(16,16,18,.55) 68%,
    rgba(16,16,18,.88) 100%);
}
.pillar__copy { position: relative; z-index: 3; display: grid; gap: .5rem; }
.pillar__kicker { color: rgba(243,241,238,.86); font-size: var(--t--1); letter-spacing: var(--track-caps); text-transform: uppercase; }
.pillar__title { font-size: var(--t-4); line-height: var(--lh-tight); letter-spacing: var(--track-head); font-weight: 500; }
.pillar__go { position: absolute; inset: 0; z-index: 2; }
.pillar__copy > * { pointer-events: none; }   /* clicks fall through to .pillar__go */
.pillar__go:focus-visible { outline-offset: -4px; }
.pillar:hover .media { filter: brightness(1.06); }
.pillar:active .media { transform: scale(.99); }
.pillar:has(.pillar__go:active) { transform: scale(.995); transition: transform var(--press) var(--ease-out); }
.pillar .media { transition: filter var(--dur) var(--ease), transform 120ms var(--ease); }
@media (max-width: 900px) { .pillars { grid-template-columns: minmax(0, 1fr); } .pillar { min-height: 56svh; } }

/* Spec table (product pages) — rows, not cards ------------------------- */
.specs { border-top: 1px solid var(--line); }
.specs__row {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--s-3); padding-block: 1rem;
  border-bottom: 1px solid var(--line);
}
.specs__key { color: var(--ink-2); }
.specs__val { color: var(--ink); }
@media (max-width: 600px) { .specs__row { grid-template-columns: minmax(0, 1fr); gap: .25rem; } }

/* Product hero (light) ------------------------------------------------ */
.product-hero { padding-top: calc(var(--nav-h) + var(--s-6)); }
.product-hero__figure { margin-top: var(--s-5); }

/* Timeline (company) -------------------------------------------------- */
.timeline { display: grid; gap: 0; border-top: 1px solid var(--line); }
.timeline__item { display: grid; grid-template-columns: 8rem minmax(0, 1fr); gap: var(--s-3); padding-block: var(--s-3); border-bottom: 1px solid var(--line); }
.timeline__year { font-size: var(--t-3); letter-spacing: -0.03em; line-height: 1; color: var(--accent); font-variant-numeric: tabular-nums; }
.timeline__text { color: var(--ink-2); max-width: var(--measure); }
@media (max-width: 600px) { .timeline__item { grid-template-columns: minmax(0, 1fr); gap: .5rem; } }

/* Project map (field) ------------------------------------------------- */
.projects { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); }
.project { display: grid; gap: .75rem; }
.project__title { font-weight: 500; }
.project__meta { color: var(--ink-2); font-size: var(--t--1); }
@media (max-width: 900px) { .projects { grid-template-columns: minmax(0, 1fr); } }

/* Exploded view (Krishi-EL) ------------------------------------------- */
.exploded { position: relative; }
.exploded__stage { position: relative; aspect-ratio: 4 / 3; }
.exploded__labels { position: absolute; inset: 0; pointer-events: none; }
.exploded__part { position: absolute; transition: transform var(--dur-slow) var(--ease), opacity var(--dur-slow) var(--ease); }
/* Visible without JS; only the animated entrance is gated on html.js. */
html.js .exploded:not(.is-in) .exploded__part { opacity: 0; }
html.js .exploded:not(.is-in) .exploded__part--frame { transform: translateY(-40px); }
html.js .exploded:not(.is-in) .exploded__part--tank  { transform: translateY(40px); }
html.js .exploded:not(.is-in) .exploded__part--rotors { transform: translateY(-80px); }
html.js .exploded:not(.is-in) .exploded__part--nozzles { transform: translateY(80px); }
.exploded__label {
  position: absolute; font-size: var(--t--1); color: var(--ink-2);
  transition: opacity var(--dur-slow) var(--ease) 400ms;
}
html.js .exploded:not(.is-in) .exploded__label { opacity: 0; }

/* Day-of-operation triptych ------------------------------------------- */
.triptych { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); }
.triptych figcaption { margin-top: .75rem; color: var(--ink-2); font-size: var(--t--1); }
.triptych time { color: var(--ink); }
@media (max-width: 900px) { .triptych { grid-template-columns: minmax(0, 1fr); } }

/* Audience list -------------------------------------------------------- */
.audience { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-4); border-top: 1px solid var(--line); padding-top: var(--s-4); }
.audience__title { font-weight: 500; margin-bottom: .5rem; }
.audience__text { color: var(--ink-2); font-size: var(--t--1); }
@media (max-width: 900px) { .audience { grid-template-columns: minmax(0, 1fr); } }

/* Contact form --------------------------------------------------------- */
.form { display: grid; gap: var(--s-3); max-width: 36rem; }
.field { display: grid; gap: .4rem; }
.field label { font-size: var(--t--1); color: var(--ink-2); }
.field input, .field select, .field textarea {
  font: inherit; color: var(--ink); background: var(--bg-2);
  border: 1px solid var(--line); border-radius: var(--r-2); padding: .8rem .9rem;
  width: 100%; max-width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus { outline: 2px solid var(--rose); outline-offset: 0; border-color: transparent; }
.field__hint { font-size: var(--t--1); color: var(--ink-3); }

/* Footer --------------------------------------------------------------- */
.footer { border-top: 1px solid var(--line); padding-block: var(--s-6) var(--s-4); font-size: var(--t--1); color: var(--ink-2); }
.footer__grid { display: grid; grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)); gap: var(--s-4); }
.footer__col { display: grid; gap: .5rem; align-content: start; }
.footer__col a { color: var(--ink-2); }
.footer__col a:hover { color: var(--ink); }
/* The wordmark carries the Eldyne brand colour, not body ink. */
.footer__wordmark { font-size: var(--t-2); letter-spacing: .14em; font-weight: 600; color: var(--rose); }
.footer__legal { margin-top: var(--s-5); display: flex; justify-content: space-between; gap: var(--s-2); flex-wrap: wrap; color: var(--ink-3); }
@media (max-width: 900px) { .footer__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
@media (max-width: 600px) { .footer__grid { grid-template-columns: minmax(0, 1fr); } }

/* Page transition seam between dark and light sections ---------------- */
.seam { height: 1px; background: var(--line); }

/* Animations (js/animations.js) -------------------------------------
   All strokes use theme tokens so the same drawing works on both themes. */
.anim { position: absolute; inset: 0; }
.anim__svg { width: 100%; height: 100%; display: block; }
.anim__label { font-family: var(--font); font-size: 22px; fill: var(--ink-2); }
.anim__num { font-family: var(--font); font-size: 56px; fill: var(--ink); font-variant-numeric: tabular-nums; }
.media .anim { z-index: 1; }

.st-line, .st-hair, .st-arm, .st-rail, .st-sleeper, .st-track, .st-blade, .st-row, .st-armline {
  fill: none; stroke: var(--ink-2); stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.st-line { stroke-width: 3; }
.st-hair { stroke-width: 1; stroke: var(--line); }
.st-coil { fill: var(--rose); fill-opacity: .06; stroke: var(--ink-2); stroke-width: 3; transition: fill-opacity 300ms linear; }
.st-arm { stroke-width: 6; stroke: var(--ink); }
.st-armfill { fill: var(--ink); }
.st-pivot { fill: var(--bg); stroke: var(--ink); stroke-width: 3; }
.st-lamp { fill: transparent; stroke: var(--ink-2); stroke-width: 2; transition: fill 200ms linear; }

/* Q-Series relay line diagram — drawn from the real relay -------------- */
.st-case { fill: none; stroke: var(--ink-2); stroke-width: 2.5; }
.st-base { fill: var(--ink); fill-opacity: .82; stroke: var(--ink-2); stroke-width: 2; }
.st-metal { fill: var(--ink-2); fill-opacity: .30; stroke: var(--ink-2); stroke-width: 2; }
.st-stack { fill: var(--ink); fill-opacity: .55; stroke: var(--ink-2); stroke-width: 2; }
.st-carrier { fill: var(--ink); fill-opacity: .30; stroke: var(--ink); stroke-width: 2.5; }
.st-blade-hi { fill: none; stroke: var(--ink); stroke-width: 11; stroke-linecap: round; }
.st-spring { fill: none; stroke: var(--ink-2); stroke-width: 2.5; stroke-linejoin: round; }
.st-fine { stroke: var(--ink-2); stroke-opacity: .55; stroke-width: 1.2; }
/* Contact points: unlit by default, filled with the brand colour when made. */
.st-cpt, .st-cpt-mov { fill: var(--bg); stroke: var(--ink-2); stroke-width: 2; transition: fill 160ms linear; }
.st-cpt-mov { stroke: var(--ink); }

.st-rail { stroke-width: 4; }
.st-sleeper { stroke-width: 2; stroke: var(--line); }
.st-section { fill: var(--rose); fill-opacity: .04; stroke: var(--line); stroke-width: 2; stroke-dasharray: 6 8; transition: fill-opacity 400ms, stroke 400ms; }
.st-dp { fill: var(--rose); }
.st-pulse { fill: none; stroke: var(--rose); stroke-width: 3; opacity: 0; }
.st-train { fill: var(--ink); fill-opacity: .92; }
.st-wheel { fill: var(--bg); stroke: var(--ink); stroke-width: 4; }

.st-track { stroke-width: 4; stroke: var(--line); transition: stroke 250ms, stroke-width 250ms; }
.st-blade { stroke-width: 4; stroke: var(--ink-2); }
.st-red { fill: #B53A3A; transition: opacity 300ms; }
.st-green { fill: #4FA35B; transition: opacity 300ms; }

.st-field { fill: var(--mauve); fill-opacity: .10; stroke: var(--line); stroke-width: 2; }
.st-row { stroke-width: 1; stroke: var(--line); }
.st-swath { stroke: var(--rose); stroke-width: 70; stroke-opacity: .45; stroke-linecap: butt; }
.st-rotor { fill: var(--ink); fill-opacity: .18; stroke: var(--ink); stroke-width: 2; }
.st-armline { stroke-width: 4; stroke: var(--ink); }
.st-body { fill: var(--ink); }
.st-tank { fill: var(--rose); }
.st-plume { fill: var(--rose); fill-opacity: .35; transition: opacity 200ms; }

/* Values row --------------------------------------------------------- */
.values { display: flex; flex-wrap: wrap; gap: .5rem 2rem; color: var(--ink); font-size: var(--t-1); letter-spacing: -0.01em; }

/* Testimonial --------------------------------------------------------- */
.quote { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: var(--s-5); align-items: end; }
.quote__text { font-size: var(--t-2); line-height: 1.3; letter-spacing: var(--track-head); text-wrap: pretty; }
.quote__who { margin-top: var(--s-3); color: var(--ink-2); font-size: var(--t--1); }
.quote__who strong { color: var(--ink); font-weight: 500; display: block; }
@media (max-width: 900px) { .quote { grid-template-columns: minmax(0, 1fr); } }

/* Photo strip --------------------------------------------------------- */
.strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-2); }
@media (max-width: 900px) { .strip { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }

/* Fact list (plain rows) ---------------------------------------------- */
.facts { border-top: 1px solid var(--line); }
.facts__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); gap: var(--s-3); padding-block: 1rem; border-bottom: 1px solid var(--line); }
.facts__key { color: var(--ink); font-weight: 500; }
.facts__val { color: var(--ink-2); max-width: var(--measure); }
@media (max-width: 600px) { .facts__row { grid-template-columns: minmax(0, 1fr); gap: .25rem; } }

/* Partners ------------------------------------------------------------ */
.partners { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); }
.partner { border-top: 1px solid var(--line); padding-top: 1rem; display: grid; gap: .3rem; }
.partner__name { font-weight: 500; }
.partner__text { color: var(--ink-2); font-size: var(--t--1); }
@media (max-width: 900px) { .partners { grid-template-columns: minmax(0, 1fr); } }

/* Narrow phones — component grids -------------------------------------- */
@media (max-width: 600px) {
  .footer__legal { flex-direction: column; gap: .5rem; }
  /* The zones table is a horizontal scroll region; make it reachable by keyboard */
  .table-wrap:focus-visible { outline: 2px solid var(--rose); outline-offset: 2px; }
}

/* Exploded diagram: the four labels are positioned as percentages over a
   4:3 figure. At 360px the figure is 320px wide and the labels overlapped
   both the artwork and each other, so below 900px they stack underneath. */
@media (max-width: 900px) {
  .exploded__labels { position: static; }
  .exploded__label {
    position: static;
    inset: auto !important;
    display: block;
    padding-block: .5rem;
    border-bottom: 1px solid var(--line);
  }
  .exploded__labels { margin-top: var(--s-3); border-top: 1px solid var(--line); }
}

/* Zone map — the map supplied by Eldyne, with its own labels. ---------- */
.zmap { margin: var(--s-4) 0 0; }
.zmap__scroll { display: block; }
.zmap__img {
  width: 100%; height: auto; display: block;
  /* The map is supplied on white. Multiplying it against the page drops the
     white out, so it sits on the section instead of inside a white box. */
  mix-blend-mode: multiply;
}
[data-theme="dark"] .zmap__img { mix-blend-mode: normal; border-radius: var(--r-3); }

/* Support request (contact) -------------------------------------------- */
.support { border-top: 1px solid var(--line); padding-top: var(--s-5); margin-top: var(--s-6); display: grid; gap: var(--s-2); }
.support__ways {
  display: grid; grid-template-columns: auto minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-5); align-items: start; margin-top: var(--s-3);
}
.support__way { display: grid; gap: .6rem; align-content: start; }
.support__way:first-child {
  justify-items: center;
  text-align: center;
}
.support__qr {
  width: 148px; height: 148px; border-radius: var(--r-2);
  background: #fff; padding: 8px; box-shadow: var(--shadow-1);
  display: block;
}
.support__lead { font-weight: 500; color: var(--ink); }
.support__label { font-size: var(--t--1); color: var(--ink-3); }
@media (max-width: 900px) {
  .support__ways { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); }
  .support__way:first-child { justify-items: center; }
}

/* Testimonial is set in italic ----------------------------------------- */
.quote__text { font-style: italic; }

/* Machine: product shot + part list ------------------------------------ */
.machine { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: var(--s-5); align-items: center; margin: var(--s-5) 0 0; }
.machine__shot { border-radius: var(--r-3); overflow: hidden; background: var(--bg-2); }
.machine__shot img { width: 100%; height: auto; display: block; }
.machine__parts { display: grid; gap: 0; border-top: 1px solid var(--line); }
.machine__parts li { padding-block: .85rem; border-bottom: 1px solid var(--line); }
.machine__part { color: var(--ink); }
@media (max-width: 900px) { .machine { grid-template-columns: minmax(0, 1fr); gap: var(--s-4); } }

/* Opening film ---------------------------------------------------------
   The film is the hero. It carries its own on-screen titles, so nothing of
   ours is laid over it — the page heading follows underneath instead. */
.filmhero { padding-top: var(--nav-h); }
.filmhero__frame {
  position: relative; background: #000;
  aspect-ratio: 16 / 9; max-height: 78svh; overflow: hidden;
}
.filmhero__video {
  width: 100%; height: 100%; object-fit: contain;
  display: block; background: #000;
}
.filmhero__fallback { padding: var(--s-4); color: var(--ink-2); }
.filmhero__copy { padding-block: var(--s-5) 0; display: grid; gap: var(--s-2); }
.filmhero__sound {
  position: absolute; right: var(--s-3); bottom: var(--s-3);
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem 1rem; border-radius: var(--r-pill);
  background: rgba(20,20,20,.62); color: #F4F2F2;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  font-size: var(--t--1); font-weight: 500;
  transition: background var(--response) var(--ease), transform var(--press) var(--ease-out);
}
.filmhero__sound:hover { background: var(--brand); }
.filmhero__sound:active { transform: scale(.97); }
.filmhero__sound.is-on { background: var(--brand); }
@media (max-width: 700px) {
  .filmhero__frame { max-height: none; }
  .filmhero__sound { right: var(--s-2); bottom: var(--s-2); }
}
.btn--play { background: var(--bg-2); color: var(--ink); }
.btn--play:hover { background: var(--brand); color: #fff; }
.btn--play.is-on { background: var(--brand); color: #fff; }
/* A speaker glyph drawn in CSS, so there is no icon file to load. */
.btn__spk {
  width: 14px; height: 12px; display: inline-block; position: relative;
  margin-right: .15rem;
}
.btn__spk::before {
  content: ""; position: absolute; left: 0; top: 3px;
  width: 0; height: 0;
  border-right: 7px solid currentColor;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
}
.btn__spk::after {
  content: ""; position: absolute; left: 8px; top: 2px;
  width: 5px; height: 8px;
  border: 1.5px solid currentColor; border-left: 0;
  border-radius: 0 6px 6px 0;
  opacity: .85;
}

/* Line icons — one shared treatment ------------------------------------ */
.machine__icon .ln, .area__icon .ln {
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.machine__icon circle:not(.ln circle), .area__icon circle:not(.ln circle) { fill: currentColor; }

.machine__parts li { display: flex; align-items: center; gap: var(--s-2); }
.machine__icon { width: 26px; height: 26px; flex: 0 0 auto; color: var(--brand-rose); }

/* Three development areas ---------------------------------------------- */
.areas {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(2rem, 3vw, 4rem);
  margin-top: var(--s-4);
  align-items: start;
}
.area {
  display: grid;
  gap: 1rem;
  justify-items: start;
}
.area__icon {
  width: clamp(56px, 5vw, 82px);
  height: clamp(56px, 5vw, 82px);
  color: var(--brand-rose);
}
.area__name {
  font-size: clamp(2rem, 2vw, 3rem);
  line-height: 1.1;
  letter-spacing: -.04em;
  color: var(--ink);
}
@media (max-width: 900px) { .areas { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .areas { grid-template-columns: minmax(0, 1fr); gap: var(--s-3); } }

/* Day-in-the-life filmstrip -------------------------------------------- */
.filmstrip { margin-inline: calc(var(--gutter) * -1); }
.filmstrip__track {
  display: flex; gap: var(--s-2);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-inline: var(--gutter);
  padding-bottom: var(--s-2);
  scrollbar-width: thin;
}
.filmstrip__item {
  flex: 0 0 min(62%, 34rem);
  scroll-snap-align: start;
}
.filmstrip__item .media {
  border-radius: var(--r-3);
  isolation: isolate;
}
/*.filmstrip__item .media::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: clamp(110px, 18%, 180px);
  height: clamp(30px, 9%, 52px);
  background: rgba(17, 17, 17, .18);
  border-bottom-right-radius: .75rem;
  box-shadow: 0 0 0 1px rgba(255,255,255,.02);
  z-index: 1;
  pointer-events: none;
}*/
.filmstrip__item figcaption { display: none; }
.filmstrip__item time { display: none; }
@media (max-width: 700px) { .filmstrip__item { flex-basis: 84%; } }

/* Content photographs are never cropped ---------------------------------
   `.media` frames default to object-fit:cover, which is right for full-bleed
   backgrounds but cuts people out of ordinary photographs. `--fit` lets the
   frame take the picture's own shape so the whole frame is shown. */
.media--fit { aspect-ratio: auto; background: transparent; }
.media--fit > img {
  position: static; width: 100%; height: auto;
  object-fit: contain; display: block;
}

/* The gallery photographs are all 16:9, so the frames match them exactly. */
.filmstrip__item .media { aspect-ratio: 16 / 9; }
.filmstrip__item .media > img { object-fit: cover; }
.filmstrip__track { align-items: start; }
/* ==========================================================================
   Eldyne — responsive fixes
   Append to the END of css/components.css, or paste into a new stylesheet
   loaded after it. Three findings from a device-matrix test of
   eldyne-review-2026-09-16-v5-fixed.

   Everything else passed: no horizontal scrolling on any page at 320, 375,
   390, 744, 768, 844 (landscape), 901, 1024 or 1920px.
   ========================================================================== */

/* 1. Zone-map labels are unreadable on tablets --------------------------
   The zone names are part of the image now, so they cannot be hidden and
   re-laid out the way the old SVG's could. Below 900px the map holds the
   width at which its labels stay legible and the figure scrolls sideways
   instead, with the names repeated underneath for anyone who would rather
   read than swipe. */
@media (max-width: 900px) {
  .zmap__scroll {
    overflow-x: auto; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch; scrollbar-width: thin;
  }
  .zmap__img { width: 880px; max-width: none; }
  .zmap::after {
    content: "Northern · North Eastern · North Western · North Central · West Central · Central · Western · South Western · Northeast Frontier · East Central · South Eastern · Eastern · Metro Railway Kolkata · East Coast · South East Central · South Central · Southern";
    display: block;
    margin-top: var(--s-3);
    font-size: var(--t--1);
    color: var(--ink-2);
    line-height: 1.7;
  }
}

/* 2. Footer links are small touch targets ------------------------------
   Measured 15-20px tall on a phone, against the 44px that both Apple and
   the WCAG target-size guidance ask for. Padding the links out costs no
   visual weight because the column already has a gap. */
@media (max-width: 900px) {
  .footer__col { gap: 0; }
  .footer__col a {
    display: inline-block;
    padding-block: .62rem;      /* 13px line + 20px padding ≈ 44px */
    min-height: 44px;
  }
  .footer__legal a {
    display: inline-block;
    padding-block: .5rem;
  }
}

/* 3. The wordmark is the only link home, and it is a small target ------- */
@media (max-width: 900px) {
  .nav__brand {
    min-height: 44px;
    padding-right: .5rem;       /* widens the hit area without moving the text */
  }
}

/* ======================================================================
   Redesigned information sections
   The site had six near-identical hairline-ruled row components, which is
   why dense pages read as undifferentiated lists. These give each kind of
   information a shape that suits it, using tokens that already exist.
   ====================================================================== */

/* Shared line-icon treatment, extended to the new components ----------- */
.cardgrid__icon .ln, .audience__icon .ln, .approval__icon .ln {
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.cardgrid__icon circle:not(.ln circle),
.audience__icon circle:not(.ln circle),
.approval__icon circle:not(.ln circle) { fill: currentColor; }

/* Card grid — replaces the .specs / .facts definition lists ------------
   A key/value row is hard to scan when there are fifteen of them. As cards
   the key becomes a heading you can find, and the value gets its own space. */
.cardgrid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3); margin: 0;
}
.cardgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.card {
  display: grid; gap: .55rem; align-content: start;
  padding: var(--s-3);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  transition: border-color var(--response) var(--ease), box-shadow var(--response) var(--ease);
}
.card:hover { border-color: color-mix(in srgb, var(--brand-rose) 45%, var(--line)); box-shadow: var(--shadow-1); }
.cardgrid__icon { width: 26px; height: 26px; color: var(--brand-rose); }
.card__key {
  font-size: var(--t--1); letter-spacing: var(--track-caps);
  text-transform: uppercase; color: var(--ink-3); margin: 0;
}
.card__val { color: var(--ink); margin: 0; }
.card--wide { grid-column: 1 / -1; }
@media (max-width: 760px) {
  .cardgrid, .cardgrid--3 { grid-template-columns: minmax(0, 1fr); }
}

/* Approvals — the year is the fact worth seeing first ------------------ */
.approvals {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-3);
}
.approval {
  display: grid; gap: .5rem; align-content: start;
  padding: var(--s-3);
  border: 1px solid var(--line);
  border-radius: var(--r-3);
  background: var(--bg-2);
  border-top: 3px solid var(--brand-rose);
}
.approval__icon { width: 30px; height: 30px; color: var(--brand-rose); }
.approval__year {
  font-size: var(--t-3); line-height: 1; letter-spacing: -.03em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.approval__name { font-weight: 600; color: var(--ink); }
.approval__ref { color: var(--ink-2); font-size: var(--t--1); }
@media (max-width: 900px) { .approvals { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .approvals { grid-template-columns: minmax(0, 1fr); } }

/* Audience — three owner types, given the editorial-card treatment ----- */
.audience {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-4); border-top: 0; padding-top: 0;
}
.audience__item {
  display: grid; gap: .8rem; align-content: start;
  padding: var(--s-4) var(--s-3) var(--s-3);
  border-radius: var(--r-3);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid var(--line);
}
.audience__icon { width: 46px; height: 46px; color: var(--brand-rose); }
.audience__title { font-size: var(--t-2); line-height: 1.15; letter-spacing: var(--track-head); color: var(--ink); font-weight: 500; margin: 0; }
.audience__text { color: var(--ink-2); font-size: var(--t-0); margin: 0; }
@media (max-width: 900px) { .audience { grid-template-columns: minmax(0, 1fr); } }

/* Milestones — a rail you move along, not a column you fall down --------
   Eleven dated entries stacked vertically ran to several screens and read
   as a long list. As a horizontal rail the whole span is one gesture: a
   swipe on a phone or tablet, the arrows or a trackpad on a desktop. The
   same markup serves all three; only the axis changes. */
.timeline {
  --tl-gap: var(--s-3);
  display: flex; gap: var(--tl-gap);
  /* Room above for the node, which sits on the line and would otherwise be
     sliced in half by the scroll container clipping its own overflow. */
  margin: var(--s-5) 0 0; padding: 8px 0 var(--s-2);
  border-top: 0;
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* The card at the right edge is meant to be cut — the fade says so, so it
     reads as "there is more" rather than as a rendering fault. */
  -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 4rem), transparent 100%);
          mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 4rem), transparent 100%);
}
.timeline.is-end {
  -webkit-mask-image: none; mask-image: none;
}
.timeline::-webkit-scrollbar { display: none; }
.timeline:focus-visible { outline: 2px solid var(--brand-rose); outline-offset: 6px; border-radius: var(--r-2); }
.timeline__item {
  flex: 0 0 clamp(15rem, 72vw, 19rem);
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  gap: 0; padding: 0; border-bottom: 0;
  scroll-snap-align: start;
}
/* The line runs through every card and over the gap between them, so it
   reads as one rail rather than eleven dashes. */
.timeline__spine {
  grid-row: 1;
  position: relative; align-self: auto;
  width: calc(100% + var(--tl-gap)); height: 1px;
  background: var(--line);
  margin-bottom: var(--s-4);
}
.timeline__item:first-child .timeline__spine {
  background: linear-gradient(90deg, transparent 0 5px, var(--line) 5px);
}
.timeline__item:last-child .timeline__spine {
  width: 100%;
  background: linear-gradient(90deg, var(--line) 0 5px, transparent 5px);
}
.timeline__spine::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 11px; height: 11px; margin: -5.5px 0 0 -1px;
  border-radius: 50%;
  background: var(--bg); border: 2px solid var(--brand-rose);
  transition: background var(--response) var(--ease), transform var(--response) var(--ease-out);
}
/* Year and text share one panel, so an entry reads as a single thing
   hanging off its node rather than as two loose paragraphs. */
.timeline__year {
  grid-row: 2;
  font-size: var(--t-3); line-height: 1; letter-spacing: -.03em;
  color: var(--brand-rose); font-variant-numeric: tabular-nums;
  text-align: left;
  margin-right: var(--tl-gap);
  padding: var(--s-3) var(--s-3) .55rem;
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid var(--line); border-bottom: 0;
  border-radius: var(--r-3) var(--r-3) 0 0;
  transition: background var(--response) var(--ease), border-color var(--response) var(--ease);
}
.timeline__text {
  grid-row: 3;
  color: var(--ink-2); max-width: none;
  font-size: var(--t-0); margin: 0;
  margin-right: var(--tl-gap);
  padding: 0 var(--s-3) var(--s-3);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 var(--r-3) var(--r-3);
  transition: background var(--response) var(--ease), border-color var(--response) var(--ease);
}
.timeline__item:hover .timeline__year,
.timeline__item:hover .timeline__text {
  background: color-mix(in srgb, var(--brand-rose) 7%, transparent);
  border-color: color-mix(in srgb, var(--brand-rose) 30%, var(--line));
}
.timeline__item:hover .timeline__spine::before { background: var(--brand-rose); transform: scale(1.15); }

/* Progress and arrows, added by the script only when the rail overflows -- */
.tlfoot { display: flex; align-items: center; gap: var(--s-3); margin-top: var(--s-3); }
.tlbar { flex: 1 1 auto; height: 3px; border-radius: 3px; background: var(--line); overflow: hidden; }
.tlbar__fill {
  display: block; height: 100%; border-radius: inherit;
  background: var(--brand-rose);
  transition: transform 120ms linear;
}
.tlnav { display: flex; gap: .5rem; }
.tlnav__btn {
  width: 40px; height: 40px; display: grid; place-items: center;
  border-radius: 50%; border: 1px solid var(--line);
  background: var(--bg-2); color: var(--ink); cursor: pointer;
  transition: background var(--response) var(--ease), border-color var(--response) var(--ease),
              transform var(--press) var(--ease), opacity var(--response) var(--ease);
}
.tlnav__btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tlnav__btn:hover:not(:disabled) { border-color: color-mix(in srgb, var(--brand-rose) 45%, var(--line)); background: color-mix(in srgb, var(--brand-rose) 10%, var(--bg-2)); }
.tlnav__btn:active:not(:disabled) { transform: scale(.92); }
.tlnav__btn:disabled { opacity: .3; cursor: default; }
.tlnav__btn:focus-visible { outline: 2px solid var(--brand-rose); outline-offset: 3px; }
@media (max-width: 700px) {
  /* Nothing to press on a phone — the rail is swiped. The bar stays, as the
     only thing that says how much is left. */
  .tlnav { display: none; }
}

/* ======================================================================
   Card flow, and giving each card family its own shape
   Every dense section had become the same bordered box, so a spec, an
   approval and an audience all read alike and the pages flattened out.
   The approval card stays as it is — it works — and the others move away
   from it: specs become compact tinted tiles with a brand edge, machine
   parts become numbered rows. All of them now arrive in sequence and
   answer to the pointer.

   Entrance uses `translate`, hover and press use `transform`. They are
   separate properties, so the lift never fights the arrival.
   ====================================================================== */

/* REVERTED: the staggered entrance used to start every card at opacity 0
   and wait for a script to reveal it. The script was not in site.js, so the
   cards never came back and whole sections read as blank. Nothing here may
   hide content on a promise that something else will show it again, so the
   arrival animation is gone. Hover and press below are additive only. */

/* Spec cards — a tinted tile with a brand edge, icon beside its label --
   Three across instead of two, so fifteen facts read as a panel of facts
   rather than fifteen paragraphs stacked down the page. */
.cardgrid, .cardgrid--3 {
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: var(--s-3);
}
.card {
  position: relative;
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  column-gap: .55rem; row-gap: .45rem;
  align-items: center; align-content: start;
  padding: var(--s-3) var(--s-3) var(--s-3) calc(var(--s-3) + .35rem);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  border: 1px solid transparent;
  border-radius: var(--r-3);
  overflow: hidden;
  transition: background var(--response) var(--ease),
              border-color var(--response) var(--ease),
              box-shadow var(--response) var(--ease),
              transform var(--response) var(--ease-out);
}
.card::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--brand-rose); opacity: .5;
  transition: opacity var(--response) var(--ease);
}
.card > .cardgrid__icon { grid-column: 1; grid-row: 1; width: 22px; height: 22px; }
.card__key { grid-column: 2; grid-row: 1; }
.card__val { grid-column: 1 / -1; grid-row: 2; font-size: var(--t-0); line-height: 1.45; }
.card:hover, .card:focus-within {
  background: color-mix(in srgb, var(--brand-rose) 8%, transparent);
  border-color: color-mix(in srgb, var(--brand-rose) 32%, transparent);
  box-shadow: var(--shadow-1);
  transform: translateY(-3px);
}
.card:hover::before, .card:focus-within::before { opacity: 1; }
.card:active { transform: scale(.985); transition-duration: var(--press); }
/* No card spans any more. A spanning card left a hole beside it on every
   row it did not fill, and the grid read as broken rather than composed. */
.card--wide { grid-column: auto; }

/* Approvals and audience — same pointer manners, shapes left alone ----- */
.approval, .audience__item {
  transition: background var(--response) var(--ease),
              border-color var(--response) var(--ease),
              box-shadow var(--response) var(--ease),
              transform var(--response) var(--ease-out);
}
.approval:hover, .audience__item:hover,
.approval:focus-within, .audience__item:focus-within {
  border-color: color-mix(in srgb, var(--brand-rose) 38%, var(--line));
  box-shadow: var(--shadow-2);
  transform: translateY(-4px);
}
.audience__item:hover { background: color-mix(in srgb, var(--brand-rose) 7%, transparent); }
.approval:active, .audience__item:active { transform: scale(.985); transition-duration: var(--press); }
.approval__icon, .audience__icon { transition: transform var(--response) var(--ease-out); }
.approval:hover .approval__icon, .audience__item:hover .audience__icon { transform: scale(1.08); }

/* Machine parts — numbered rows, not a hairline table ------------------ */
.machine__parts { counter-reset: part; gap: .45rem; border-top: 0; align-content: center; }
.machine__parts li {
  counter-increment: part;
  display: grid; grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center; gap: var(--s-2);
  padding: .8rem .95rem;
  border-bottom: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  background: color-mix(in srgb, var(--ink) 4%, transparent);
  transition: background var(--response) var(--ease),
              border-color var(--response) var(--ease),
              transform var(--response) var(--ease-out);
}
.machine__parts li::before {
  content: counter(part, decimal-leading-zero);
  font-size: var(--t--1); letter-spacing: var(--track-caps);
  font-variant-numeric: tabular-nums; color: var(--ink-3);
  transition: color var(--response) var(--ease);
}
.machine__parts li:hover {
  background: color-mix(in srgb, var(--brand-rose) 10%, transparent);
  border-color: color-mix(in srgb, var(--brand-rose) 34%, var(--line));
  transform: translateX(4px);
}
.machine__parts li:hover::before { color: var(--brand-rose); }
.machine__parts li:active { transform: scale(.99); transition-duration: var(--press); }
