/* ==========================================================================
   Linker Tel — Precision Hardware & Systems Engineering
   Aesthetic: Machined titanium, deep obsidian slate, precision engineering
   datum lines, CAD-inspired viewport framing, and restrained telemetry signals.
   Designed for Tier-1 semiconductor and manufacturing partners.
   ========================================================================== */

:root {
  /* Surface & Ground.
     Sampled from the brand image rather than chosen: deep space there measures
     #010103, the nebula #010206 and the foreground terrain a literal #000000.
     The image reads as blue but is almost entirely black -- the blue is a few
     thin strokes against near-nothing. So the ground goes darker and takes a
     blue bias, which also makes every existing accent read brighter without
     touching the accents themselves. */
  --ground:        #05070E;
  --surface:       #0A0E18;
  --surface-2:     #101622;
  --surface-card:  #0C111C;
  --surface-hover: #141C2A;

  /* Typography Colors — machined titanium and calibrated engineering tones */
  --steel-bright:  #F2F6FA;
  --steel:         #D1D9E2;   /* primary body — crisp, high legibility */
  --steel-dim:     #8C99A8;   /* secondary explanatory prose */
  /* Metadata, labels, technical annotations. #637282 was annotated 5.6:1 but
     measures 3.98:1 against this ground — under the 4.5:1 AA minimum, and it
     styles most of the small text on the site. This is 4.83:1, measured. */
  --steel-deep:    #70808F;

  /* Structural Rulers & Hairlines */
  --line:          rgba(209, 217, 226, 0.14);
  --line-soft:     rgba(209, 217, 226, 0.07);
  --line-focus:    rgba(209, 217, 226, 0.32);

  /* Telemetry & Signal Accents (used with strict engineering discipline).
     Retuned to the brand image's own two blues. It works with a deep
     structural stroke and a near-white peak, not one mid cyan: the ring
     strokes sample #08549F and the ripple highlight #B0EBFD. Two values give
     the depth a single flat accent cannot.
     --signal-deep is structural ONLY -- borders, strokes, active states. At
     roughly 2.1:1 on this ground it must never carry text. */
  --signal:        #3B9EFF;   /* the image's azure, lifted to stay legible */
  --signal-deep:   #08549F;   /* sampled ring stroke — structure, never text */
  --signal-peak:   #B0EBFD;   /* sampled ripple highlight — the near-white top */
  --signal-dim:    rgba(59, 158, 255, 0.18);
  --signal-amber:  #F59E0B;   /* hardware development active status */
  --signal-green:  #10B981;   /* verified / validated status */

  /* Typography Stacks */
  /* Saira is DIN-derived: the register of engineering drawings, machine plates
     and industrial signage, rather than "futuristic". Its wdth axis spans
     50-125, which covers every font-variation-settings value used below, so the
     existing typographic scale carries over unchanged.
     Public Sans is the US design-system face -- institutional and deliberately
     characterless, so prose reads as documentation instead of branding.
     Martian Mono replaces Space Mono, which is the most-used "technical"
     webfont in existence and is a large part of why this read as templated. */
  --font-display:  'Saira', 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body:     'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --font-mono:     'Martian Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Layout Constants */
  --wrap:          1240px;
  --gutter:        clamp(20px, 5vw, 64px);
  --section:       clamp(76px, 11vw, 152px);
}

*, *::before, *::after { box-sizing: border-box; }

/* ── Ambient field ─────────────────────────────────────────────────────────
   Site-wide electrical background. Created by JS and appended to body, so no
   markup changes across the pages.

   It sits at z-index 0 and every content region is lifted to 1, so nothing
   ever draws over text -- the layer shows through the gaps between panels,
   which is where the dark space actually is. Low opacity on top of already
   low per-strike alpha: the brand image is almost entirely black with a few
   thin bright marks, and this has to stay on the right side of that. */
.ambient-field {
  position: fixed;
  inset: 0;
  /* width/height are not redundant with inset:0. A canvas is a REPLACED
     element with an intrinsic 300x150, and for an absolutely positioned
     replaced element with auto width the used value resolves to that
     intrinsic size rather than stretching to the containing block. Without
     these the backing store measured 300x150 while CSS scaled it across the
     whole viewport, so every bolt was drawn into a small buffer and blown up. */
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  /* Raised from 0.55 by request: the strike is meant to be plainly visible
     when it fires, not a hint at one. This does not touch text legibility --
     the canvas sits at z-index 0 beneath every content region, so it only
     lightens the open dark space between panels. */
  opacity: 0.9;
}
body > header,
body > main,
body > footer { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  /* The canvas is never created under reduced motion; this is belt and braces
     in case one is ever added by other means. */
  .ambient-field { display: none; }
}

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--ground);
  color: var(--steel);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

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

/* ── Layout & Sections ─────────────────────────────────────────────────── */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* scroll-margin-top clears the fixed navbar. Without it, any programmatic
   scroll -- an in-page anchor, scrollIntoView, or the browser restoring
   position on reload -- parks a section's top edge flush with the viewport,
   which puts it underneath the 68px header and clips whatever sits first,
   usually the eyebrow. Set on .section rather than patched per page, because
   it affects every section on every page. */
.section { padding-block: var(--section); position: relative; scroll-margin-top: 96px; }
.section--head { padding-block-start: clamp(136px, 18vh, 196px); padding-block-end: clamp(52px, 8vw, 96px); }
.section--tight { padding-block: clamp(48px, 7vw, 92px); }
.section--surface { background: var(--surface); border-block: 1px solid var(--line-soft); }

/* Architectural Engineering Background (Refined Hairline Guide rather than AI Grid) */
.section--grid {
  position: relative;
}
.section--grid::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
  background-size: 120px 120px;
  background-position: center top;
  -webkit-mask-image: radial-gradient(ellipse 85% 60% at 50% 0%, #000 0%, transparent 80%);
  mask-image: radial-gradient(ellipse 85% 60% at 50% 0%, #000 0%, transparent 80%);
  opacity: 0.65;
}

.rule { height: 1px; background: var(--line-soft); border: 0; margin: 0; }

/* ── Precision Typography ──────────────────────────────────────────────── */

/* Engineering Section Header Label */
.label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin: 0 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.label::before {
  /* Was "SYS_REF //", stamped on every eyebrow on every page. An automatic
     designator that refers to nothing is costume, not information, and the
     uniformity is precisely what made the site read as machine-produced.
     Suppressed rather than deleted so the label's flex/gap styling stays intact. */
  content: none;
  color: var(--signal);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  opacity: 0.8;
}
.label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line-soft);
  max-width: 140px;
}
.label--signal { color: var(--signal); }
.label--plain::before { display: none; }

.display {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 116, 'wght' 300;
  font-weight: 300;
  font-size: clamp(2.2rem, 5vw, 4.1rem);
  line-height: 1.04;
  letter-spacing: -0.01em;
  text-wrap: balance;
  margin: 0 0 1.6rem;
  color: var(--steel-bright);
}

.display--wide {
  font-variation-settings: 'wdth' 124, 'wght' 260;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-size: clamp(1.6rem, 3.8vw, 2.9rem);
}

.h2 {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 112, 'wght' 420;
  font-weight: 420;
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  line-height: 1.18;
  text-wrap: balance;
  margin: 0 0 1.1rem;
  color: var(--steel-bright);
}

.h3 {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 108, 'wght' 500;
  font-size: 1.0625rem;
  margin: 0 0 0.5rem;
  color: var(--steel-bright);
}

.lede {
  font-size: clamp(1.02rem, 1.4vw, 1.18rem);
  line-height: 1.6;
  color: var(--steel);
  max-width: 62ch;
  margin: 0 0 1.5rem;
}

.prose { max-width: 70ch; }
.prose p { margin: 0 0 1.25rem; color: var(--steel-dim); line-height: 1.65; }
.prose p.lead-note { color: var(--steel); font-size: 1.05rem; }
.prose p:last-child { margin-bottom: 0; }
.muted { color: var(--steel-dim); }

/* ── Navigation ────────────────────────────────────────────────────────── */

.nav {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: 100;
  /* Was rgba(9,12,16,0.85) -- the old ground hardcoded as a literal. When the
     ground moved to #05070E this became a lighter bar floating above a darker
     page. Tied to the token so it can never drift from the ground again. */
  background: color-mix(in srgb, var(--ground) 85%, transparent);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid var(--line-soft);
  padding-block-start: env(safe-area-inset-top, 0px);
}

.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 68px;
}

.brand { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.brand img { width: 22px; height: auto; }
.brand-name {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 125, 'wght' 550;
  font-size: 0.875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--steel-bright);
}

.nav-links { display: flex; align-items: center; gap: clamp(0.9rem, 2vw, 1.85rem); }
.nav-links a {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--steel-deep);
  transition: color 0.18s ease;
  white-space: nowrap;
  position: relative;
  padding-block: 0.3rem;
}
.nav-links a:hover { color: var(--steel-bright); }
.nav-links a[aria-current="page"] {
  color: var(--steel-bright);
}
.nav-links a[aria-current="page"]::after {
  content: "";
  position: absolute;
  bottom: -4px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--signal);
}

.nav-toggle {
  display: none;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--steel);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  padding: 0.5rem 0.85rem;
  cursor: pointer;
}

@media (max-width: 900px) {
  .nav-toggle { display: block; }
  .nav-links {
    position: absolute;
    inset-block-start: 100%;
    inset-inline: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--ground);
    border-bottom: 1px solid var(--line);
    padding: 0.5rem var(--gutter) 1.25rem;
  }
  .nav-links a { width: 100%; padding: 0.85rem 0; border-bottom: 1px solid var(--line-soft); font-size: 0.8125rem; }
  .nav-links a[aria-current="page"]::after { display: none; }
  .nav-links[hidden] { display: none; }
}

/* ── Hero Section ──────────────────────────────────────────────────────── */

.hero {
  position: relative;
  overflow: hidden;
  border-bottom: 1px solid var(--line-soft);
  padding-block: clamp(124px, 18vh, 196px) clamp(72px, 10vh, 120px);
}

.hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: clamp(2.5rem, 5vw, 4.5rem);
}

.hero-content { position: relative; }

.hero-mark {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 125, 'wght' 240;
  font-weight: 240;
  font-size: clamp(2.1rem, 4.8vw, 3.8rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
  margin: 0 0 1.4rem;
  color: var(--steel-bright);
}

.hero-sub {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 105, 'wght' 380;
  font-size: clamp(1.1rem, 2.1vw, 1.55rem);
  line-height: 1.35;
  color: var(--steel-bright);
  max-width: 32ch;
  margin: 0 0 1.6rem;
  text-wrap: balance;
}

.hero-note { color: var(--steel-dim); max-width: 56ch; margin: 0; font-size: 1rem; line-height: 1.62; }

/* ── CAD & Telemetry Viewport (Reframing the Globe Video) ───────────────────
   Transforms the raw floating video into an authentic engineering viewport
   with corner crosshairs, calibration coordinates, and active telemetry readout. */
.cad-viewport {
  position: relative;
  border: 1px solid var(--line);
  background: var(--surface-card);
  padding: 1.25rem;
}

/* Precision Corner Calibration Brackets */
.cad-viewport::before,
.cad-viewport::after {
  content: "+";
  position: absolute;
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  color: var(--steel-deep);
  pointer-events: none;
  line-height: 1;
}
.cad-viewport::before { top: 6px; left: 8px; }
.cad-viewport::after  { bottom: 6px; right: 8px; }

.cad-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-bottom: 0.85rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line-soft);
}
.cad-header .cad-live {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--signal);
}
.cad-header .cad-live::before {
  content: "";
  width: 5px; height: 5px;
  background: var(--signal);
  box-shadow: 0 0 6px var(--signal);
  border-radius: 50%;
}

.cad-media {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background: radial-gradient(circle at center, var(--surface-2) 0%, var(--ground) 75%);
}

/* Crosshair marking the point the coordinate readout refers to. Thin enough to
   read as an instrument overlay rather than a graphic. */
.cad-reticle {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}
.cad-reticle::before,
.cad-reticle::after {
  content: "";
  position: absolute;
  background: var(--signal);
  opacity: 0.5;
}
.cad-reticle::before { left: 50%; top: 44%;  width: 1px; height: 12%; transform: translateX(-50%); }
.cad-reticle::after  { top: 50%;  left: 44%; height: 1px; width: 12%;  transform: translateY(-50%); }

/* The globe and its frame separate slightly under the pointer, so the panel
   reads as having depth. Driven in JS and disabled for reduced motion. */
/* Depth. Perspective sits on the frame so the panel tilts into the page
   rather than sliding around flat on it.
   transform-style: preserve-3d is deliberately NOT used -- .cad-media has
   overflow:hidden, and any overflow other than visible forces the used value
   back to flat, so it would be a lie in the stylesheet. The depth comes from
   perspective on the parent plus the globe drifting against the tilt, which
   needs no 3D context and behaves identically everywhere. */
.cad-viewport {
  perspective: 1100px;
  perspective-origin: 50% 50%;
}

.cad-media,
.cad-media video {
  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .cad-media,
  .cad-media video { transition: none; }
}

/* Readouts change continuously, so the columns must not resize as digits
   change or the whole panel twitches. */
.cad-footer div span[data-lat],
.cad-footer div span[data-lon],
.cad-footer div span[data-rot],
.cad-header [data-utc] {
  font-variant-numeric: tabular-nums;
}

.cad-media video {
  width: 100%;
  max-width: 440px;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 50%;
  -webkit-mask-image: radial-gradient(circle, #000 0 45%, rgba(0,0,0,0.85) 48%, transparent 50%);
  mask-image: radial-gradient(circle, #000 0 45%, rgba(0,0,0,0.85) 48%, transparent 50%);
}

.cad-footer {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  margin-top: 0.85rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--line-soft);
  font-family: var(--font-mono);
  font-size: 0.5625rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--steel-deep);
}
.cad-footer div span { display: block; color: var(--steel); font-size: 0.6875rem; margin-top: 0.15rem; }

@media (max-width: 900px) {
  .hero-grid { grid-template-columns: 1fr; gap: 2.5rem; }
  .cad-viewport { order: -1; max-width: 420px; margin-inline: auto; }
}

/* ── Telemetry & Status Badges ─────────────────────────────────────────── */

.status {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-dim);
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface-2) 50%, transparent);
  padding: 0.42rem 0.85rem;
  margin: 0 0 1.75rem;
}
.status::before {
  content: "";
  width: 5px; height: 5px;
  background: var(--signal-amber);
  box-shadow: 0 0 8px var(--signal-amber);
  flex-shrink: 0;
  border-radius: 50%;
  /* It claims a programme is active, so it should behave like an indicator
     rather than a printed dot. Slow and shallow -- a heartbeat, not a blink. */
  animation: status-pulse 2.4s ease-in-out infinite;
}
@keyframes status-pulse {
  0%, 100% { opacity: 1;    box-shadow: 0 0 8px var(--signal-amber); }
  50%      { opacity: 0.45; box-shadow: 0 0 3px var(--signal-amber); }
}
/* CSS animation is outside the JS reduced-motion guard, so it needs its own. */
@media (prefers-reduced-motion: reduce) {
  .status::before { animation: none; }
}
.status--green::before {
  background: var(--signal-green);
  box-shadow: 0 0 8px var(--signal-green);
}

/* ── Buttons & Calls to Action ─────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.85rem 1.45rem;
  border: 1px solid var(--line);
  color: var(--steel);
  background: color-mix(in srgb, var(--surface-card) 60%, transparent);
  cursor: pointer;
  transition: all 0.2s ease;
}
/* A control being actuated rather than a colour swapping. The fill wipes in
   from the left and the label rides above it; `transition: all` on .btn would
   otherwise try to animate the pseudo-element's geometry too, so the wipe owns
   its own transition. */
/* The label is a bare text node -- <a class="btn">Explore Platform Stack</a> --
   so there is no child element to lift above the fill. Raising ".btn > *"
   would match nothing and the wipe would paint straight over the text.
   Putting the fill at z-index:-1 works regardless of markup; `isolation`
   keeps it inside the button's own stacking context so it cannot slip
   behind the button's background or its neighbours. */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--surface-hover);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.btn:hover::after,
.btn:focus-visible::after { transform: scaleX(1); }

.btn:hover {
  border-color: var(--steel-dim);
  color: var(--steel-bright);
}

/* The primary button is already a solid fill, so a second wipe over it would
   only muddy it. */
.btn--primary::after { content: none; }

@media (prefers-reduced-motion: reduce) {
  .btn::after { transition: none; }
}
.btn--primary {
  background: var(--steel-bright);
  border-color: var(--steel-bright);
  color: var(--ground);
}
.btn--primary:hover {
  background: #FFFFFF;
  border-color: #FFFFFF;
  color: var(--ground);
  box-shadow: 0 0 16px rgba(242, 246, 250, 0.16);
}
.btn-row { display: flex; flex-wrap: wrap; gap: 0.85rem; }

/* ── Hardware Architecture Stack (Replaces Generic 5-Band AI Cell) ─────── */

.arch-stack {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid var(--line);
  background: var(--surface-card);
  margin-top: 2.5rem;
}

.arch-layer {
  display: grid;
  grid-template-columns: 140px minmax(200px, 260px) 1fr;
  gap: 1.5rem;
  padding: 1.75rem 2rem;
  border-bottom: 1px solid var(--line-soft);
  align-items: baseline;
  transition: background 0.18s ease;
}
.arch-layer:last-child { border-bottom: 0; }

/* The five subsystems converge -- they are not an ordered sequence, so they
   carry no "01-05" column and the grid is two.
   This was briefly scoped behind .arch-stack--unnumbered so platform.html
   could keep the numbered variant while index was tried out. Platform has
   since dropped its numbering too, .arch-layer-id is used nowhere, and a
   modifier that distinguishes nothing is just a trap for whoever reads it
   next -- so the two-column layout is simply what .arch-layer is now, and the
   modifier class has been taken out of the markup as well. */
.arch-layer { grid-template-columns: minmax(200px, 280px) 1fr; }
@media (max-width: 900px) {
  .arch-layer { grid-template-columns: 1fr; }
}
.arch-layer:hover { background: var(--surface-hover); }

/* ── Stack cross-section diagram ───────────────────────────────────────────
   Everything here is styled to its final, readable state. The scroll
   animation in JS only sequences the reveal; with JS blocked the diagram is
   simply already drawn. */
.stack-diagram {
  margin: 2.5rem 0 0;
  border: 1px solid var(--line-soft);
  background: var(--surface-card);
  padding: 1.5rem 1rem 1.25rem;
}
.stack-diagram svg { width: 100%; height: auto; display: block; }

/* The caption rule is scoped to .figure, and this figure is not one -- without
   this it renders at body size in body colour, the only unstyled thing on the
   page. Matched to the captions elsewhere rather than left to inherit. */
.stack-diagram figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.85rem;
}

.sd-band rect {
  fill: rgba(255, 255, 255, 0.022);
  stroke: var(--line);
  stroke-width: 1;
}
.sd-band text {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  fill: var(--steel);
}
.sd-band .sd-note {
  font-size: 9.5px;
  letter-spacing: 0.06em;
  fill: var(--steel-deep);
  text-anchor: end;
}
/* Active band: the one whose subsystem is currently in view below. */
.sd-band.is-active rect { fill: rgba(56, 214, 255, 0.05); stroke: var(--signal-dim); }
.sd-band.is-active text { fill: var(--steel-bright); }
.sd-band rect, .sd-band text { transition: fill 0.35s ease, stroke 0.35s ease; }

.sd-path {
  fill: none;
  stroke: var(--signal);
  stroke-width: 1.25;
  opacity: 0.85;
}
.sd-node { fill: var(--signal); }
.sd-axis {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  fill: var(--steel-deep);
}
.sd-shell {
  fill: none;
  stroke: var(--line-soft);
  stroke-width: 1;
  stroke-dasharray: 3 4;
}

/* SVG text scales with the viewBox, not with the viewport. At 390px the svg
   renders about 332px wide against a 720-unit viewBox -- a ratio near 0.46 --
   so 11px type lands at roughly 5px on screen. These sizes are in viewBox
   units and are deliberately large to come out legible after that scaling.

   Sizing the text up is not enough on its own, though, and the numbers hid it:
   the on-screen size measured fine while the picture showed the labels
   spilling out of their bands and the "zero-copy" caption clipped off the left
   edge of the viewBox. So the geometry moves too -- the bands start further
   left and the side label is dropped rather than half-shown. */
@media (max-width: 640px) {
  .stack-diagram { padding: 1rem 0.5rem; }
  .sd-band text { font-size: 21px; letter-spacing: 0.02em; }
  .sd-band .sd-note { display: none; }   /* no room for a second column */

  /* Reclaim the gutter the zero-copy label used.

     Done with a transform on the whole group, not with `x`/`width` as CSS
     geometry properties. Those applied to <rect> but silently not to <text>,
     which left the bands stretched left while the labels stayed put -- a large
     unexplained indent that measured as "fits" and looked broken. A transform
     moves every child by the same amount, so the group keeps its internal
     spacing whatever the element type. */
  .sd-bands { transform: translateX(-72px); }
  .sd-band rect { width: 600px; }
  .sd-shell { transform: translateX(-76px); }

  /* The path and its label need the gutter that no longer exists. The zero-copy
     relationship is stated in the caption and in the subsystem rows below, so
     dropping it here loses nothing and beats showing it clipped. */
  .sd-path, .sd-node, .sd-axis { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .sd-band rect, .sd-band text { transition: none; }
}

/* ── Signal-flow diagram ───────────────────────────────────────────────────
   Styled to its final readable state; the JS only sequences the draw. */
.sig-flow {
  margin: 2.5rem 0 0;
  border: 1px solid var(--line-soft);
  background: var(--surface-card);
  padding: 1.5rem 1rem 1.25rem;
}
.sig-flow svg { width: 100%; height: auto; display: block; }

/* The caption rule is scoped to .figure and this figure is not one, so
   without this the caption renders in the body face at body size. The
   stylesheet already records me making this mistake on the cross-section and
   then repeating it on the convergence diagram. Third time, stated up front. */
.sig-flow figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.85rem;
}

.sf-block rect {
  fill: rgba(255, 255, 255, 0.022);
  stroke: var(--line);
  stroke-width: 1;
}
.sf-block text {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  fill: var(--steel);
  text-anchor: middle;
}
.sf-block .sf-sub {
  font-size: 9.5px;
  letter-spacing: 0.05em;
  fill: var(--steel-deep);
}
/* The context engine is a control block, not a stage in the data path. */
.sf-block--aux rect { stroke: var(--line-soft); stroke-dasharray: 3 3; }

.sf-path {
  fill: none;
  stroke: var(--signal-deep);   /* structural stroke, never text */
  stroke-width: 1.25;
}
/* The leg the prose actually claims: straight into accelerator SRAM. */
.sf-path--direct { stroke: var(--signal); }
.sf-arrows path { fill: var(--signal-deep); }

.sf-busname {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  fill: var(--signal);
}
.sf-ctrl {
  fill: none;
  stroke: var(--steel-deep);
  stroke-width: 1;
  stroke-dasharray: 2 4;
}
.sf-thermal {
  fill: none;
  stroke: var(--signal-amber, #E0A42B);
  stroke-width: 1;
  stroke-dasharray: 5 3;
  opacity: 0.7;
}
.sf-axis {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  fill: var(--steel-deep);
}
.sf-shell {
  fill: none;
  stroke: var(--line-soft);
  stroke-width: 1;
  stroke-dasharray: 3 4;
}
.sf-shell-label {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.16em;
  fill: var(--steel-deep);
}

/* One drawing per aspect, swapped here. The landscape one is the default.

   This replaces roughly seventy lines that tried to contort the 720x300
   landscape SVG into a phone column: font inflation to 20px, box width and
   height overrides, five per-block transforms, and hiding every connector and
   the package outline. It is all gone, because it never worked and could not
   have. Recorded so it is not attempted again:

   - `translate` is RELATIVE. It composes with the x already on each <rect>,
     so a delta reasoned about as a destination sent FABRIC to x=840 in a
     720-unit viewBox, clean out of the picture.
   - `viewBox` is an SVG attribute and cannot be set from CSS, so the height
     could not grow to fit a fifth row. Rearranging inside a box that is too
     short only moves the clipping around.
   - With connectors hidden, what survived was five labels in boxes. The
     connectors are what make it a signal path rather than a list.

   Measurements said "no overlaps, even pitch" about a layout that was
   visibly incoherent, through five successive corrections. The picture is
   what settled it. */
/* Scoped as `.sig-flow svg.sf-…`, not a bare `.sf-…`, and that is load-bearing.
   `.sig-flow svg` above already sets `display: block` at specificity (0,1,1);
   a bare class is (0,1,0) and loses to it at EVERY width. Written that way
   first, the swap did nothing at all -- both drawings computed `display:
   block` on desktop and phone alike, and the phone kept showing the landscape
   one. Scoping wins on the cascade honestly; `!important` would have won the
   argument while leaving the same trap for the next rule added here. */
.sig-flow svg.sf-mobile { display: none; }

@media (max-width: 640px) {
  .sig-flow { padding: 1rem 0.5rem; }
  .sig-flow svg.sf-desktop { display: none; }
  /* The portrait viewBox renders near 1:1 at phone width, so the shared type
     sizes above land correctly with no inflation at all. */
  .sig-flow svg.sf-mobile { display: block; }
}
@media (prefers-reduced-motion: reduce) {
  .sf-block rect, .sf-block text { transition: none; }
}

/* ── Application sequence (numbered steps on a rail) ───────────────────────
   Markup rather than SVG, deliberately: the box-and-arrow diagram language is
   already used on four pages and a fifth would read as a template.

   The rail is static and full height. It is a ::before, which JS cannot
   target, and the obvious workaround -- animating a custom property the
   pseudo-element reads -- fails silently to an INVISIBLE rail if it does not
   parse, which is this session's recurring failure mode. The staggered steps
   already carry the downward motion. (An earlier version of this comment said
   "the JS only scales it in". It does not, and never did.) */
.steps {
  list-style: none;
  margin: 2.5rem 0 0;
  padding: 0;
  position: relative;
}

/* The rail. transform-origin at the top so the JS scaleY reads as drawing
   downward rather than growing from the middle. */
.steps::before {
  content: "";
  position: absolute;
  left: 15px;
  top: 6px;
  bottom: 6px;
  width: 1px;
  background: var(--line);
  transform-origin: 50% 0;
}

.step {
  position: relative;
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 0 1.25rem;
  padding-bottom: 2.25rem;
}
.step:last-child { padding-bottom: 0; }

/* The node sits ON the rail, so it needs the page ground behind it or the
   rail shows through the middle of the number. */
.step-num {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 31px;
  height: 31px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--signal);
}

.step-title {
  margin: 0 0 0.4rem;
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--steel-bright);
}
.step-body p {
  margin: 0;
  color: var(--steel-dim);
  font-size: 0.9375rem;
  line-height: 1.62;
  max-width: 60ch;
}
.step-body a { color: var(--steel-bright); text-decoration: underline; }

@media (max-width: 640px) {
  .steps::before { left: 13px; }
  .step { grid-template-columns: 44px 1fr; gap: 0 0.9rem; padding-bottom: 1.9rem; }
  .step-num { width: 27px; height: 27px; font-size: 0.625rem; }
  .step-title { font-size: 1rem; }
}

/* ── Disclosure gate sequence ──────────────────────────────────────────────
   Styled to its final readable state; the JS only sequences the draw. */
.gate-seq {
  margin: 2.5rem 0 0;
  border: 1px solid var(--line-soft);
  background: var(--surface-card);
  padding: 1.5rem 1rem 1.25rem;
}
.gate-seq svg { width: 100%; height: auto; display: block; }

/* `.figure figcaption` is scoped and this figure is not a .figure, so without
   this the caption renders in the body face at body size. Third diagram in a
   row where that applies; written up front rather than discovered again. */
.gate-seq figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.85rem;
}

.gs-stage rect {
  fill: rgba(255, 255, 255, 0.022);
  stroke: var(--line);
  stroke-width: 1;
}
.gs-num {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  fill: var(--signal);
}
.gs-name {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  fill: var(--steel-bright);
}
.gs-sub {
  font-family: var(--font-mono);
  font-size: 9.5px;
  letter-spacing: 0.04em;
  fill: var(--steel-deep);
}

.gs-line {
  fill: none;
  stroke: var(--signal-deep);   /* structural stroke, never text */
  stroke-width: 1.25;
}
.gs-arrows path { fill: var(--signal-deep); }

/* A gate is a condition, not a stage: hollow, so it reads as a checkpoint on
   the run rather than another box in the sequence. */
.gs-diamond {
  fill: var(--surface-card);
  stroke: var(--signal);
  stroke-width: 1.25;
}
.gs-gate-label {
  font-family: var(--font-mono);
  font-size: 8.5px;
  letter-spacing: 0.12em;
  fill: var(--steel-deep);
}
.gs-axis {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.1em;
  fill: var(--steel-deep);
}

/* Scoped `.gate-seq svg.gs-…`, not a bare class. `.gate-seq svg` above sets
   display:block at (0,1,1) and a bare `.gs-mobile` is (0,1,0), so it would
   lose at every width and both drawings would show -- the exact failure the
   signal-flow diagram hit. */
.gate-seq svg.gs-mobile { display: none; }

@media (max-width: 640px) {
  .gate-seq { padding: 1rem 0.5rem; }
  .gate-seq svg.gs-desktop { display: none; }
  .gate-seq svg.gs-mobile { display: block; }
}

/* ── Convergence diagram ───────────────────────────────────────────────────
   Styled to its final readable state; the JS only sequences the draw. */
.converge {
  margin: 2.5rem 0 0;
  border: 1px solid var(--line-soft);
  background: var(--surface-card);
  padding: 1.5rem 1rem 1.25rem;
}
.converge svg { width: 100%; height: auto; display: block; }

/* Same gap as the cross-section: the caption rule is scoped to .figure, and
   this figure is not one, so without this it renders in the body face at body
   size -- the only unstyled thing in the section. I made this exact mistake on
   the cross-section and still repeated it here. */
.converge figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.85rem;
}

.cv-paths path {
  fill: none;
  stroke: var(--signal-deep);   /* structural stroke, never text */
  stroke-width: 1.25;
}
.cv-nodes circle { fill: var(--signal); }
.cv-labels text {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: 0.12em;
  fill: var(--steel);
}
/* Energy travelling along a path.
   Taken from the brand image, where the filaments between the satellites and
   the globe are smooth flows along defined routes -- not lightning, which is
   jagged, forking and random. A bright short segment sweeping an existing
   path shows direction, so it says something (subsystem into core) rather
   than just glowing.
   The element is created in JS from the path it rides, so there is no second
   copy of the geometry to drift out of sync, and none of this exists at all
   when motion is reduced. */
.energy-pulse {
  fill: none;
  stroke: var(--signal-peak);
  stroke-width: 2.25;
  stroke-linecap: round;
  pointer-events: none;
  filter: drop-shadow(0 0 4px var(--signal));
}

.cv-ring { fill: none; stroke: var(--signal); stroke-width: 1; opacity: 0.55; }
.cv-dot  { fill: var(--signal-peak); }
.cv-core text {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  fill: var(--steel-deep);
}

/* SVG text scales with the viewBox, not the viewport, so phone sizes are set
   in viewBox units and are deliberately large. The labels are short precisely
   so they survive this. */
@media (max-width: 640px) {
  .converge { padding: 1rem 0.5rem; }
  .cv-labels text { font-size: 26px; letter-spacing: 0.04em; }
  /* The core label is hidden on phone rather than shrunk. Below the core is
     where the Thermal and Runtime curves both sweep, so at any size large
     enough to read it collides with one of them -- 22px and 18px were both
     measured as crossed. Nothing is lost: the caption immediately beneath
     already states "five subsystems developed as one architecture". Same call
     as the cross-section's zero-copy label, and better than showing it
     overlapped. */
  .cv-core text { display: none; }
  .cv-nodes circle { r: 7; }
  .cv-dot { r: 8; }
}
@media (prefers-reduced-motion: reduce) {
  .cv-dot { animation: none; }
}

/* Node points where each subsystem meets the spine -- the brand image's own
   vocabulary of glowing points at line intersections, applied to something
   structural that already exists. Deliberately NOT added to every hairline on
   the site: that would be decoration rather than meaning. */
.arch-layer::after {
  content: "";
  position: absolute;
  inset-inline-start: 1rem;
  inset-block-start: 50%;
  width: 5px;
  height: 5px;
  /* Half the dot's own width, so its centre lands on the spine rather than
     1.5px to the right of it. Measured, not guessed: the offset was identical
     on both viewports, which made it arithmetic rather than rounding. */
  margin-inline-start: -2.5px;
  margin-block-start: -2.5px;
  border-radius: 50%;
  background: var(--signal-deep);
  transition: background 0.35s ease, box-shadow 0.35s ease;
}
.arch-layer.is-active::after {
  background: var(--signal);
  box-shadow: 0 0 8px var(--signal-dim);
}
@media (max-width: 860px) {
  .arch-layer::after { inset-inline-start: 0.6rem; }
}
@media (prefers-reduced-motion: reduce) {
  .arch-layer::after { transition: none; }
}

/* A spine down the stack. The heading claims five CONVERGENT subsystems, and
   five identical detached rows contradicted that -- this is what makes them
   read as one architecture rather than a list. Sits inside the left padding,
   so it never collides with the text. */
.arch-stack { position: relative; }
.arch-stack::before {
  content: "";
  position: absolute;
  inset-block: 1.75rem;
  inset-inline-start: 1rem;
  width: 1px;
  background: linear-gradient(180deg, transparent, var(--line) 12%, var(--line) 88%, transparent);
  pointer-events: none;
}
@media (max-width: 860px) {
  .arch-stack::before { inset-inline-start: 0.6rem; }
}

/* Active state: emphasis, never revelation. Each layer is fully legible
   without it, so a blocked script costs nothing but the highlight. */
.arch-layer {
  position: relative;
  transition: background 0.18s ease, opacity 0.35s ease;
}
.arch-layer::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  inset-block: 1.25rem;
  width: 2px;
  background: var(--signal);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.arch-layer.is-active::before { transform: scaleY(1); }
.arch-layer.is-active .arch-layer-title { color: #FFFFFF; }
.arch-layer.is-active .metric-chip {
  border-color: var(--signal-dim);
  color: var(--steel-bright);
}
.metric-chip { transition: border-color 0.3s ease, color 0.3s ease; }

@media (prefers-reduced-motion: reduce) {
  .arch-layer, .arch-layer::before, .metric-chip { transition: none; }
}

/* .arch-layer-id removed: the "Layer/Subsystem 01-05" column is gone from both
   stacks, so nothing carries this class any more. */

.arch-layer-title {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 115, 'wght' 480;
  font-size: 1.0625rem;
  color: var(--steel-bright);
  margin: 0;
}

.arch-layer-desc {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--steel-dim);
  line-height: 1.6;
}

.arch-layer-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.65rem;
}

.metric-chip {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.08em;
  color: var(--steel);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line-soft);
  padding: 0.25rem 0.55rem;
}

@media (max-width: 860px) {
  .arch-layer {
    grid-template-columns: 1fr;
    gap: 0.65rem;
    padding: 1.4rem 1.25rem;
  }
}

/* ── Hardware Spec Matrix & Cards ──────────────────────────────────────── */

.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  margin-block: 2.5rem;
}

.metric-card {
  background: var(--surface);
  padding: 2rem 1.75rem;
}

.metric-val {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 120, 'wght' 350;
  font-size: 2rem;
  color: var(--steel-bright);
  margin: 0 0 0.4rem;
  line-height: 1.1;
}

.metric-label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin: 0 0 0.6rem;
}

.metric-sub {
  font-size: 0.875rem;
  color: var(--steel-dim);
  line-height: 1.55;
  margin: 0;
}

/* ── Figures & Schematics ──────────────────────────────────────────────── */

.figure { margin: 0; position: relative; }
.figure img { width: 100%; height: auto; border: 1px solid var(--line); }
.figure figcaption {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.figure figcaption::before {
  /* Was "FIG //" on every caption. These are product renders, not numbered
     figures in a technical paper; the prefix claimed a rigour that isn't there. */
  content: none;
  color: var(--signal);
  opacity: 0.8;
}
.figure--scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.figure--scroll img { min-width: 780px; }

/* ── Split Layouts ─────────────────────────────────────────────────────── */

.split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split--top { align-items: start; }

/* ── Engineering Specification Tables ──────────────────────────────────── */

.spec { margin: 0; }
.spec-row {
  display: grid;
  grid-template-columns: minmax(160px, 240px) 1fr;
  gap: 1rem 2rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--line-soft);
}
.spec-row:first-child { border-top: 1px solid var(--line-soft); }
.spec-key {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--steel-deep);
  padding-top: 0.2rem;
}
.spec-val { margin: 0; color: var(--steel); font-size: 0.9375rem; line-height: 1.6; }
.spec-val a { color: var(--steel); text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.spec-val a:hover { color: var(--steel-bright); text-decoration-color: var(--steel); }
.spec-val .sub { display: block; color: var(--steel-dim); font-size: 0.8125rem; margin-top: 0.25rem; }

@media (max-width: 640px) {
  .spec-row { grid-template-columns: 1fr; gap: 0.35rem; padding: 1rem 0; }
  .spec-row:first-child { border-top: 0; }
}

/* ── Discipline / Capability Entries ───────────────────────────────────── */

.entries { border-top: 1px solid var(--line-soft); }
.entry {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 1rem 2.5rem;
  padding: 1.95rem 0;
  border-bottom: 1px solid var(--line-soft);
  align-items: baseline;
}
.entry h3 {
  font-family: var(--font-display);
  font-variation-settings: 'wdth' 114, 'wght' 460;
  font-size: 1.15rem;
  margin: 0;
  color: var(--steel-bright);
}
.entry p { margin: 0; color: var(--steel-dim); font-size: 0.9375rem; line-height: 1.62; }
.entry .entry-meta {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin-top: 0.65rem;
}
@media (max-width: 760px) { .entry { grid-template-columns: 1fr; gap: 0.5rem; } }

/* ── Tags & Chips ──────────────────────────────────────────────────────── */

.tags { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 2rem; padding: 0; list-style: none; }
.tags li {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  color: var(--steel-dim);
  border: 1px solid var(--line);
  background: color-mix(in srgb, var(--surface-card) 40%, transparent);
  padding: 0.45rem 0.85rem;
}

/* ── Technical Disclaimers / Confidential Protocols ────────────────────── */

.confidential {
  border-inline-start: 2px solid var(--signal);
  background: color-mix(in srgb, var(--signal) 4%, transparent);
  padding: 1rem 1.25rem;
  color: var(--steel-dim);
  font-size: 0.9375rem;
  line-height: 1.62;
  max-width: 72ch;
  margin-block: 2rem;
}
.confidential strong { color: var(--steel-bright); font-weight: 500; }

/* ── Footer ────────────────────────────────────────────────────────────── */

.footer {
  border-top: 1px solid var(--line);
  padding-block: clamp(56px, 8vw, 96px) clamp(32px, 4vw, 48px);
  padding-block-end: calc(clamp(32px, 4vw, 48px) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
}
.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 2.5rem;
  margin-bottom: 3.5rem;
}
.footer h4 {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--steel-deep);
  margin: 0 0 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.footer h4::before {
  /* Was "DIR //" above every footer column. "Company" and "Corporate Office"
     are plain headings; dressing them as directory entries fooled nobody. */
  content: none;
  color: var(--signal);
  font-size: 0.5625rem;
  opacity: 0.8;
}
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { margin-bottom: 0.65rem; }
.footer li a { font-size: 0.875rem; color: var(--steel-dim); transition: color 0.18s ease; }
.footer li a:hover { color: var(--steel-bright); }
.footer-base {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 2rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.85rem;
  border-top: 1px solid var(--line-soft);
}
.footer-base p { margin: 0; font-size: 0.75rem; color: var(--steel-deep); font-family: var(--font-mono); letter-spacing: 0.04em; }

[hidden] { display: none !important; }
