/* Auria — Design System (DARK MODE)
 *
 * Component styles for showcase pages. Extends tokens.css.
 * Built during Phase 1, pivoted to dark on 2026-05-15.
 *
 * Visual direction: brand/visual-direction.md (favor volio.md, dark adaptation).
 * Tokens: sandbox/tokens.css (regenerate via punch-token-export).
 *
 * Dark-mode application of Volio idioms:
 *   - Page surface: brand-primary navy (#111A2E)
 *   - Elevated surface: brand-secondary navy (#1B2A4A) for CTA blade and slight separation
 *   - Single-cell emphasis: LIGHT cell (surface-1 white) on dark page — symmetric flip of Volio's dark-on-light
 *   - Hairline rules: rgba(255,255,255,0.10) — low-opacity white instead of #E5E5E5
 *   - Pill + sharp split, accent scarcity, vertical-rule stat strip, static logo cloud — unchanged
 *   - Centered text-only hero — unchanged, even more powerful on dark
 */

/* ---- Reset + base ---- */

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

html {
  scroll-behavior: smooth;
}

/* ---- Reveal-on-scroll polish ----
 * Sections + blades get a class .reveal at load. JS adds .is-revealed when the
 * element enters the viewport. Combined: a tasteful fade + slide-up that fires
 * once per element as you scroll in. Respects reduced motion. */
.reveal {
  opacity: 0;
  transform: translateY(48px);
  transition:
    opacity 900ms cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1);
  will-change: opacity, transform;
}
.reveal.is-revealed {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .reveal,
  .reveal.is-revealed {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
/* Don't reveal-fade things that have their own scroll-driven opacity / sticky
 * behavior — they'd fight each other. */
.transition,
.transition__inner,
.transition__intro,
.transition__headline,
.hero,
.hero--globe { opacity: 1 !important; transform: none !important; }

body {
  margin: 0;
  font-family: var(--type-family-body);
  font-size: var(--type-size-body);
  line-height: var(--type-lh-normal);
  color: var(--color-text-inverse);
  /* Brand-primary navy base + the project's Background Texture overlay
   * (a darker gradient on top of the page). Texture sits fixed so it doesn't
   * scroll-stretch with content. */
  /* The texture jpg is a near-solid navy of ~rgb(18,26,47) — lighter than the
   * site navy. Multiply-blend it against this computed color so the result lands
   * on #0E1626 (14,22,38) while the texture pattern is left completely intact. */
  background-color: rgb(198, 216, 206);
  background-image: url('assets/images/Background%20Texture.jpg');
  background-blend-mode: multiply;
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  background-attachment: fixed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: inherit; text-decoration: none; }

img, svg { display: block; max-width: 100%; }

::selection { background: var(--color-brand-accent); color: var(--color-brand-primary); }

/* ---- Universal H2 treatment ----
 * All section-level H2s are ALL CAPS in the display face. Negative tracking
 * relaxed slightly (-0.01em vs the headline default of -0.025em) so caps
 * don't read as cramped. h1 and h3+ stay normal case. */
h2 {
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

/* ---- HeliOS lockup ----
 * Per the client's naming note, HeliOS keeps its internal capitalisation even
 * where the surrounding text is set in caps — HELIOS destroys the "OS". Every
 * uppercasing context (the h1/h2/h4-h6 rules above, eyebrows, nav, footer,
 * card categories) inherits down, so the brand needs its own declaration to
 * opt out. Wrap the word, not the element: the label around it still uppercases.
 *   <span class="brand-helios">HeliOS</span> */
.brand-helios { text-transform: none; }

/* ---- Container ---- */

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 var(--space-4);
}

@media (min-width: 1024px) {
  .container { padding: 0 var(--space-6); }
}

/* ---- Hairline grid container frame (Volio structural idiom) ----
 * Page-spanning vertical hairlines at the container edges. They sit fixed
 * and stretch the full viewport height, framing every section as if the
 * content were inside a graph-paper container. Only visible at desktop
 * widths where the container is constrained (>= 1248px = 1200 + 2 * 24px
 * gutter), so on smaller viewports the lines hide and content goes
 * edge-to-edge gracefully. */

.grid-frame {
  /* Anchored to the document (absolute, not fixed) so the lines exist only
   * BELOW the hero and never overlap it. JS sets `top` to hero.bottom on load
   * and resize. `bottom: 0` anchors the line to the bottom of <body>. */
  position: absolute;
  top: 100vh;   /* fallback before JS measures */
  bottom: 0;
  width: 1px;
  background: rgba(255, 255, 255, 0.12);
  z-index: 1;
  pointer-events: none;
  display: none;
}
.grid-frame--left { left: 50%; transform: translateX(-600px); }
.grid-frame--right { left: 50%; transform: translateX(599px); }

@media (min-width: 1248px) {
  .grid-frame { display: block; }
}

/* ---- Type utilities ---- */

.display {
  font-family: var(--type-family-display);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: var(--type-lh-tight);
  color: var(--color-text-inverse);
}

.eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0;
}

.muted { color: var(--color-text-dim); }

/* ---- Pill + sharp split: buttons and eyebrow tags ---- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--type-family-button);
  font-size: var(--type-size-body-sm);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 14px 22px;
  border-radius: 2px;  /* small rigid radius, not pill */
  border: 1px solid transparent;
  cursor: pointer;
  transition:
    background-color var(--motion-duration-base) ease,
    color var(--motion-duration-base) ease,
    border-color var(--motion-duration-base) ease,
    transform var(--motion-duration-base) ease;
  white-space: nowrap;
}

.btn--primary {
  background: var(--color-brand-accent);
  color: var(--color-brand-primary);
}
.btn--primary:hover {
  background: var(--color-text-inverse);
  color: var(--color-brand-primary);
  transform: translateY(-1px);
  box-shadow: 0 0 0 1px rgba(245, 179, 30, 0.40);
}

.btn--ghost {
  background: transparent;
  color: var(--color-text-inverse);
  border-color: rgba(255, 255, 255, 0.30);
}
.btn--ghost:hover {
  border-color: var(--color-text-inverse);
  background: rgba(255, 255, 255, 0.05);
  transform: translateY(-1px);
}

/* On a light surface (e.g., inside the emphasis cell), flip ghost to dark text */
.btn--ghost-on-light {
  background: transparent;
  color: var(--color-brand-primary);
  border-color: rgba(17, 26, 46, 0.30);
}
.btn--ghost-on-light:hover {
  border-color: var(--color-brand-primary);
  background: rgba(17, 26, 46, 0.04);
}

.btn--small { padding: 10px 16px; font-size: 11px; }

.btn--link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--type-family-button);
  font-size: var(--type-size-body-sm);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
  padding: 0;
  border: none;
  background: transparent;
  border-bottom: 1px solid rgba(255, 255, 255, 0.30);
  border-radius: 0;
  padding-bottom: 4px;
  transition: border-color var(--motion-duration-base) ease, color var(--motion-duration-base) ease;
}
.btn--link:hover {
  color: var(--color-brand-accent);
  border-color: var(--color-brand-accent);
}

/* Used inside the emphasis cell (light surface) */
.btn--link-on-light {
  color: var(--color-brand-primary);
  border-bottom-color: rgba(17, 26, 46, 0.30);
}
.btn--link-on-light:hover {
  color: var(--color-brand-primary);
  border-color: var(--color-brand-primary);
}

.btn .arrow {
  display: inline-block;
  transform: translateX(0);
  transition: transform var(--motion-duration-base) ease;
}
.btn:hover .arrow { transform: translateX(3px); }

/* Eyebrow pill — accent-filled tag, the only place hot color appears */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-brand-primary);
  background: var(--color-brand-accent);
  padding: 6px 14px;
  border-radius: 999px; /* pill + sharp split */
}
.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--color-brand-primary);
}
.pill--ghost {
  color: var(--color-text-dim);
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.20);
}
.pill--ghost::before { background: var(--color-brand-accent); }

/* ---- Nav (full-width rigid containers, ON.energy reference) ----
 * The nav is a single horizontal bar that spans the full viewport width
 * edge-to-edge, divided into rigid sharp 0px container cells separated by
 * hairline borders (no pill rounding, no inter-cell gaps). Logo on the far
 * left, equal-width nav cells in the middle, accent CTA on the far right.
 * Dynamic hover: cell brightens, accent indicator dot appears. */

.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(14, 22, 38, 0.85);   /* hero navy */
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  transition: border-bottom-color var(--motion-duration-base) ease;
}
.nav.is-scrolled { border-bottom-color: rgba(255, 255, 255, 0.18); }

.nav__inner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: stretch;
  height: 64px;
}
/* The wrapping <nav> element in the middle slot needs to stretch its child
 * .nav__links to the full 64px height — otherwise the cell borders only
 * span the text height (~18px) and don't touch the top/bottom of the bar. */
.nav__inner > nav {
  display: flex;
  align-items: stretch;
}

/* Logo cell — sharp 0px rigid container on the left, hairline right border.
 * Holds the Auria Logo.svg (preserves brand colors). Text fallback if SVG fails. */
.nav__brand {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-7);
  border-right: 1px solid rgba(255, 255, 255, 0.10);
  font-family: var(--type-family-display);
  font-weight: 700;
  font-size: 18px;
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  border-radius: 0;
  background: transparent;
  transition: background-color var(--motion-duration-base) ease, color var(--motion-duration-base) ease;
}
.nav__brand:hover { background: rgba(255, 255, 255, 0.04); }
.nav__brand-logo {
  height: 24px;
  width: auto;
  display: block;
}

/* Middle nav items — equal-width sharp cells separated by hairlines */
.nav__links {
  display: none;
  list-style: none;
  margin: 0;
  padding: 0;
}
@media (min-width: 1024px) {
  .nav__links {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    align-items: stretch;
    width: 100%;
    height: 100%;
  }
}
.nav__links > li {
  display: flex;
  align-items: stretch;
  border-right: 1px solid rgba(255, 255, 255, 0.10);
  height: 100%;
}

.nav__links > li > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 100%;
  padding: 0 var(--space-5);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  background: transparent;
  border-radius: 0;
  position: relative;
  transition: background-color var(--motion-duration-base) ease, color var(--motion-duration-base) ease;
}
/* Hover: subtle bg tint + text brightens + small amber dot slides in from the
 * left as the cell's hover indicator. */
.nav__links > li > a:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--color-text-inverse);
}
.nav__links > li > a::before {
  content: "";
  width: 5px;
  height: 5px;
  background: var(--color-brand-accent);
  border-radius: 50%;
  opacity: 0;
  transform: translateX(-6px);
  margin-right: 0;
  transition: opacity 200ms ease, transform 200ms ease, margin-right 200ms ease;
}
.nav__links > li > a:hover::before,
.nav__links > li.hdr-nav-item.open > a::before {
  opacity: 1;
  transform: translateX(0);
  margin-right: 8px;
}
/* Active (mega open): keep tint + add an amber underline aligned to bottom of
 * the nav cell (mirrors the wireframe's underline-under-active-cell pattern). */
.nav__links > li.hdr-nav-item.open > a,
.nav__links > li.nav__item.open > a {
  background: rgba(255, 255, 255, 0.06);
  color: var(--color-text-inverse);
}
.nav__links > li > a::after {
  content: "";
  position: absolute;
  left: var(--space-5);
  right: var(--space-5);
  bottom: -1px;
  height: 2px;
  background: var(--color-brand-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 200ms cubic-bezier(0.22, 0.61, 0.36, 1);
}
.nav__links > li.hdr-nav-item.open > a::after,
.nav__links > li.nav__item.open > a::after { transform: scaleX(1); }

/* CTA cell — amber on the far right. Sharp 0px (matches rest of nav). */
.nav__cta {
  display: none;
  align-items: center;
  gap: 10px;
  padding: 0 var(--space-7);
  background: var(--color-brand-accent);
  color: var(--color-brand-primary);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  border-radius: 0;
  border-left: 1px solid rgba(255, 255, 255, 0.10);
  flex-shrink: 0;
  transition: background-color var(--motion-duration-base) ease;
}
.nav__cta:hover { background: var(--color-text-inverse); color: var(--color-brand-primary); }
.nav__cta .arrow { transition: transform var(--motion-duration-fast) ease; }
.nav__cta:hover .arrow { transform: translateX(4px); }
@media (min-width: 768px) { .nav__cta { display: inline-flex; } }

/* Right-cell group: holds CTA + burger so they share the 3rd grid column. */
.nav__end {
  display: inline-flex;
  align-items: stretch;
  border-left: 1px solid rgba(255, 255, 255, 0.10);
}
/* The CTA already has a left border in the design system; double border would
 * look heavy now that .nav__end provides the hairline, so suppress here. */
.nav__end .nav__cta { border-left: none; }

/* Burger — hidden ≥1024px (nav__links visible there); shown below as the mobile menu trigger. */
.nav__burger {
  display: none;
  width: 56px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  background: transparent;
  border: none;
  border-left: 1px solid rgba(255, 255, 255, 0.10);
  cursor: pointer;
  padding: 0;
}
.nav__burger span {
  width: 18px;
  height: 1.5px;
  background: var(--color-text-inverse);
  display: block;
  transition: transform 250ms ease;
}
@media (max-width: 1023px) {
  .nav__inner { grid-template-columns: auto 1fr auto; height: 56px; }
  .nav__brand { padding: 0 var(--space-5); font-size: 16px; }
  .nav__burger { display: inline-flex; }
}
@media (max-width: 767px) {
  .nav__end { border-left: none; }
}

/* ---- Section scaffolding (airier per ON.energy direction) ---- */

/* Halved 2026-08-04: was --space-12/--space-11 (160px/120px), which stacked to
   320px of dead space between two adjacent default sections on desktop. Now
   --space-10/--space-9 (80px/64px) -> 160px/128px. Still token-driven, so the
   existing responsive step-downs at the 1024/640 breakpoints still apply. */
.section {
  padding-top: var(--space-10);
  padding-bottom: var(--space-10);
}
.section--tight {
  padding-top: var(--space-9);
  padding-bottom: var(--space-9);
}
.section--air {
  padding-top: 200px;
  padding-bottom: 200px;
}
.section--rule-top { border-top: 1px solid rgba(255, 255, 255, 0.10); }
.section--rule-bottom { border-bottom: 1px solid rgba(255, 255, 255, 0.10); }

.section__header {
  max-width: 720px;
  margin: 0 auto var(--space-9);
  text-align: center;
}
.section__header .pill { margin-bottom: var(--space-5); }
.section__header h2 {
  font-family: var(--type-family-display);
  font-weight: 600;
  font-size: var(--type-size-h2);
  line-height: var(--type-lh-snug);
  letter-spacing: -0.02em;
  margin: 0 0 var(--space-4);
  color: var(--color-text-inverse);
}
.section__header p {
  font-size: var(--type-size-body-lg);
  color: var(--color-text-dim);
  margin: 0;
}

@media (min-width: 1024px) {
  .section__header h2 { font-size: var(--type-size-h2-lg); }
}

/* ---- Hero (centered text-only, no product mockup — Volio idiom) ----
 *
 * NOTE: The default `.hero` is the centered text-only treatment from the
 * Volio decode. The `.hero--globe` modifier overrides it for the globe-hero
 * variant adapted from the omma.build interactive-globe-hero generation.
 * See globe.js for the Three.js canvas that renders inside `.hero__globe`.
 */

.hero {
  padding-top: var(--space-12);
  padding-bottom: var(--space-12);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  text-align: center;
}

/* ---- Hero · Globe variant ---- */

.hero--globe {
  position: relative;
  padding: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  min-height: 92vh;
  overflow: hidden;
  /* Hero box itself stretches full-viewport so the gradient bg and globe canvas
   * cover edge-to-edge on any width. Content inside is capped to 1920 via the
   * @media rule below to keep text + CTAs from drifting on ultra-wide screens. */
  /* Full hero background ported from V2 (Orbital light-blue): two static accent
   * radials over a radial navy base with a lighter center (#16223a) that lifts
   * the whole hero — this brighter base is what makes V2's gradient read. */
  background:
    /* Bottom flatten: an opaque #0E1626 band anchored to the hero's bottom edge
     * (the seam/line above the Solutions section) so the gradient + bottom-right
     * glow are removed where the hero meets that line. Solid for the last ~34vh,
     * fading to transparent by ~66vh up, so the upper hero keeps its gradient. */
    linear-gradient(to top, #0E1626 0, #0E1626 34vh, rgba(14, 22, 38, 0) 66vh) bottom center / 100% 66vh no-repeat,
    radial-gradient(58% 44% at 22% 28%, rgba(47, 196, 219, 0.10), transparent 60%),
    radial-gradient(54% 46% at 82% 88%, rgba(43, 137, 166, 0.08), transparent 64%),
    radial-gradient(120% 60% at 50% 40%, #16223a 0%, #0E1626 55%, #0E1626 100%);
}

/* Pin wrapper. Default: fills the hero. Scroll mode (JS adds .is-scroll):
 * a sticky, viewport-tall stage the globe animation plays inside. */
.hero--globe .hero__pin {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.hero--globe.is-scroll {
  min-height: 200vh;
  overflow: visible;
}
.hero--globe.is-scroll .hero__pin {
  position: sticky;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100vh;
}

/* Static two-tone accent glow ported from V2's hero. Brighter than the base
 * radials (0.16 / 0.12) — this is what makes the gradient read. Shifted lower
 * in the hero. Sits behind the transparent globe canvas (z-index 0; hero
 * content is z-index 20) so it shows through. No drift/animation. */
.hero--globe .hero__pin::before {
  content: "";
  position: absolute;
  inset: -12%;
  z-index: 0;
  pointer-events: none;
  /* Upper accent glow only. The lower-right glow that used to carry down onto
   * the seam above the Solutions section has been removed entirely. */
  background:
    radial-gradient(44% 40% at 36% 40%, rgba(47, 196, 219, 0.16), transparent 66%);
}

/* V2's exact burst graphic — 168 dots + connecting quadratic lines + drift +
 * cursor-repel + gold accent dot, drawn on a 2D canvas. Fades in as the globe
 * fades out. Sized/masked exactly like V2's .burst. */
.hero__burst {
  position: absolute;
  z-index: 2;
  top: 50%;
  left: 50%;
  width: clamp(560px, 52vw, 780px);  /* dot-ring radius ≈ the globe's edge ring, so they overlap as ONE circle */
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
  transform-origin: center;
  display: block;
  pointer-events: none;
  opacity: 0;
  /* Gentle, full-height bottom fade — a continuous gradient with no flat section
   * or sharp inflection, so there's no visible light-to-dark seam. */
  -webkit-mask-image: linear-gradient(to bottom, #000 8%, rgba(0,0,0,0.35) 70%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 8%, rgba(0,0,0,0.35) 70%, transparent 96%);
}
/* Chips live on their own canvas with NO mask, so all four render (the lower
 * two are dimmed in JS instead of being clipped by the fade). */
.hero__burst--chips {
  -webkit-mask-image: none;
  mask-image: none;
}

/* Centered transition module — lead copy + CTAs, styled EXACTLY like V2's
 * .hero__body / .hero__lead. Rises into the middle of the burst on scroll. */
.hero__center {
  position: absolute;
  z-index: 25;
  top: 50%;
  left: 50%;
  width: min(620px, 86vw);
  transform: translate(-50%, calc(-50% + 10vh));
  text-align: center;
  opacity: 0;
  pointer-events: none;
}
/* Soft darkening behind the copy for legibility over the busy burst. Made very
 * large + gradual (fades to transparent by 100%) so its edge is imperceptible —
 * no visible ring/band — while still lifting the text off the graphic. */
.hero__center::before {
  content: "";
  position: absolute;
  inset: -90%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse 55% 48% at 50% 50%, rgba(6, 8, 14, 0.62), rgba(6, 8, 14, 0.30) 44%, rgba(6, 8, 14, 0) 100%);
}
.hero__center.is-visible { pointer-events: auto; }
.hero__center-lead {
  position: relative;
  font-family: "Hubot Sans", system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(20px, 2.6vw, 35px);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: #fff;
  margin: 0;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 2px 38px rgba(6, 8, 14, 0.92);
}
.hero--globe .hero__center .hero__center-ctas {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;   /* override .hero--globe .hero__ctas flex-start */
  margin-top: clamp(26px, 3.4vw, 40px);
}
@media (max-width: 900px) {
  .hero__center, .hero__burst { display: none; }
}

/* Three.js canvas container — fills the section */
.hero__globe {
  position: absolute;
  inset: 0;
  z-index: 1;  /* above the drifting accent glow (z-index 0), below content (20) */
  cursor: grab;
  touch-action: none;
}
.hero__globe.dragging { cursor: grabbing; }
.hero__globe canvas { display: block; }

/* Hero content layout — ON.energy-style asymmetric.
 * Headline-block (eyebrow + headline + CTAs) anchored to the MIDDLE-LEFT.
 * Body subhead drops further to the BOTTOM-LEFT (smaller bottom padding so
 * it sits low in the viewport). The empty middle-right area lets the globe
 * canvas breathe. H1 is all caps and constrained to ~30% of the viewport
 * on desktop. */
.hero--globe .hero__content {
  position: absolute;
  inset: 0;
  z-index: 20;
  padding: var(--space-11) var(--space-7) var(--space-7);
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.hero--globe .hero__content > * { pointer-events: auto; }

/* On ultra-wide viewports (>1920px) the hero box stretches edge-to-edge so the
 * globe canvas + gradient bg cover the full width. Cap the content overlay to
 * 1920 here so headline + CTAs stay anchored near the globe. With inset:0 +
 * max-width + margin:auto, an absolutely-positioned box centers automatically. */
@media (min-width: 1921px) {
  .hero--globe .hero__content {
    max-width: 1920px;
    margin-left: auto;
    margin-right: auto;
  }
  .hero--globe .hero__zoom {
    right: calc((100vw - 1920px) / 2 + var(--space-7));
  }
}

/* Middle-left positioning for the headline + CTA cluster */
.hero__headline-block {
  margin-top: auto;     /* push down from top */
  margin-bottom: auto;  /* push up from bottom — vertically centers */
  max-width: 56%;
  text-align: left;
}

/* Bottom-left body subhead — sits LOW in the viewport */
.hero--globe .hero__subhead {
  text-align: left;
  margin: 0;
  max-width: 44ch;
  align-self: flex-start;
}

/* Override the centered hero defaults inside .hero--globe.
 * H1 is ALL CAPS and constrained to ~30% of viewport width on desktop. */
.hero--globe .hero__pill { margin-bottom: var(--space-6); }
.hero--globe .hero__headline {
  text-align: left;
  margin: 0 0 var(--space-7);
  text-transform: uppercase;
  letter-spacing: -0.015em;
}
@media (min-width: 1024px) {
  .hero--globe .hero__headline {
    max-width: 52vw;
    min-width: 14ch;
    font-size: 56px;  /* cap so the wrap is manageable */
  }
}
@media (min-width: 1440px) {
  .hero--globe .hero__headline {
    max-width: 48vw;
    font-size: 64px;
  }
}
.hero--globe .hero__ctas {
  justify-content: flex-start;
}

@media (max-width: 768px) {
  .hero--globe .hero__content { padding: var(--space-9) var(--space-4); }
  .hero__headline-block { max-width: 100%; }
  .hero--globe .hero__subhead { max-width: 100%; }
  .hero--globe .hero__headline { max-width: 100%; }
}

/* HUD overlays — corner chrome adapted from omma's full-viewport layout
 * to be scoped INSIDE the hero section. */
.hero__hud {
  position: absolute;
  z-index: 15;
  pointer-events: none;
}
.hero__hud--tl { top: var(--space-7); left: var(--space-7); }
.hero__hud--tr { top: var(--space-7); right: var(--space-7); text-align: right; }
.hero__hud--bl { bottom: var(--space-7); left: var(--space-7); }
.hero__hud--br { bottom: var(--space-7); right: var(--space-7); text-align: right; }
.hero__hud--cb {
  bottom: var(--space-5);
  left: 50%;
  transform: translateX(-50%);
  text-align: center;
}

.hero__sys-id {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  line-height: 1.8;
  margin: 0;
}
.hero__sys-id span { color: rgba(255, 255, 255, 0.40); }

.hero__telem-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px var(--space-7);
}
.hero__telem-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 6px 0;
}
.hero__telem-lbl {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
}
.hero__telem-val {
  font-family: var(--type-family-eyebrow);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: var(--color-text-inverse);
  font-variant-numeric: tabular-nums;
}

.hero__status-row {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: flex-end;
  margin-bottom: 4px;
}
.hero__status-dot {
  width: 5px;
  height: 5px;
  background: var(--color-brand-accent);
  border-radius: 50%;
}
.hero__status-txt {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-dim);
}
.hero__status-ts {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.40);
  font-variant-numeric: tabular-nums;
}

.hero__nav-info {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  text-align: right;
  line-height: 1.8;
  margin: 0;
}

.hero__diagram-label {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  margin: 0;
}

/* Floating spec card — bottom-right of the hero, sits over the globe.
 * Adapted from the ON.energy decode (offset floating card pattern). Subsumes
 * the role of the standalone .hero__hud--br (status + UTC), promoting that
 * chrome into a more substantive operator-console card with a CTA.
 * Sharp 0px corners per Auria's pill + sharp split (NOT ON.energy's rounded). */
.hero__spec-card {
  position: absolute;
  bottom: var(--space-7);
  right: var(--space-7);
  z-index: 18;
  width: 340px;
  max-width: calc(100% - var(--space-7) * 2);
  background: rgba(27, 42, 74, 0.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.10);
  padding: var(--space-5) var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  pointer-events: auto;
  opacity: 0;
  animation: heroFadeIn 800ms ease forwards;
  animation-delay: 700ms;
}
.hero__spec-card__label {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}
.hero__spec-card__indicator {
  width: 5px;
  height: 5px;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  flex-shrink: 0;
}
.hero__spec-card__stat {
  font-family: var(--type-family-body);
  font-size: var(--type-size-body);
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text-inverse);
  margin: 0;
}
.hero__spec-card__cta {
  align-self: flex-start;
}
.hero__spec-card__divider {
  height: 1px;
  background: rgba(255, 255, 255, 0.10);
  margin: 0;
  border: none;
}
.hero__spec-card__meta {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-variant-numeric: tabular-nums;
}
.hero__spec-card__meta .hero__status-dot {
  flex-shrink: 0;
}

@media (max-width: 768px) {
  .hero__spec-card { display: none; }
}

/* ---- Hero zoom slider — interactive zoom control ----
 * Pinned to the bottom-right of the hero. Mission-styled label + tick marks.
 * Native <input type="range"> styled with a glowing amber handle and amber
 * fill on the left side of the track (showing "filled" zoom amount). */
.hero__zoom {
  position: absolute;
  z-index: 18;
  right: var(--space-7);
  bottom: var(--space-7);
  width: 360px;
  max-width: calc(100% - var(--space-7) * 2);
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-6);
  background: rgba(17, 26, 46, 0.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.08);
  opacity: 0;
  animation: heroFadeIn 800ms ease forwards;
  animation-delay: 700ms;
}
@media (max-width: 768px) { .hero__zoom { display: none; } }
@media (prefers-reduced-motion: reduce) { .hero__zoom { opacity: 1; animation: none; } }

.hero__zoom-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.hero__zoom-eyebrow { color: rgba(255,255,255,0.50); }
.hero__zoom-value { color: #568296; font-variant-numeric: tabular-nums; }

.hero__zoom-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 24px;
  background: transparent;
  cursor: grab;
  outline: none;
  margin: 0;
  /* Track via background-image (left side steel-teal, right side dim) — driven
   * by a CSS variable --fill that JS updates from the slider value */
  --fill: 40%;
}
.hero__zoom-slider:active { cursor: grabbing; }

/* WebKit track */
.hero__zoom-slider::-webkit-slider-runnable-track {
  height: 1px;
  background:
    linear-gradient(to right,
      #568296 0,
      #568296 var(--fill),
      rgba(255,255,255,0.20) var(--fill),
      rgba(255,255,255,0.20) 100%);
  border: none;
  border-radius: 0;
}
/* Firefox track */
.hero__zoom-slider::-moz-range-track {
  height: 1px;
  background:
    linear-gradient(to right,
      #568296 0,
      #568296 var(--fill),
      rgba(255,255,255,0.20) var(--fill),
      rgba(255,255,255,0.20) 100%);
  border: none;
}
/* WebKit thumb */
.hero__zoom-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -8.5px;
  border-radius: 50%;
  background: #568296;
  border: 1px solid rgba(86, 130, 150, 0.9);
  box-shadow: 0 0 0 6px rgba(86, 130, 150, 0.18);
  cursor: grab;
  transition: box-shadow 200ms ease, transform 200ms ease;
}
.hero__zoom-slider:hover::-webkit-slider-thumb,
.hero__zoom-slider:focus::-webkit-slider-thumb {
  box-shadow: 0 0 0 9px rgba(86, 130, 150, 0.22);
}
.hero__zoom-slider:active::-webkit-slider-thumb { cursor: grabbing; transform: scale(1.05); }
/* Firefox thumb */
.hero__zoom-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #568296;
  border: 1px solid rgba(86, 130, 150, 0.9);
  box-shadow: 0 0 0 6px rgba(86, 130, 150, 0.18);
  cursor: grab;
}
.hero__zoom-slider:hover::-moz-range-thumb,
.hero__zoom-slider:focus::-moz-range-thumb {
  box-shadow: 0 0 0 9px rgba(86, 130, 150, 0.22);
}

.hero__zoom-ticks {
  display: flex;
  justify-content: space-between;
  font-family: var(--type-family-eyebrow);
  font-size: 9px;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.40);
}

/* Globe tooltip — follows cursor when hovering over a city point */
.globe-tooltip {
  position: fixed;
  z-index: 200;
  padding: 6px 12px;
  background: rgba(17, 26, 46, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.12);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--color-text-inverse);
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
  white-space: nowrap;
}
.globe-tooltip.visible { opacity: 1; }

/* HUD entrance fade (skipped under reduced-motion via CSS at-rule) */
.hero__hud, .hero__globe { opacity: 0; animation: heroFadeIn 800ms ease forwards; }
.hero__hud--tl { animation-delay: 300ms; }
.hero__hud--tr { animation-delay: 400ms; }
.hero__hud--bl { animation-delay: 500ms; }
.hero__hud--br { animation-delay: 600ms; }
.hero__hud--cb { animation-delay: 700ms; }
.hero__globe { animation-delay: 100ms; }
@keyframes heroFadeIn { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .hero__hud, .hero__globe, .hero__spec-card { opacity: 1 !important; animation: none !important; }
  .globe-tooltip { transition: none !important; }
}

/* Responsive — drop the side HUD chrome on small screens (keep the centered content + bottom chrome only) */
@media (max-width: 768px) {
  .hero--globe { min-height: 88vh; }
  .hero__hud--tl { top: var(--space-4); left: var(--space-4); }
  .hero__hud--tr { display: none; }
  .hero__hud--bl { bottom: var(--space-4); left: var(--space-4); }
  .hero__hud--br { bottom: var(--space-4); right: var(--space-4); }
  .hero__telem-grid { gap: 2px var(--space-5); }
  .hero__telem-val { font-size: 12px; }
  .hero__sys-id, .hero__nav-info, .hero__telem-lbl, .hero__status-txt, .hero__status-ts, .hero__diagram-label { font-size: 9px; }
}
.hero__pill { margin-bottom: var(--space-7); }
.hero__headline {
  font-family: var(--type-family-display);
  font-weight: 600;
  font-size: var(--type-size-h1);
  line-height: var(--type-lh-tight);
  letter-spacing: -0.025em;
  color: var(--color-text-inverse);
  max-width: 14ch;
  margin: 0 auto var(--space-6);
}
.hero__subhead {
  font-size: var(--type-size-body-lg);
  line-height: var(--type-lh-normal);
  color: var(--color-text-dim);
  max-width: 56ch;
  margin: 0 auto var(--space-9);
}
.hero__ctas {
  display: flex;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
@media (min-width: 768px) {
  .hero__headline { font-size: var(--type-size-h1-lg); }
}
@media (min-width: 1024px) {
  .hero__headline { font-size: var(--type-size-display); }
}
@media (min-width: 1280px) {
  .hero__headline { font-size: var(--type-size-display-lg); }
}

/* ---- Intro statement ---- */

.intro {
  text-align: center;
  max-width: 880px;
  margin: 0 auto;
}
.intro__headline {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: var(--type-size-h2);
  line-height: var(--type-lh-snug);
  letter-spacing: -0.015em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
}
.intro__body {
  font-size: var(--type-size-body-lg);
  line-height: var(--type-lh-normal);
  color: var(--color-text-dim);
  max-width: 64ch;
  margin: 0 auto;
}
@media (min-width: 1024px) {
  .intro__headline { font-size: var(--type-size-h2-lg); }
}

/* ---- Asymmetric stacked blades (ON.energy primary direction) ----
 * Replaces the tight 3-up hairline grid for the mission section. Each blade is
 * a full-width section with a constrained-width content block offset to one
 * side. The empty side IS the design — generous whitespace carries the airiness.
 * Alternate left/right/left for the 3-blade rhythm. Sharp 0px structural per
 * the pill + sharp split. */

/* Hairline grid container around the entire mission blade stack (Volio grid
 * idiom). Top + bottom hairlines on the .blades container, internal horizontal
 * hairlines between blades, and a central vertical hairline running the full
 * height of each blade. ALL grid lines meet at intersections — the .blades
 * extends container-edge-to-edge via negative margins so the horizontal
 * hairlines reach the page-edge .grid-frame vertical lines. */
.blades {
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  /* Bleed out of container padding so blade horizontal dividers touch the
   * page-edge .grid-frame lines. Matches the smaller global container padding. */
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
}
@media (min-width: 1024px) {
  .blades {
    margin-left: calc(var(--space-6) * -1);
    margin-right: calc(var(--space-6) * -1);
  }
}
.blade {
  padding: 0;  /* desktop: no outer padding so visual fills cell to hairlines */
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  position: relative;
}
.blade:first-child { border-top: none; }
@media (max-width: 1023px) {
  /* Mobile: stacks single-column, needs vertical padding for breathing */
  .blade { padding: 80px 0; }
}
@media (min-width: 1024px) {
  /* Central vertical hairline — spans the FULL blade height (including
   * vertical padding) so it touches the horizontal divider above and below.
   * z-index above .blade__inner so the visual cell's navy bg (which starts
   * at 50% on blade--left) doesn't paint over the line. */
  .blade::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 1px;
    background: rgba(255, 255, 255, 0.12);
    pointer-events: none;
    z-index: 2;
  }
}

.blade__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-9);
  align-items: stretch;
  position: relative;
  padding: 0 var(--space-5);
}
@media (min-width: 1024px) {
  .blade__inner {
    grid-template-columns: 1fr 1fr;
    gap: 0;  /* zero gap so visual touches the central hairline */
    padding: 0;
  }
  /* Asymmetric L/R alternation per Volio blade architecture (PDF page 4 ref).
   * Default: content left, visual right.
   * --right modifier: visual left, content right (order swap on desktop only;
   * mobile always renders content first). */
  .blade--right .blade__content { order: 2; }
  .blade--right .blade__visual { order: 1; }
}

.blade__content {
  max-width: 680px;
  padding: 100px var(--space-6);
  align-self: center;
}
@media (min-width: 1024px) {
  .blade__content { padding: 140px var(--space-7); }
}
.blade--right .blade__content { margin-left: auto; }

/* Visual placeholder — fills its grid cell completely on all four sides.
 * NO own border, NO corner mark, NO inset — the surrounding grid lines
 * (central vertical, blade horizontal dividers, page-edge frame) provide
 * the framing. Cell extends to the horizontal hairlines top + bottom. */
.blade__visual {
  position: relative;
  /* Base background matches the site bg so the cell is invisible until the
   * scope-reveal animation grows the image in — a darker base (brand-secondary)
   * showed as a visible box before the reveal fired. */
  background: var(--color-brand-primary);
  display: block;  /* not flex — scope-reveal absolute-fills via inset: 0 */
  overflow: hidden;
  min-height: 360px;
  transition: background-color 300ms ease;
}
@media (min-width: 1024px) {
  .blade__visual { min-height: 0; align-self: stretch; }
}
.blade__visual:hover { background-color: rgba(35, 54, 95, 0.92); }
/* Small mono eyebrow label at top-left of the scope-reveal inner. The
 * gradient + grid pattern now carries the visual weight of the scale
 * animation — the label is just a discrete spec annotation. */
.blade__visual-label {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  text-align: left;
  padding: var(--space-4) var(--space-5);
  margin: 0;
  max-width: 28ch;
}

.blade__marker {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  margin: 0 0 var(--space-7);
  display: flex;
  align-items: center;
  gap: 14px;
}
.blade__marker-num {
  color: var(--color-text-inverse);
  font-weight: 500;
}
.blade__marker-rule {
  display: inline-block;
  width: 32px;
  height: 1px;
  background: rgba(255, 255, 255, 0.30);
}

.blade__title {
  font-family: var(--type-family-display);
  font-size: clamp(36px, 5vw, 64px);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-7);
  max-width: 22ch;
}

.blade__body {
  font-size: var(--type-size-body-lg);
  line-height: 1.6;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-8);
  max-width: 56ch;
}

.blade__cta { /* uses .btn--link */ }

/* ---- Feature row (DEPRECATED: hairline-rule modular grid + single-cell emphasis)
 * The .feature-grid pattern below is kept for any legacy compositions but is
 * no longer used by the homepage mission section. The new pattern is .blades
 * (asymmetric stacked blades) above. */

.feature-grid {
  display: grid;
  grid-template-columns: 1fr;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}
@media (min-width: 768px) {
  .feature-grid--3 { grid-template-columns: repeat(3, 1fr); }
  .feature-grid--4 { grid-template-columns: repeat(4, 1fr); }
}

.feature-cell {
  position: relative;
  padding: var(--space-9) var(--space-7);
  background: var(--color-brand-primary);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-height: 360px;
}
.feature-cell:first-child { border-top: none; }

@media (min-width: 768px) {
  .feature-cell {
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.10);
  }
  .feature-cell:first-child { border-left: none; }
}

.feature-cell__marker {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--color-text-dim);
  margin: 0;
}
.feature-cell__title {
  font-family: var(--type-family-display);
  font-size: var(--type-size-h3);
  font-weight: 600;
  line-height: var(--type-lh-snug);
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0;
}
.feature-cell__body {
  font-size: var(--type-size-body);
  line-height: var(--type-lh-normal);
  color: var(--color-text-dim);
  margin: 0;
  flex: 1;
}
.feature-cell__cta { margin-top: auto; }

/* Single-cell emphasis (Volio-style single-cell emphasis, dark-mode flip).
 * In light mode the emphasis cell was DARK on a light page.
 * In dark mode we flip the move: LIGHT cell on a dark page. Same direction (one
 * cell stands out via inversion), opposite tonal direction.
 *
 * NOTE: Class renamed from --inverted to --emphasis to reflect that the emphasis
 * cell now reads opposite to the page surface (light here, was dark before).
 */
.feature-cell--emphasis {
  background: var(--color-surface-1);
}
.feature-cell--emphasis .feature-cell__marker { color: var(--color-text-accent); }
.feature-cell--emphasis .feature-cell__title { color: var(--color-brand-primary); }
.feature-cell--emphasis .feature-cell__body { color: var(--color-text-muted); }

/* ---- Logo cloud — continuous marquee ----
 * Two duplicated sets of items inside a track that animates translateX(-50%)
 * for a seamless loop. Hover pauses. Edges fade out via CSS mask so logos
 * don't pop in/out at the viewport edges. Honors prefers-reduced-motion. */

.logo-cloud {
  display: flex;
  overflow: hidden;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  padding: 0;
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
  /* Soft fade edges so items don't visibly pop at the marquee boundary */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, black 6%, black 94%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, black 6%, black 94%, transparent 100%);
}
@media (min-width: 1024px) {
  .logo-cloud {
    margin-left: calc(var(--space-6) * -1);
    margin-right: calc(var(--space-6) * -1);
  }
}

.logo-cloud__track {
  display: flex;
  flex-shrink: 0;
  width: max-content;
  animation: marquee 36s linear infinite;
}
.logo-cloud:hover .logo-cloud__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .logo-cloud__track { animation: none; }
}

.logo-cloud__set {
  display: flex;
  flex-shrink: 0;
  align-items: center;
}

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

.logo-cloud__item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 88px;
  padding: 0 var(--space-9);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  text-align: center;
  white-space: nowrap;
  flex-shrink: 0;
  position: relative;
}
/* A small dot separator between items — gives even rhythm to the marquee */
.logo-cloud__item::after {
  content: "";
  position: absolute;
  right: calc(var(--space-9) * -0.05);
  top: 50%;
  width: 4px;
  height: 4px;
  background: rgba(255, 255, 255, 0.25);
  border-radius: 50%;
  transform: translateY(-50%);
}

/* Logo images in the marquee — same treatment as the Helios proof ticker:
   colored marks render as light monochrome on the navy. */
.logo-cloud__item--logo img {
  height: 44px; width: auto; object-fit: contain;
  filter: grayscale(1) invert(1);
  mix-blend-mode: screen;
  opacity: 0.85;
}
.logo-cloud__item--white img { filter: none; height: 28px; }
.logo-cloud__item--sm img { height: 20px; }

.logo-cloud__label {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  text-align: center;
  margin: 0 0 var(--space-7);
}

/* ---- Stat section — graphic above + stats below ----
 * Graphic is a flex item (NOT absolute) so it occupies the upper portion only,
 * not behind the stats. Cleaner separation. The .container wrapper for the
 * stats sits below as another flex item. */
.stat-section {
  position: relative;
  min-height: 95vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* transparent — shows the site body (#0E1626 + texture). */
}
/* flex items default to min-width:auto, which lets the stat grid's
   min-content width push the container past the viewport on phones —
   the section's overflow:hidden then clips the right column. */
.stat-section > .container { min-width: 0; width: 100%; }
/* Subtle accent glows as an overlay (so the section stays transparent). */
.stat-section::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(56% 46% at 20% 24%, rgba(47, 196, 219, 0.09), transparent 62%),
    radial-gradient(52% 48% at 26% 90%, rgba(47, 196, 219, 0.07), transparent 60%);
}
.stat-section .container { position: relative; z-index: 1; }
/* No-graphic variant: .stat-section reserves min-height:95vh so the three.js
   line-graphic can fill it via flex:1. Pages that do not load that script
   must not reserve the space, or the strip floats under a tall void. */
.stat-section--plain { min-height: 0; }
.stat-section--plain .stat-section__graphic { display: none; }

.stat-section__graphic {
  position: relative;
  flex: 1;
  /* The Three.js scene has orbital rings spanning x: -6 to +6 in world units.
   * The camera shows 2 * viewSize * aspect = 8 * (width/height) horizontally,
   * so when the container's aspect drops below ~1.5 the outer rings get
   * clipped on the right. Enforce a 2:1 minimum aspect so the rings always
   * fit at any viewport. */
  aspect-ratio: 2 / 1;
  min-height: 0;
  max-height: 58vh;
  z-index: 0;
  pointer-events: none;
  /* Soft-fade the bottom so the graphic never hard-cuts at its box edge. */
  -webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
}
.stat-section__graphic canvas { display: block; width: 100% !important; height: 100% !important; }
.stat-section .container {
  position: relative;
  z-index: 1;
}

/* ---- Stat section intro (eyebrow + headline + subtext above the stat strip) ---- *
 * Sits between the orbital line graphic above and the stat strip below.
 * Provides context for what the numbers represent. Left-aligned, text-anchored
 * to the container's left edge. */
.stat-section__intro {
  /* Headline-left / body-right, matching the Solutions section header above. */
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(28px, 5vw, 72px);
  align-items: end;
  margin: 0 0 var(--space-9);
}
.stat-section__intro-left { min-width: 0; }
.stat-section__intro .stat-section__headline { margin-bottom: 0; }
.stat-section__subtext { max-width: 46ch; }
@media (max-width: 767px) {
  .stat-section__intro { grid-template-columns: 1fr; gap: var(--space-5); align-items: start; }
}
.stat-section__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-eyebrow);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-4);
}
.stat-section__headline {
  font-family: var(--type-family-display);
  font-size: clamp(28px, 3.4vw, 44px);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
}
.stat-section__subtext {
  font-size: 16px;
  line-height: 1.55;
  color: var(--color-text-dim);
  margin: 0;
}

/* ---- Stat strip — top rule only, no bottom rule. Bleeds to page-edge frame.
 * 4 stats render as a single horizontal "tape" at desktop (4 equal columns)
 * so there's no awkward orphan cell; balanced 2x2 at smaller breakpoints. ---- */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
}
@media (min-width: 768px)  { .stat-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) {
  .stat-strip {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    margin-left: calc(var(--space-6) * -1);
    margin-right: calc(var(--space-6) * -1);
  }
}

/* Scoped to .stat-strip specifically — a flush grid of cells sharing
 * hairlines (no gaps), as opposed to .stats/.stats--text's independent
 * gapped cards (styles.css), which keep their own full border and must
 * not have it stripped by this component's border-top/left resets. */
.stat-strip .stat {
  padding: var(--space-9) var(--space-6) var(--space-7);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 320px;
  gap: var(--space-3);
}
/* Numbered marker + value sit at the TOP of each stat cell.
 * Label drops to the BOTTOM via margin-top: auto. Generous breathing
 * room between the value and label is part of the design. */
.stat__label {
  margin-top: auto;
}
.stat-strip .stat:first-child { border-top: none; }
/* Mobile cells run 320px against ~126px of content, leaving 154px of dead
   air under the label. Down 25% to 240px. */
@media (max-width: 767px) {
  .stat-strip .stat { min-height: 240px; }
}
@media (min-width: 768px) {
  .stat-strip .stat {
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.10);
  }
  .stat-strip .stat:first-child { border-left: none; }
}

.stat__num {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
  margin: 0;
}

.stat__value {
  display: block;
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: 64px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--color-brand-accent);
  margin: 0;
  /* tabular-nums prevents width jitter while the counter scrambles & ticks */
  font-variant-numeric: tabular-nums;
}
.stat__label {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-body-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0;
}
@media (min-width: 1024px) {
  /* Slightly smaller numerals at desktop now that 5 cells share the row */
  .stat__value { font-size: 64px; }
  .stat { padding: var(--space-9) var(--space-5) var(--space-7); min-height: 280px; }
}
@media (min-width: 1248px) {
  .stat__value { font-size: 72px; }
}
/* small screens LAST so it wins the cascade over the base sizes above */
@media (max-width: 767px) {
  .stat__value { font-size: clamp(32px, 10.5vw, 58px); }  /* scales with the 2-col cells so 1,000+ always fits */
  .stat { padding: var(--space-7) var(--space-4) var(--space-6); min-height: 0; }
}


/* ---- Compliance row (badge chips) ---- */

.compliance {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-7) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}
.compliance__label {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 var(--space-4) 0 0;
}
.compliance__badge {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
  border: 1px solid rgba(255, 255, 255, 0.20);
  padding: 8px 14px;
  border-radius: 0; /* sharp 0px structural corners */
}

/* ---- CTA blade (elevated brand-secondary surface for separation from page bg) ---- */

.cta-blade {
  background: var(--color-brand-primary);
  color: var(--color-text-inverse);
  padding: var(--space-11) 0;
  position: relative;
  z-index: 2;   /* sit above the fixed grid-frame hairlines (z:1) so they don't cross the cells */
  overflow: hidden;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}
/* Full-width variant: cta-grid breaks out of the .container and spans the
 * full viewport, with smaller edge padding (--space-6 instead of container
 * max-width). The internal hairlines still anchor at the page edges. */
.cta-blade--fullwidth { padding: 0; border: none; }
.cta-blade__bleed {
  width: 100%;
  padding: 0;
}
.cta-blade--fullwidth .cta-grid {
  border-left: none;
  border-right: none;
}
.cta-blade__pill { margin-bottom: var(--space-6); }

/* ---- CTA asymmetric hairline grid (Enerblock idiom) ---- *
 * 2×2 grid with 1px hairline borders between cells. Top-left = narrow body,
 * top-right = small meta/spec readout, bottom-left = pill + CTAs, bottom-right
 * = MASSIVE display headline that dominates the composition. */
.cta-grid {
  display: grid;
  grid-template-columns: 1fr;
  border: 1px solid rgba(255, 255, 255, 0.12);
}
@media (min-width: 768px) {
  .cta-grid {
    grid-template-columns: 5fr 7fr;
  }
}
.cta-grid__cell {
  padding: var(--space-8) var(--space-7);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  position: relative;
}
.cta-grid__cell:first-child { border-top: none; }
@media (min-width: 768px) {
  .cta-grid__cell--tl { border-top: none; }
  .cta-grid__cell--tr {
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.12);
  }
  .cta-grid__cell--bl { border-top: 1px solid rgba(255, 255, 255, 0.12); }
  .cta-grid__cell--br {
    border-left: 1px solid rgba(255, 255, 255, 0.12);
  }
}
.cta-grid__label {
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-5);
}
.cta-grid__body {
  font-size: var(--type-size-body-lg);
  line-height: 1.55;
  color: var(--color-text-dim);
  margin: 0;
  max-width: 38ch;
}
/* Meta cell: a tight 2-col readout that reads like a sensor spec block */
.cta-grid__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-6);
  row-gap: var(--space-3);
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.40);
}
.cta-grid__meta-val {
  color: var(--color-text-inverse);
  font-weight: 500;
}
.cta-grid__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-6);
}
/* The dominant headline — oversize display type that anchors the
 * bottom-right cell. Reads as the signature moment of the section. */
.cta-grid__headline {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: clamp(36px, 5.8vw, 88px);
  line-height: 0.98;
  letter-spacing: -0.025em;
  color: var(--color-text-inverse);
  margin: 0;
  max-width: 14ch;
}
@media (min-width: 1248px) {
  .cta-grid__cell { padding: var(--space-9) var(--space-8); }
  .cta-grid__cell--br { padding-top: var(--space-12); padding-bottom: var(--space-11); }
}

/* ---- Footer (footer-as-feature, ON.energy decode adaptation) ----
 * Elevated brand-secondary surface (matches the CTA blade above) with a faint
 * grid-pattern overlay to mark the footer as a designed moment. NO amber CTA
 * strip — the page already has a CTA blade above; adding an amber strip here
 * would push past the 2-accent-moment budget. The grid pattern is the move.
 * Sharp 0px corners per Auria's pill + sharp split (NOT ON.energy's rounded). */

/* Footer (Kosbiotic-style: brand-primary anchor with a dramatic oversize
 * brand wordmark at the bottom). Same surface as the page bg + CTA blade
 * so the page closes as one continuous dark plane. The wordmark itself
 * carries the visual weight at the bottom. */
.footer {
  background: linear-gradient(180deg, var(--color-brand-primary) 0%, #131d34 100%);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  padding: var(--space-11) 0 0;
  position: relative;
  overflow: hidden;
}
.footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-9);
  margin-bottom: var(--space-9);
}
/* 4-col layout — brand block (wider) + 3 link columns. The brand block on the
 * left gives the footer intentional weight and balances the dense Missions
 * column visually. */
@media (min-width: 768px) {
  .footer__grid {
    grid-template-columns: 1.6fr 1fr 1fr 1fr;
    gap: var(--space-10);
    align-items: start;
  }
}
.footer__brand-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 36ch;
}
.footer__brand-logo {
  height: 32px;
  width: auto;
  display: block;
  align-self: flex-start;
}
.footer__brand {
  font-family: var(--type-family-display);
  font-weight: 700;
  font-size: 28px;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0;
}
.footer__tagline {
  color: var(--color-text-dim);
  font-size: var(--type-size-body-sm);
  line-height: 1.55;
  margin: 0;
}
.footer__brand-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  text-decoration: none;
  padding-top: var(--space-2);
  transition: gap var(--motion-duration-fast) ease, color var(--motion-duration-fast) ease;
}
.footer__brand-cta:hover {
  gap: var(--space-4);
  color: var(--color-text-inverse);
}
.footer__brand-cta span {
  transition: transform var(--motion-duration-fast) ease;
}
.footer__brand-cta:hover span {
  transform: translateX(2px);
}
.footer__heading {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-4);
}
.footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer__list li { margin: 0 0 var(--space-3); }
.footer__list a {
  font-family: var(--type-family-body);
  font-size: var(--type-size-body-sm);
  color: var(--color-text-inverse);
  transition: color var(--motion-duration-fast) ease;
}
.footer__list a:hover { color: var(--color-brand-accent); }

.footer__bottom {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding-top: var(--space-7);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-dim);
}
@media (min-width: 768px) {
  .footer__bottom {
    flex-direction: row;
    align-items: center;
    gap: var(--space-7);
  }
  .footer__copy { flex: 0 0 auto; }
  .footer__legend {
    flex: 1 1 auto;
    text-align: center;
    color: rgba(255, 255, 255, 0.35);
  }
  .footer__bottom-links { margin-left: auto; }
}
.footer__bottom-links {
  display: flex;
  gap: var(--space-5);
  list-style: none;
  margin: 0;
  padding: 0;
}
.footer__bottom-links a:hover { color: var(--color-brand-accent); }

/* ---- Footer social profiles (bottom row, right side) ---- */
.footer__social {
  gap: var(--space-4);
  align-items: center;
}
.footer__social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-dim);
  transition: color var(--motion-duration-fast) ease;
}
.footer__social a:hover { color: var(--color-brand-accent); }
.footer__social-icon {
  display: block;
  width: 17px;
  height: 17px;
  fill: currentColor;
}

/* ---- Pain item icons (Thin Icon 1/2/3.svg above each pain title) ---- */
.pain__item-icon {
  display: block;
  width: 56px;
  height: 56px;
  margin: 0 0 var(--space-6);
  filter: brightness(0) invert(1);
  opacity: 0.85;
}

/* ---- Dramatic scroll-driven opacity on the transition section ----
 * Both intro and headline fade in based on scroll progress. The intro pins
 * brighter early; the headline takes over as the section centers in viewport.
 * Driven by a CSS variable `--scroll-progress` set by JS (0 at section enter,
 * 1 at section exit). The fallback initial value lives on the section itself
 * so JS's per-element override flows cleanly through the cascade — declaring
 * --scroll-progress on the children would override the inherited live value
 * and freeze the animation at the fallback. */
.transition {
  --scroll-progress: 0;
}
.transition__intro,
.transition__headline {
  will-change: opacity, transform;
}
/* Math note: with 200vh section height, scroll-progress = 0.333 when section
 * top hits viewport top (sticky pin starts), and 0.666 when sticky pin ends.
 * Map opacity into that pin range:
 *   intro fades in from 0.30 to 0.42 of scroll
 *   headline fades in from 0.42 to 0.55, then both stay through 0.66 */
.transition__intro {
  opacity: clamp(0, calc((var(--scroll-progress) - 0.30) * 8), 1);
  transform: translateY(calc((1 - clamp(0, (var(--scroll-progress) - 0.30) * 6, 1)) * 40px));
}
/* Headline stays at 100% opacity. Each word turns from white to amber
 * sequentially as scroll progresses through the pin range — a typewriter
 * color sweep. JS splits the headline into .word spans, each with a
 * --word-index custom property. Each word's color-progress threshold is
 * staggered so they animate one after another. */
.transition__headline {
  opacity: 1;
  transform: none;
}
.transition__headline .word {
  display: inline-block;
  /* total-words is set on the parent headline by JS after split.
   * Sweep spans scroll-progress 0.35 → 0.70 (wider window, very visible).
   * Each word gets a ~0.06 progress slice; multiplier 14 makes each word's
   * own ramp snap from white → amber over ~7% of total scroll. */
  --word-stagger: calc(var(--word-index, 0) / var(--total-words, 8));
  --word-start: calc(0.35 + var(--word-stagger) * 0.35);
  --word-progress: clamp(0, calc((var(--scroll-progress) - var(--word-start)) * 14), 1);
  color: color-mix(
    in srgb,
    var(--color-text-inverse),
    var(--color-brand-accent) calc(var(--word-progress) * 100%)
  );
  transition: color 80ms linear;
}
@supports not (color: color-mix(in srgb, white, black 50%)) {
  .transition__headline .word { color: var(--color-text-inverse); }
}
@media (prefers-reduced-motion: reduce) {
  .transition__headline .word { color: var(--color-text-inverse); }
}
@media (prefers-reduced-motion: reduce) {
  .transition__intro,
  .transition__headline {
    opacity: 1 !important;
    transform: none !important;
  }
}

/* ============================================================================
 * NEW SECTIONS — added per the full PDF homepage brief.
 * Hero tabs (Volio reference, page 1), Pain Point, Differentiator,
 * Domain Expertise, Product Families (tabbed, Volio reference page 9).
 * ============================================================================ */

/* ---- Hero tabs (Volio-reference tab interface) ----
 * Sits in its own section directly below the hero. 4 tabs across the top,
 * one panel below shows the active tab's content. Pill tab buttons (per
 * Auria's pill + sharp split — interactive elements 999px). Active tab
 * gets a faint amber treatment to distinguish without burning the full
 * accent budget. Tab switching is JS-toggled (see init script in index.html). */

.tabs {
  padding: var(--space-12) 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* Rigid hairline grid bar — sharp 0px cells separated by hairlines, no pill
 * rounding, no inter-cell gaps. Outer top + bottom hairlines bound the bar.
 * Negative horizontal margins bleed the bar out of the container padding so
 * the top + bottom rules reach end-to-end (touching the page-edge frame). */
.tabs__bar {
  display: grid;
  grid-template-columns: 1fr;
  margin-bottom: var(--space-12);
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}
@media (min-width: 768px) {
  .tabs__bar { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 1024px) {
  .tabs__bar {
    margin-left: calc(var(--space-6) * -1);
    margin-right: calc(var(--space-6) * -1);
  }
}

.tabs__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 0 var(--space-5);
  height: 64px;
  background: transparent;
  border: none;
  border-right: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 0;
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  cursor: pointer;
  transition:
    background-color var(--motion-duration-base) ease,
    color var(--motion-duration-base) ease;
}
.tabs__btn:last-child { border-right: none; }
@media (max-width: 767px) {
  .tabs__btn {
    border-right: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  }
  .tabs__btn:last-child { border-bottom: none; }
}
.tabs__btn:hover {
  color: var(--color-text-inverse);
  background: rgba(255, 255, 255, 0.04);
}
.tabs__btn[aria-selected="true"] {
  background: rgba(245, 179, 30, 0.08);
  color: var(--color-text-inverse);
}
/* Reserve dot space in ALL tab states — opacity toggles, layout doesn't shift
 * when a tab becomes active. Fixes the content jitter on click. */
.tabs__btn::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--color-brand-accent);
  border-radius: 50%;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--motion-duration-base) ease;
}
.tabs__btn[aria-selected="true"]::before {
  opacity: 1;
}

.tabs__panels {
  position: relative;
  min-height: 240px;
}
.tabs__panel {
  display: none;
  max-width: 880px;
  margin: 0 auto;
  text-align: center;
}
.tabs__panel.is-active { display: block; }

.tabs__panel__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-5);
}
.tabs__panel__headline {
  font-family: var(--type-family-display);
  font-size: clamp(28px, 4vw, 48px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
}
.tabs__panel__subhead {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-body-sm);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-6);
}
.tabs__panel__body {
  font-size: var(--type-size-body-lg);
  line-height: 1.6;
  color: var(--color-text-dim);
  max-width: 60ch;
  margin: 0 auto;
}

/* ---- Transition (dramatic full-screen moment between pain + missions) ----
 * Combines the pain transition statement and the missions section headline into
 * one cinematic full-viewport beat. Top-anchored intro paragraph; bottom-anchored
 * oversize headline. Darker radial gradient overlay reinforces the drama. */

/* Pinned-scroll dramatic moment. Section is 200vh tall to give scroll runway;
 * the inner content uses position: sticky to PIN to the top of the viewport
 * for the duration of the section. As scroll progresses, --scroll-progress
 * (set by JS, 0 at section enter, 1 at section exit) drives the text opacity
 * fades. The pin happens in the middle third of scroll (~0.33 to 0.66). */
.transition {
  min-height: 200vh;
  position: relative;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  /* No glow on this section. */
  background: transparent;
}
.transition__inner {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;   /* center the whole block vertically */
  width: 100%;
  padding: var(--space-12) 0;
  gap: var(--space-12);
}
.transition__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-5);
  text-align: center;
}
.transition__intro {
  font-family: var(--type-family-display);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: -0.005em;
  color: var(--color-text-inverse);
  max-width: 60ch;
  margin: 0 auto;               /* center the paragraph block */
  padding-bottom: var(--space-7);
  text-align: center;
}
.transition__headline {
  font-family: var(--type-family-display);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
  max-width: 18ch;
  margin: 0 auto var(--space-6);   /* centered block, gap before the paragraph */
  padding-top: var(--space-4);     /* small gap under the eyebrow */
  text-align: center;
}
/* Match the hero H1 size (still an <h2> for SEO). Beats the unified-H2 rule
 * via higher specificity. */
.transition .transition__headline { font-size: 56px; }
@media (min-width: 1440px) { .transition .transition__headline { font-size: 64px; } }
@media (max-width: 1023px)  { .transition .transition__headline { font-size: clamp(36px, 6vw, 52px); } }

/* No 200vh pinned runway — the section is a compact, natural-height block with
 * modest padding on all screens. The word-colour sweep still animates via
 * --scroll-progress (computed from the section's position, not the pin), and the
 * copy stays visible (opacity:1 above). */
.transition { min-height: 0; }
.transition__inner {
  position: static;
  height: auto;
  min-height: 0;
  padding: var(--space-9) 0;
  gap: var(--space-7);
}

/* ---- Pain Point section (3-up + transition statement) ---- */

.pain {
  padding: max(32px, calc(var(--space-12) - 75px)) 0 max(48px, calc(var(--space-12) - 50px));   /* top 85 / bottom 110 on desktop; floored on phones where --space-12 shrinks below the offsets */
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
/* Subtle cyan glow in the lower-right, matching the accent glow on prior sections. */
.pain::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(52% 48% at 84% 66%, rgba(47, 196, 219, 0.08), transparent 62%);
}
.pain .container { position: relative; z-index: 1; }
.pain__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-5);
  text-align: center;
}
.pain__headline {
  font-family: var(--type-family-display);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  max-width: none;   /* explicit <br> controls the two-line break */
  margin: 0 auto max(32px, calc(var(--space-12) - 75px));   /* 85 on desktop; floored on phones (--space-12:64px would go negative and pull the grid over the text) */
  text-align: center;
}
.pain__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-9);
  list-style: none;
  padding: 0;
  margin: 0;  /* section padding-bottom already provides trailing space */
}
@media (min-width: 1024px) {
  .pain__list { grid-template-columns: repeat(3, 1fr); gap: var(--space-11); }
  /* Four-up variant — same list, one more column. Used where the section has
     four steps rather than a multiple of three. */
  .pain__list--four { grid-template-columns: repeat(4, 1fr); gap: var(--space-9); }
}
.pain__item {
  border-top: 1px solid rgba(255, 255, 255, 0.20);
  padding-top: var(--space-6);
}
.pain__item-title {
  font-family: var(--type-family-display);
  font-size: var(--type-size-h3);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-4);
}
.pain__item-body {
  font-size: var(--type-size-body);
  line-height: 1.6;
  color: var(--color-text-dim);
  margin: 0;
}
.pain__transition {
  font-family: var(--type-family-display);
  font-size: clamp(20px, 2.4vw, 28px);
  font-weight: 400;
  line-height: 1.4;
  color: var(--color-text-inverse);
  max-width: 60ch;
  margin: 0;
  padding-top: var(--space-9);
  border-top: 1px solid rgba(255, 255, 255, 0.20);
}

/* ---- Differentiator — STACKED NUMBERED ROWS (Enerblock idiom) ----
 * Three rows numbered 01/02/03, each row sticky-pinned during scroll so the
 * next row scrolls UP over the previous one. Creates a stacking-card effect
 * without horizontal layout. Hairline rules between rows + at the top.
 * Each row: [marker] [icon visual] [headline + body + meta-grid]. */

.diff {
  padding: var(--space-12) 0 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.diff__headline {
  font-family: var(--type-family-display);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  max-width: 18ch;
  margin: 0 auto var(--space-12);
  text-align: center;
}

/* ---- Family stacked rows (Enerblock idiom, moved here from differentiator) ----
 * Four rows numbered 01/02/03/04 for the four product families. Each row
 * sticky-pins at the top of viewport; ascending z-index lets the next row
 * scroll up OVER the pinned previous, creating a card-stack effect.
 * Falls back to relative position on prefers-reduced-motion. */
.fam-stack { position: relative; }

.fam-row {
  position: relative;
  background: var(--color-brand-primary);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  z-index: 1;
}
.fam-row:last-child { border-bottom: none; }
.fam-row[data-fam-row="02"] { z-index: 2; }
.fam-row[data-fam-row="03"] { z-index: 3; }
.fam-row[data-fam-row="04"] { z-index: 4; }

@media (min-width: 1024px) {
  .fam-row { position: sticky; top: 64px; }
}

.fam-row__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
  padding: var(--space-11) var(--space-7);
  align-items: start;
}
@media (min-width: 1024px) {
  /* Two cols at desktop: large unframed logo on the left, headline + body
   * + meta on the right. The logo IS the visual identity — no frame, no
   * containing box, no oversized number. */
  .fam-row__inner {
    grid-template-columns: 5fr 6fr;
    gap: var(--space-10);
    padding: calc(var(--space-12) - 100px) var(--space-7);   /* 100px less top & bottom (160 → 60) */
    align-items: center;
  }
}

/* Small numbered eyebrow above the logo — keeps the row index visible
 * without the oversized number column. */
.fam-row__marker {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
.fam-row__num {
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  color: var(--color-brand-accent);
}
.fam-row__num::before {
  content: '— ';
  color: rgba(255, 255, 255, 0.35);
}

/* LARGE unframed product logo — the visual identity of each row. No box,
 * no border, no background tint. The logo takes up the full visual column
 * width up to ~520px. */
.fam-row__visual {
  display: block;
  width: 100%;
  max-width: 520px;
}
.fam-row__logo {
  display: block;
  width: 100%;
  height: auto;
  max-height: 120px;
  object-fit: contain;
  object-position: left center;
}
@media (min-width: 1024px) {
  .fam-row__logo { max-height: 160px; }
  /* Each logo PNG has its own baked-in transparent left padding; offset it so
   * the logo's visible content left-aligns with the number above (×0.4 render
   * scale at the desktop 160px logo height). */
  .fam-row[data-fam-row="01"] .fam-row__logo { margin-left: -39px; }
  .fam-row[data-fam-row="02"] .fam-row__logo { margin-left: -38px; }
  .fam-row[data-fam-row="03"] .fam-row__logo { margin-left: -46px; }
  .fam-row[data-fam-row="04"] .fam-row__logo { margin-left: -47px; }
}

.fam-row__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.fam-row__title {
  font-family: var(--type-family-display);
  font-size: var(--type-size-h4);   /* H4 (22px) */
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0;
  max-width: none;   /* let the headline sit on one line */
}
.fam-row__cta { color: #2FC4DB; border-bottom-color: rgba(47, 196, 219, 0.45); padding-bottom: 8px; }
.fam-row__cta:hover { color: #2FC4DB; border-bottom-color: #2FC4DB; }
.fam-row__body {
  font-size: var(--type-size-body-lg);
  line-height: 1.55;
  color: var(--color-text-dim);
  margin: -16px 0 0;   /* tighter headline↔body gap (flex gap 24 → ~8px) */
  max-width: 56ch;
}
.fam-row__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-6);
  row-gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: 0;
  border-top: none;
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.fam-row__meta > span:nth-child(odd) { color: rgba(255, 255, 255, 0.40); }
.fam-row__meta > span:nth-child(even) { color: var(--color-text-inverse); font-weight: 500; }

@media (prefers-reduced-motion: reduce) {
  .fam-row { position: relative; top: auto; }
}
/* 3 columns inside a hairline grid container — outer top + bottom hairlines,
 * vertical hairlines between columns. Each column has an icon above the title.
 * Extends to page-edge frame via negative margins (matches .blades / .tabs__bar). */
.diff__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
}
@media (min-width: 1024px) {
  .diff__cols {
    grid-template-columns: repeat(3, 1fr);
    margin-left: calc(var(--space-6) * -1);
    margin-right: calc(var(--space-6) * -1);
  }
}
.diff__col {
  padding: var(--space-9) var(--space-7);
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.diff__col:first-child { border-top: none; }
@media (min-width: 1024px) {
  .diff__col {
    border-top: none;
    border-left: 1px solid rgba(255, 255, 255, 0.10);
  }
  .diff__col:first-child { border-left: none; }
}
.diff__col-icon {
  display: block;
  width: 48px;
  height: 48px;
  margin: 0 0 var(--space-7);
  filter: brightness(0) invert(1);
  opacity: 0.85;
}
.diff__col-title {
  font-family: var(--type-family-display);
  font-size: var(--type-size-h3);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
}
.diff__col-body {
  font-size: var(--type-size-body);
  line-height: 1.6;
  color: var(--color-text-dim);
  margin: 0;
}

/* ---- Solutions (psuite) — ported from V2, converted to DARK MODE ----
 * Pinned section: header lifts/fades as the cards rise and lock, then the card
 * track scrolls horizontally (driven by the psuite JS). */
.psuite {
  position: relative;
  z-index: 2;                          /* opaque #0E1626 covers the .grid-frame lines (z:1) here */
  color: #fff;
  --pad-x: clamp(20px, 4vw, 64px);
  background: #0E1626;                  /* solid site navy — removes the texture on THIS section only */
}
/* Hero-style blueprint grid behind the pinned content, fading toward the
 * bottom (end) of the section. Sits below the header (z6) and cards (z2). */
.psuite__pin::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Matches the hero's WebGL background grid: cell ≈ 2.75% of viewport height
   * (the hero grid is projected from a plane and scales with viewport height,
   * so a vh-relative cell keeps the two grids in lock-step at any window size). */
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
  background-size: 2.75vh 2.75vh;
  -webkit-mask-image: linear-gradient(to bottom, #000 32%, transparent 88%);
  mask-image: linear-gradient(to bottom, #000 32%, transparent 88%);
}
.psuite__pin { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.psuite__head {
  position: absolute; top: 0; left: 0; right: 0; z-index: 6;
  padding: clamp(72px, 9vh, 116px) var(--pad-x) 0;   /* tighter above */
  will-change: transform, opacity;
}
/* Two columns: headline on the left, supporting text on the right. */
.psuite__head-in {
  max-width: 1320px; margin: 0 auto; width: 100%; position: relative; z-index: 1;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(28px, 5vw, 72px);
  align-items: end;
}
@media (max-width: 900px) {
  .psuite__head-in { grid-template-columns: 1fr; gap: 18px; }
}
.psuite__eyebrow {
  font-family: var(--type-family-eyebrow); font-size: 12px; font-weight: 700;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--color-brand-accent);
  display: inline-flex; align-items: center; gap: 13px; margin: 0 0 22px;
}
.psuite__eyebrow::before {
  content: ""; width: 12px; height: 12px; border-radius: 50%;
  border: 1.5px solid var(--color-brand-accent); background: radial-gradient(circle, var(--color-brand-accent) 0 2.1px, transparent 2.7px);
}
.psuite__title {
  font-family: var(--type-family-display); font-weight: 300;
  font-size: clamp(28px, 4vw, 52px); line-height: 1.04; letter-spacing: 0;  /* loosened from -0.025em */
  color: #fff; max-width: 20ch;
}
.psuite__sub {
  font-family: var(--type-family-body); font-size: 16px;
  line-height: 1.55; color: rgba(255, 255, 255, 0.66); max-width: 46ch;
  margin: 0;
}
.psuite__viewport { position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; overflow: hidden; will-change: transform; }
.ptrack {
  display: flex; align-items: center; gap: clamp(20px, 2.4vw, 40px);
  padding: 0 var(--pad-x);
  /* Left edge aligns with the centered 1320px headline column. */
  padding-left: max(var(--pad-x), calc((100% - 1320px) / 2));
  will-change: transform;
}
.pcard {
  position: relative; flex: 0 0 auto;
  width: clamp(560px, 58vw, 780px); height: clamp(360px, 54vh, 460px);
  /* height clamp is fine for desktop's typical (short, wide) aspect ratio, but
   * tablet-portrait viewports are much taller relative to width — the 460px
   * ceiling then leaves a lot of dead space above/below the pinned card row.
   * Raised via a dedicated tall-viewport override below, not by touching the
   * base rule (desktop must stay pixel-identical). */
  background: #16223a;                 /* card: lighter navy for depth */
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
  overflow: hidden;
  /* Image left, text right. Graphic spans the full-height left column; the
   * category + copy stack in the right column. */
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas: "gfx cat" "gfx foot";
  transition: border-color .25s, box-shadow .25s;
}
.pcard:hover { border-color: rgba(47, 196, 219, 0.45); box-shadow: 0 20px 44px -28px rgba(0, 0, 0, 0.65); }
.pcard__cat {
  grid-area: cat;
  padding: clamp(26px, 3vw, 36px) clamp(26px, 2.2vw, 34px) 0;   /* top-right cell */
  font-family: var(--type-family-eyebrow); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: #2FC4DB; line-height: 1.4;
}
.pcard__gfx { grid-area: gfx; position: relative; min-height: 0; margin: 0; overflow: hidden; background: #0a1120; }
.cardburst {
  position: absolute; inset: 0; width: 100%; height: 100%;
  -webkit-mask-image: radial-gradient(120% 118% at 50% 50%, #000 40%, transparent 90%);
  mask-image: radial-gradient(120% 118% at 50% 50%, #000 40%, transparent 90%);
}
/* Unscoped so they style the <use>-cloned SVG content (a descendant selector
 * doesn't reliably cross the use shadow boundary). Class names are unused
 * elsewhere in this site. */
.ln  { fill: none; stroke: rgba(176, 198, 224, 0.42); stroke-width: 0.8; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.ln2 { fill: none; stroke: rgba(176, 198, 224, 0.22); stroke-width: 0.8; vector-effect: non-scaling-stroke; }
.dsh { fill: none; stroke: rgba(176, 198, 224, 0.18); stroke-width: 0.8; stroke-dasharray: 3 5; vector-effect: non-scaling-stroke; }
.acc { fill: none; stroke: #2FC4DB; stroke-width: 1; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.dotg { fill: #2FC4DB; }
.ctag {
  position: absolute; z-index: 2; font-family: var(--type-family-eyebrow);
  font-size: 9px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: #cfe0ee; background: rgba(12, 20, 36, 0.86); padding: 3px 7px;
  white-space: nowrap; opacity: 0; pointer-events: none; animation: ctagcycle 12s ease-in-out infinite;
}
@keyframes ctagcycle {
  0%, 3% { opacity: 0; transform: translateY(4px); }
  7%, 15% { opacity: .92; transform: none; }
  20%, 100% { opacity: 0; transform: translateY(-4px); }
}
.pcard__foot {
  grid-area: foot;
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(12px, 1.6vh, 20px) clamp(26px, 2.2vw, 34px) clamp(26px, 2.4vw, 34px);
}
.pcard__name {
  font-family: var(--type-family-display); font-weight: 400;
  font-size: clamp(19px, 1.7vw, 24px); line-height: 1.14; letter-spacing: -0.015em;
  color: #fff; max-width: 22ch;
}
.pcard__desc { font-size: 13px; line-height: 1.5; color: rgba(255, 255, 255, 0.60); margin-top: 11px; max-width: 40ch; }
.pcard__cta {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  margin-top: 20px; padding: 13px 16px; background: #F5B31E; color: #0E1626;
  font-family: var(--type-family-eyebrow); font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.3; transition: background .2s ease;
}
.pcard__cta .l { min-width: 0; }
.pcard__cta .ar { flex: 0 0 auto; font-size: 13px; }
.pcard__cta:hover { background: #FFD147; }
@media (prefers-reduced-motion: reduce) { .ctag { animation: none; opacity: 0; } }
/* prev/next controls for the native-scroll card track (small screens only) */
.psuite__nav { display: none; gap: 12px; justify-content: center; padding: 22px var(--pad-x) 0; }
.psuite__arrow {
  width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid rgba(255, 255, 255, 0.30); border-radius: 0;
  color: #fff; font-size: 18px; line-height: 1; cursor: pointer;
  transition: border-color .2s ease, background .2s ease, opacity .2s ease;
}
.psuite__arrow:hover { border-color: rgba(47, 196, 219, 0.7); background: rgba(47, 196, 219, 0.08); }
.psuite__arrow[disabled] { opacity: 0.3; cursor: default; pointer-events: none; }
/* Tablet-portrait: .psuite__pin is a full 100svh sticky viewport, but at
 * tall/narrow aspect ratios the 460px card-height ceiling leaves a large
 * dead gap above and below the pinned card row. Let cards grow taller here
 * so the row actually fills the pinned viewport. JS reads the card's
 * rendered height at runtime (measure()), so no script changes are needed —
 * it adapts automatically. Scoped by width (still in the pinned-scroll JS
 * range, i.e. > the 880px mobile cutoff) AND height (only kicks in once the
 * viewport is tall enough to actually cause the gap). */
@media (min-width: 881px) and (max-width: 1200px) and (min-height: 850px) {
  .pcard { height: clamp(360px, 62vh, 640px); }
}
@media (max-width: 880px) {
  .psuite { height: auto !important; }
  .psuite__pin { position: static; height: auto; overflow: visible; padding-bottom: 80px; }
  .psuite__head { position: static; padding: clamp(88px, 11vh, 130px) var(--pad-x) 0; transform: none !important; opacity: 1 !important; }
  .psuite__title br { display: none; }  /* let small screens wrap naturally */
  .psuite__viewport { position: static; display: block; overflow-x: auto; margin-top: 34px; transform: none !important; -webkit-overflow-scrolling: touch; scroll-snap-type: x mandatory; }
  /* where prev/next arrows are present the native bar is a duplicate control — hide it */
  .psuite:has(.psuite__nav) .psuite__viewport { scrollbar-width: none; -ms-overflow-style: none; }
  .psuite:has(.psuite__nav) .psuite__viewport::-webkit-scrollbar { display: none; }
  /* stretch, not center: copy of uneven length would otherwise give every card
     a different height and stagger the row. */
  .ptrack { transform: none !important; padding-bottom: 14px; align-items: stretch; }
  /* Cards align with the headline column above instead of sitting on a
     centring buffer — same --pad-x the head uses. Snap moves from centre to
     start so the snapped position IS that alignment, and scroll-padding on
     the scroller carries the inset. */
  .psuite__viewport { scroll-padding-left: var(--pad-x); }
  .ptrack { padding-left: var(--pad-x); }
  /* Trailing side stays a flex-item spacer rather than padding-right:
     Chromium excludes a scroll container's trailing child padding from
     scrollWidth, so padding would silently clip the last card's scroll room.
     Sized so the last card still reaches the start position:
     viewport - inset - card - gap. */
  .ptrack::after { content: ""; display: block; flex: 0 0 max(0px, calc(22vw - var(--pad-x) - clamp(20px, 2.4vw, 40px) + 1px)); }
  .pcard { height: auto; min-height: 0; width: 78vw; transform: none !important; scroll-snap-align: start; }
  /* stack the card vertically: graphic on top, category + copy below.
     The foot takes 1fr so the shorter cards absorb the slack instead of
     leaving it under the card. */
  .pcard {
    grid-template-columns: 1fr;
    grid-template-rows: 220px auto 1fr;
    grid-template-areas: "gfx" "cat" "foot";
  }
  .pcard__gfx { border-bottom: 1px solid rgba(255, 255, 255, 0.10); }
  .psuite__nav { display: flex; }
}

/* ---- Domain Expertise (asymmetric: headline left, capability list right) ---- */

.expertise {
  padding: var(--space-12) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.expertise__inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-9);
}
@media (min-width: 1024px) {
  .expertise__inner {
    grid-template-columns: 5fr 6fr;
    gap: var(--space-11);
    align-items: start;
  }
}
.expertise__headline {
  font-family: var(--type-family-display);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  max-width: 14ch;
  margin: 0;
}
.expertise__list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.expertise__item {
  padding: var(--space-6) 0;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  font-family: var(--type-family-body);
  font-size: var(--type-size-body-lg);
  line-height: 1.5;
  color: var(--color-text-inverse);
  display: flex;
  gap: var(--space-5);
  align-items: baseline;
}
.expertise__item:first-child { border-top: none; padding-top: 0; }
.expertise__item-num {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.40);
  flex-shrink: 0;
  min-width: 32px;
}

/* ---- Product Families (tabbed — Volio reference page 9) ----
 * Vertical tab list on the left, panel on the right. Active tab gets the same
 * faint-amber treatment as the hero tabs. Stacks to top-tab + below-panel
 * on mobile. */

.families {
  padding: calc(var(--space-12) - 50px) 0;   /* 50px less above the header; matching space below the last card before the prefooter */
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.families .fam-row {
  /* Each sticky family card needs an opaque bg so when they stack on top of
   * each other while scrolling, the previous card doesn't show through.
   * Body texture is preserved by leaving the .families section transparent. */
  background: var(--color-brand-primary);
}
.families__header {
  margin-bottom: calc(var(--space-12) - 50px);   /* 50px less below the header (160 → 110) */
  max-width: 720px;
}
.families__headline {
  font-family: var(--type-family-display);
  font-size: clamp(32px, 4vw, 56px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
}
.families__intro {
  font-size: var(--type-size-body-lg);
  color: var(--color-text-dim);
  line-height: 1.6;
  margin: 0;
}

.families__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
}
@media (min-width: 1024px) {
  .families__layout {
    grid-template-columns: 5fr 7fr;
    gap: 0;                 /* tabs + panel sit flush — unified bordered block */
    align-items: stretch;
    min-height: 70vh;
  }
}

/* Rigid hairline grid stack — sharp 0px cells separated by horizontal hairlines,
 * outer top + bottom hairlines bound the stack. Negative horizontal margins
 * bleed the stack out of the container padding so the rules reach end-to-end
 * on the page edge. No pills. */
.families__tabs {
  display: flex;
  flex-direction: column;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  margin-left: calc(var(--space-4) * -1);
  margin-right: calc(var(--space-4) * -1);
}
@media (min-width: 1024px) {
  .families__tabs {
    margin-left: calc(var(--space-6) * -1);
    margin-right: 0;
    height: 100%;  /* fill the families__layout column height */
  }
  /* Each tab takes an equal share of the column height */
  .families__tab { flex: 1; }
}
.families__tab {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-6) var(--space-7);
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 0;
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  cursor: pointer;
  transition: color var(--motion-duration-base) ease, background-color var(--motion-duration-base) ease;
  text-align: left;
  position: relative;
  min-height: 128px;
}
.families__tab:last-child { border-bottom: none; }
/* Per-tab horizontal hairline naturally terminates at the tab cell's right edge,
 * which is the panel column's left edge — no ::after extension needed. The lines
 * touch the panel without crossing it. */
.families__tab:hover {
  color: var(--color-text-inverse);
  background: rgba(255, 255, 255, 0.04);
}
.families__tab[aria-selected="true"] {
  background: rgba(245, 179, 30, 0.08);
  color: var(--color-text-inverse);
}
/* Reserve dot space in ALL tab states — opacity toggles, layout doesn't shift
 * when a tab becomes active. Fixes the content jitter on active. */
.families__tab::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  background: var(--color-brand-accent);
  border-radius: 50%;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity var(--motion-duration-base) ease;
}
.families__tab[aria-selected="true"]::before {
  opacity: 1;
}
.families__tab-num {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.40);
}

/* Product logo inside each family tab — original colors (amber + white preserved),
 * much larger size per user direction, no warping (object-fit: contain + auto width). */
.families__tab-logo {
  height: 64px;
  width: auto;
  max-width: 280px;
  object-fit: contain;
  object-position: left center;
  opacity: 0.7;
  transition: opacity var(--motion-duration-base) ease;
  display: block;
  flex-shrink: 0;
}
.families__tab:hover .families__tab-logo,
.families__tab[aria-selected="true"] .families__tab-logo {
  opacity: 1;
}

/* Larger product logo inside each panel — sits above the panel title.
 * Keeps original colors (amber + white preserved). */
.families__panel__logo {
  height: 80px;
  width: auto;
  max-width: 360px;
  object-fit: contain;
  object-position: left center;
  margin-bottom: var(--space-7);
  display: block;
}

.families__panels {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  /* Extend the panel to the right page-edge frame on desktop so the right
   * side reaches the right margin hairline. Negative margin matches the
   * .container padding. */
}
@media (min-width: 1024px) {
  .families__panels {
    margin-right: calc(var(--space-6) * -1);
  }
}

.families__panel {
  display: none;
  /* Tabs column already has top + bottom hairlines (.families__tabs borders).
   * Panel uses ONLY a left border to separate from tabs; top + bottom are
   * implied by the tabs' borders since columns share the same row height
   * via align-items: stretch. */
  border: none;
  border-left: 1px solid rgba(255, 255, 255, 0.18);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
  background: var(--color-brand-secondary);
  padding: var(--space-9);
  min-height: 320px;
  flex-direction: column;
  justify-content: center;
}
.families__panel.is-active {
  display: flex;
  flex: 1;
}

.families__panel__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-5);
}
.families__panel__title {
  font-family: var(--type-family-display);
  font-size: var(--type-size-h2);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-5);
  max-width: 22ch;
}
.families__panel__body {
  font-size: var(--type-size-body-lg);
  line-height: 1.6;
  color: var(--color-text-dim);
  margin: 0;
  max-width: 60ch;
}

/* ========================================================================
 * SECTION-TRANSITION ANIMATIONS
 * Six high-end scroll-driven moments layered on top of the existing reveals:
 *   1. Stat counter roll-up (JS-driven; no CSS needed)
 *   2. Hairline self-draw on section dividers
 *   3. Mission blade reveal choreography
 *   4. Pin + horizontal scroll for product families
 *   5. Cross-section background wash
 *   6. Footer wordmark draw-in
 * Every animation gates on prefers-reduced-motion in JS or via media query.
 * ====================================================================== */

/* ---- 2. Section-rule self-draw ---- *
 * A 1px hairline that scales from 0 → 1 horizontally on enter viewport.
 * Anchored top-of-section; drops the existing static border-top in favor
 * of an animated child element with class .section-rule.
 * (border-top stays as a fallback when JS doesn't run.) */
.section-rule {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: rgba(255, 255, 255, 0.10);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
  z-index: 2;
}
.section-rule.is-drawn { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .section-rule { transform: scaleX(1); transition: none; }
}

/* ---- 3. Mission blade reveal choreography ---- *
 * REMOVED the outer .blade__visual clip-path wipe — it was conflicting with
 * the inner scope-reveal (the outer wipe-up was masking the scope animation
 * entirely, so all the user saw was the upward wipe). The scope-reveal
 * inside the blade__visual now handles all visual reveal motion.
 *
 * Central vertical hairline still draws downward as the blade enters. */
.blade::before {
  transform-origin: top center;
  transform: scaleY(0);
  transition: transform 1100ms cubic-bezier(0.65, 0, 0.35, 1) 100ms;
}
.blade.is-revealed::before { transform: scaleY(1); }
@media (prefers-reduced-motion: reduce) {
  .blade::before { transform: none; transition: none; }
}

/* ---- 4. Pin + horizontal scroll for product families ---- *
 * When .families gets .is-pinned (set by JS), panels stack absolutely on
 * top of each other. The active panel slides in from the right + fades in;
 * inactive panels translate out. The tabs column stays static; tab active
 * state is driven by scroll progress. */
.families.is-pinned .families__panels {
  position: relative;
  /* Make the panel container hold the tallest panel's height so the layout
   * doesn't collapse. min-height already set by individual panels. */
  min-height: 420px;
  overflow: hidden;
}
.families.is-pinned .families__panel {
  display: flex;
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateX(48px);
  transition:
    opacity 600ms cubic-bezier(0.2, 0.8, 0.2, 1),
    transform 700ms cubic-bezier(0.2, 0.8, 0.2, 1);
  pointer-events: none;
  /* Override the "hidden" attribute so all panels render simultaneously
   * but only one is visible. */
}
.families.is-pinned .families__panel[hidden] { display: flex; }
.families.is-pinned .families__panel.is-active {
  opacity: 1;
  transform: translateX(0);
  pointer-events: auto;
  z-index: 1;
}
.families.is-pinned .families__panel:not(.is-active) {
  /* Outgoing panel slides slightly to the LEFT as the next slides in from
   * the right — feels like a deck of cards turning. */
  transform: translateX(-32px);
}
@media (prefers-reduced-motion: reduce) {
  .families.is-pinned .families__panel {
    transition: none;
  }
}

/* ---- 5. Cross-section background wash ---- *
 * A fixed full-viewport tint that lerps as scroll progresses. Sits ABOVE
 * the body's texture image but BELOW page content (z-index: 0; main content
 * gets z-index: 1). Uses semi-transparent gradient stops so the texture
 * still reads through. CSS variables --wash-from / --wash-to / --wash-glow
 * are interpolated by JS on scroll. */
.bg-wash {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 80% 50% at 50% 100%, var(--wash-glow, rgba(245, 179, 30, 0.04)), transparent 70%),
    linear-gradient(180deg, var(--wash-from, rgba(17, 26, 46, 0.0)) 0%, var(--wash-to, rgba(19, 29, 52, 0.45)) 100%);
  mix-blend-mode: normal;
  transition: background 800ms linear;
}
/* Lift content above the wash so it's not tinted out. The nav already has
 * its own position: sticky + z-index: 40, and grid-frame already has z-index:1
 * — both float above the wash without help. Just need main + footer here. */
main, .footer { position: relative; z-index: 1; }

/* ---- Footer hairline cells (Enerblock idiom, simplified) ---- *
 * Each link column has a left hairline border (vertical rule between cells)
 * and the column heading is followed by a small amber square marker inline.
 * On mobile the grid collapses to 1 col; left borders flip to top borders. */
.footer__cell {
  position: relative;
  padding: var(--space-6) var(--space-6) 0;
  border-left: 1px solid rgba(255, 255, 255, 0.10);
}
@media (max-width: 767px) {
  .footer__cell {
    border-left: none;
    border-top: 1px solid rgba(255, 255, 255, 0.10);
    padding: var(--space-7) 0 0;
  }
}
.footer__heading-marker {
  display: inline-block;
  width: 10px;
  height: 10px;
  background: var(--color-brand-accent);
  margin-left: var(--space-3);
  vertical-align: middle;
  position: relative;
  top: -1px;
}

/* Below 768px the footer link columns collapse into tap-to-toggle
 * accordions. Above 768px the lists are always visible (no rules here). */
@media (max-width: 767px) {
  .footer__heading {
    cursor: pointer;
    position: relative;
    margin-bottom: 0;
    padding: var(--space-2) var(--space-7) var(--space-2) 0;
    user-select: none;
  }
  .footer__heading::after {
    content: '';
    position: absolute;
    right: 4px;
    top: 0;
    bottom: 0;
    margin: auto 0;
    width: 7px;
    height: 7px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--motion-duration-fast) ease;
  }
  .footer__cell.is-open .footer__heading::after {
    transform: translateY(2px) rotate(225deg);
  }
  .footer__list {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    transition: max-height var(--motion-duration-base) ease,
                opacity var(--motion-duration-fast) ease,
                margin-top var(--motion-duration-base) ease;
  }
  .footer__cell.is-open .footer__list {
    max-height: 420px;
    opacity: 1;
    margin-top: var(--space-4);
  }
}

/* ---- Cross-image SCOPE REVEAL (Enerblock idiom — REFACTORED) ---- *
 *
 * Architecture (matches Enerblock's actual implementation):
 *   .scope-reveal           = OUTER static frame. Holds crosshair markers
 *                             and coordinate labels which are ALWAYS visible.
 *   .scope-reveal__viewport = INNER clipped element that animates. clip-path
 *                             starts as a tiny 1.5rem corner square and
 *                             expands to the full viewport bounds.
 *   .scope-reveal__inner    = Image/content inside the viewport. Scales from
 *                             1.97x → 1x synchronized with the clip-path.
 *
 * The key change from the previous version: frame chrome is OUTSIDE the
 * clipped area, so labels and crosshairs are always visible — they don't
 * get clipped away at the start of the animation.
 *
 * Driven by --scope-progress (0 → 1) set by JS via scroll scrub.
 * Falls back to fully-revealed when JS isn't present. */
/* RESTORED to match Enerblock's actual cross-image mechanic:
 *
 *   WRAPPER (.scope-reveal__viewport) — clip-path inset opens from a tiny
 *   top-left corner outward. As --scope-progress goes 0 → 1, the right and
 *   bottom inset shrink from 95% (tiny visible corner) to 0% (full frame).
 *
 *   INNER (.scope-reveal__inner) — transform: scale starts at 1.97x
 *   (zoomed in) and reduces to 1x (natural). transform-origin top-left
 *   keeps the zoom anchored at the same corner the clip-path opens from.
 *
 * Combined: at progress 0 you see a tiny top-left corner of a zoomed-in
 * image; as you scroll, the visible area opens AND the image zooms back
 * out to natural size. Falls back to fully-revealed when JS isn't present. */
/* SIZED VIA ABSOLUTE POSITIONING so the scope-reveal fills the parent
 * .blade__visual completely. The previous attempt used width:100%/height:100%
 * on a block child of a flex-centering parent, which collapsed to the content
 * height — making the whole animated area invisibly small. Absolute + inset:0
 * bypasses the flex layout entirely. The parent .blade__visual already has
 * position: relative + overflow: hidden, so this works without further changes. */
/* Pure CSS @keyframes animation triggered by IntersectionObserver — no
 * GSAP, no ScrollTrigger, no scrub, no Lenis dependency. Works under
 * file:// as well as live servers. FAIL-SAFE: default state is fully
 * revealed; the .is-revealing class plays the animation from initial
 * hidden state → final revealed state. */
.scope-reveal {
  position: absolute;
  inset: 0;
  display: block;
}
.scope-reveal__viewport {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.scope-reveal__inner {
  position: absolute;
  inset: 0;
  display: block;
  background-color: var(--color-brand-secondary);
  transform-origin: 0 0;
}

/* When JS adds .is-revealing, both layers animate via keyframes that contain
 * the full hidden → revealed sequence. No race conditions possible. */
.scope-reveal.is-revealing .scope-reveal__viewport {
  animation: scopeViewportReveal 1800ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
.scope-reveal.is-revealing .scope-reveal__inner {
  animation: scopeInnerReveal 1800ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

@keyframes scopeViewportReveal {
  0%   { clip-path: inset(0% 95% 95% 0%); }
  100% { clip-path: inset(0% 0% 0% 0%); }
}
@keyframes scopeInnerReveal {
  0%   { transform: scale(2); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .scope-reveal.is-revealing .scope-reveal__viewport,
  .scope-reveal.is-revealing .scope-reveal__inner { animation: none; }
}

/* COORDINATE labels on the outer frame — always visible decorative spec marks. */
.scope-reveal__coord {
  position: absolute;
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  letter-spacing: 0.16em;
  color: rgba(245, 179, 30, 0.75);
  pointer-events: none;
  z-index: 3;
  white-space: nowrap;
}
.scope-reveal__coord--y { bottom: -16px; left: 8px; }
.scope-reveal__coord--x { top: -16px; right: 8px; }

@media (prefers-reduced-motion: reduce) {
  .scope-reveal { --scope-progress: 1; }
  .scope-reveal__inner { transform: none; transition: none; }
}

/* ---- 7. Stat-section line-graphic — RADIAL BOOT-UP REVEAL ---- *
 * Cooler than a left-to-right wipe: the graphic blooms outward from a center
 * point (like a radar coming online) while a faint amber pulse-ring expands
 * synchronously and fades. Combined with a tiny scale-in for "settling" feel.
 * The Three.js canvas inside is unmodified — wrapper-level effects only. */
.stat-section__graphic {
  transform-origin: 50% 50%;
  transition:
    clip-path 2200ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity 1400ms ease,
    transform 2400ms cubic-bezier(0.16, 1, 0.3, 1);
}
.stat-section__graphic.is-armed {
  /* Start with a small visible circle at center (not zero) so there's always
   * SOMETHING on screen even mid-animation — avoids a blank-section moment.
   * Opacity also starts at a low value rather than 0 for the same reason. */
  clip-path: circle(8% at 50% 50%);
  opacity: 0.15;
  transform: scale(0.96);
}
.stat-section__graphic.is-armed.is-revealed {
  clip-path: circle(85% at 50% 50%);
  opacity: 1;
  transform: scale(1);
}
/* Amber pulse-ring overlay that expands with the reveal and fades out */
.stat-section__graphic::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 24px;
  height: 24px;
  margin: -12px 0 0 -12px;
  border-radius: 50%;
  border: 1px solid rgba(245, 179, 30, 0.0);
  pointer-events: none;
  opacity: 0;
}
.stat-section__graphic.is-armed.is-revealed::after {
  animation: graphicPulse 2400ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes graphicPulse {
  0%   { transform: scale(0.4);  opacity: 0;   border-color: rgba(245, 179, 30, 0.55); }
  18%  { opacity: 1; }
  100% { transform: scale(60);   opacity: 0;   border-color: rgba(245, 179, 30, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .stat-section__graphic {
    clip-path: none; opacity: 1; transform: none; transition: none;
  }
  .stat-section__graphic::after,
  .stat-section__graphic.is-armed.is-revealed::after { animation: none; opacity: 0; }
}

/* Section needs position: relative so .section-rule can absolutely position. */
section[data-section] {
  position: relative;
}

/* ─── Unified section backgrounds ──────────────────────────────────────────
   By default body has a Background Texture.jpg + radial gradient. Transparent
   sections show that texture inconsistently between Y positions (the body
   radial gradient is brighter at top). For visual uniformity across the home,
   give every section an explicit solid bg, except sections that intentionally
   show a different surface (hero with its own gradient, transition with
   dramatic radial overlays).
   ───────────────────────────────────────────────────────────────────────── */
/* Home sections are transparent so the body's Background Texture.jpg +
 * radial gradient shows through (matches the design system spec). */
section[data-section="hero_tabs"],
section[data-section="integration_grid"],
section[data-section="pain_point"],
section[data-section="feature_split_rows"],
section[data-section="stat_strip"],
section[data-section="differentiator"],
section[data-section="domain_expertise"] {
  background: transparent;
}
/* NOTE: "cta" intentionally excluded — the final CTA keeps its own opaque
 * space-panel background (which also covers the .grid-frame lines here). */

/* ─────────────────────────────────────────────────────────────────────────
   MOBILE RESPONSIVE COMPACTION
   Sections default to padding:160px and several have min-height:80-95vh,
   which makes the home page 10×+ viewport tall on small phones. Cap padding
   and min-height aggressively below tablet (<768px) so each section fits in
   roughly 1 viewport without huge empty zones.
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width: 767px) {
  /* Generic block-padding cap for any data-section except the hero. The
   * attribute selector outranks .section / .pain / .stat-strip class rules.
   * "products" (psuite) is excluded: its own mobile layout (≤880px, see
   * .psuite__pin / .psuite__head below) already carries dedicated top/bottom
   * spacing, so this generic padding was stacking on top of it and leaving
   * ~140-190px of dead navy space after the card row. */
  section[data-section]:not([data-section="hero"]):not([data-section="products"]) {
    padding-top: var(--space-9);     /* 64px (was 120-160px) */
    padding-bottom: var(--space-9);
  }
  /* Sections that intentionally use min-height for scroll choreography on
   * desktop — collapse to natural content height on mobile. */
  section[data-section="transition"],
  section[data-section="stat_strip"] {
    min-height: 0;
  }
  /* Families: keep the asymmetric padding-bottom but shrink both sides. */
  section[data-section="product_families"] {
    padding-top: var(--space-9);
    padding-bottom: var(--space-6);  /* 32px tail */
  }
  /* Section headers: less breathing room below their headline on mobile. */
  .section__header { margin-bottom: var(--space-7); }
  /* Blade rows: large desktop internal padding makes each row 1000+px tall. */
  .blade { padding: var(--space-7) 0; }
  .blade__content { padding: var(--space-7) var(--space-5); }
}

/* Below desktop the side-by-side layout breaks down. Stack vertically:
 * content on top, visual below. The visual stays visible (real image inside)
 * and takes a sensible image-aspect height instead of the desktop 360px
 * placeholder. */
@media (max-width: 1023px) {
  .blade__inner { grid-template-columns: 1fr; }
  .blade__visual {
    min-height: 0;
    aspect-ratio: 16 / 9;
    width: 100%;
  }
  /* The desktop `.blade--right .blade__content { margin-left: auto }` rule
   * pushes the content to the right edge of its grid cell, which made sense
   * when the cell was 50% of viewport. In the stacked layout the cell is
   * full-width, so margin-auto leaves a huge left gap. Reset to left-aligned. */
  .blade--right .blade__content { margin-left: 0; }
  /* Below desktop the .blade__content sits in a full-width cell, so the 540px
   * cap leaves dead space on the right. Let content fill the column. */
  .blade__content { max-width: 100%; }
}

/* Soften the same patterns on tablet too (768–1023). */
@media (min-width: 768px) and (max-width: 1023px) {
  /* "products" (psuite) excluded — see the ≤767px rule above for why. */
  section[data-section]:not([data-section="hero"]):not([data-section="products"]) {
    padding-top: var(--space-10);    /* 80px */
    padding-bottom: var(--space-10);
  }
  section[data-section="stat_strip"] { min-height: 0; }
  /* transition handled by the broader @media (max-width: 1279px) rule above */
}

/* ─────────────────────────────────────────────────────────────────────────
   KEYPOINT/SECTION CARDS — used by all detail pages (missions/products/etc)
   Section eyebrow + headline + card grid pattern.
   ───────────────────────────────────────────────────────────────────────── */
.section__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-5);
}
.section__headline {
  font-family: var(--type-family-display);
  font-size: clamp(28px, 3.5vw, 48px);
  font-weight: 500;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  max-width: 30ch;
  margin: 0 0 var(--space-9);
}
.kp-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
@media (min-width: 768px) {
  .kp-grid--2 { grid-template-columns: repeat(2, 1fr); }
  .kp-grid--3 { grid-template-columns: repeat(3, 1fr); }
}
.kp-card {
  padding: var(--space-7);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  transition: background-color 250ms ease, border-color 250ms ease;
}
.kp-card:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.16);
}
/* Card titles sit in 178px (kp-grid--4) and 275px (kp-grid--3) columns, so a
   long one strands a two-word orphan on its last line. Balance evens the
   lines instead. Purely typographic: unsupported browsers ignore it. */
.kp-card__title {
  text-wrap: balance;
  font-family: var(--type-family-display);
  font-size: clamp(18px, 1.6vw, 22px);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-3);
  line-height: 1.25;
}
.kp-card__body {
  font-size: 15px;
  line-height: 1.65;
  color: var(--color-text-dim);
  margin: 0;
}

/* Detail pages: ensure background sections paint over the grid-frame hairlines. */
.page-inner section.section {
  background: var(--color-brand-primary);
}

/* ─────────────────────────────────────────────────────────────────────────
   LEADERSHIP cards — used by /company-leadership.html
   Visual placeholder (portrait area) + name + title + preview + full bio.
   ───────────────────────────────────────────────────────────────────────── */
.lead-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-7);
}
@media (min-width: 768px) { .lead-grid { grid-template-columns: repeat(2, 1fr); } }
.lead-card {
  display: flex;
  flex-direction: column;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 2px;
  overflow: hidden;
  transition: border-color 250ms ease, background-color 250ms ease;
}
.lead-card:hover {
  background: rgba(255, 255, 255, 0.05);
  border-color: rgba(255, 255, 255, 0.18);
}
.lead-card__visual {
  aspect-ratio: 4 / 5;
  background:
    linear-gradient(135deg, rgba(245, 179, 30, 0.18) 0%, transparent 60%),
    repeating-linear-gradient(0deg, transparent 0 31px, rgba(255, 255, 255, 0.05) 31px 32px),
    repeating-linear-gradient(90deg, transparent 0 31px, rgba(255, 255, 255, 0.05) 31px 32px),
    var(--color-brand-secondary);
}
.lead-card__body { padding: var(--space-6); }
.lead-card__name {
  font-family: var(--type-family-display);
  font-size: clamp(20px, 1.6vw, 24px);
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-text-inverse);
  margin: 0 0 4px;
}
.lead-card__title {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-4);
}
.lead-card__preview {
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-5);
}
.lead-card__btn {
  align-self: flex-start;
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  background: transparent;
  border: none;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  padding: var(--space-4) 0 0;
  width: 100%;
  text-align: left;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: gap 200ms ease, color 200ms ease;
}
.lead-card__btn:hover { gap: 14px; color: var(--color-text-inverse); }
.lead-card__btn span { transition: transform 200ms ease; }
.lead-card__btn:hover span { transform: translateX(4px); }

/* ─── Leadership side panel (drawer) ─── */
.lead-drawer {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  visibility: hidden;
}
.lead-drawer[aria-hidden="false"] {
  pointer-events: auto;
  visibility: visible;
}
.lead-drawer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(7, 11, 22, 0.70);
  opacity: 0;
  transition: opacity 300ms ease;
  border: none;
  cursor: pointer;
  padding: 0;
}
.lead-drawer[aria-hidden="false"] .lead-drawer__backdrop { opacity: 1; }
.lead-drawer__panel {
  position: absolute;
  top: 64px;   /* below the sticky nav (64px tall on desktop) */
  right: 0;
  bottom: 0;
  width: min(640px, 96vw);
  background: var(--color-brand-primary);
  border-left: 1px solid rgba(255, 255, 255, 0.16);
  transform: translateX(100%);
  transition: transform 360ms cubic-bezier(0.22, 0.61, 0.36, 1);
  overflow-y: auto;
  padding: var(--space-7) var(--space-7) var(--space-9);
}
@media (max-width: 1023px) { .lead-drawer__panel { top: 56px; } }
.lead-drawer[aria-hidden="false"] .lead-drawer__panel { transform: translateX(0); }
.lead-drawer__close {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  z-index: 10;
  width: 40px;
  height: 40px;
  background: rgba(17, 26, 46, 0.85);
  border: 1px solid rgba(255, 255, 255, 0.20);
  color: var(--color-text-inverse);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 200ms ease, background-color 200ms ease;
}
.lead-drawer__close:hover { border-color: var(--color-brand-accent); background: rgba(245, 179, 30, 0.08); }
.lead-drawer__visual {
  aspect-ratio: 4 / 5;
  width: 50%;
  margin: 0 auto var(--space-7);
  background:
    linear-gradient(135deg, rgba(245, 179, 30, 0.18) 0%, transparent 60%),
    repeating-linear-gradient(0deg, transparent 0 31px, rgba(255, 255, 255, 0.05) 31px 32px),
    repeating-linear-gradient(90deg, transparent 0 31px, rgba(255, 255, 255, 0.05) 31px 32px),
    var(--color-brand-secondary);
  border: 1px solid rgba(255, 255, 255, 0.08);
}
.lead-drawer__eyebrow {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-4);
}
.lead-drawer__name {
  font-family: var(--type-family-display);
  font-size: clamp(28px, 3vw, 40px);
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-2);
}
.lead-drawer__title {
  font-family: var(--type-family-eyebrow);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-6);
}
.lead-drawer__preview {
  font-size: 17px;
  line-height: 1.6;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-6);
  padding-bottom: var(--space-6);
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
}
.lead-drawer__bio p {
  font-size: 15px;
  line-height: 1.7;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-4);
}

/* Blade visual: real SVG illustration (replaces the placeholder scope-reveal). */
.blade__visual-img {
  display: block;
  width: 100%;
  height: auto;
  max-height: 100%;
  object-fit: contain;
}
/* Blade visual cell — fixed-aspect block that holds the HUD overlay. Restored
 * after a refactor that had collapsed it to 0 height. */
.blade__visual {
  position: relative;
  background: var(--color-brand-secondary);
  overflow: hidden;
  min-height: 360px;
  padding: 0;
}
@media (min-width: 1024px) {
  .blade__visual { min-height: 0; align-self: stretch; }
}
@media (max-width: 1023px) {
  .blade__visual { aspect-ratio: 4 / 3; }
}

/* ─────────────────────────────────────────────────────────────────────────
   HUD overlay — blade visual SVG + positioned badges/callouts (per design)
   ───────────────────────────────────────────────────────────────────────── */
.hud {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.hud__grid {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  display: block;
}
.hud__badge {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: inline-block;
  padding: 5px 9px;
  background: rgba(17, 26, 46, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-family: var(--type-family-eyebrow);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  color: var(--color-text-inverse);
  white-space: nowrap;
  z-index: 2;
}
.hud__badge--left  { left: 11%; }
.hud__badge--right { right: 8%; }
.hud__callout {
  position: absolute;
  right: 14%;
  list-style: none;
  margin: 0;
  padding: 9px 12px;
  border: 1px solid rgba(255, 255, 255, 0.20);
  background: rgba(17, 26, 46, 0.55);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  font-family: var(--type-family-eyebrow);
  font-size: 9.5px;
  letter-spacing: 0.10em;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.78);
  z-index: 2;
  min-width: 96px;
}
.hud__callout--tr { top: 12%; }
.hud__callout--br { bottom: 12%; }
.hud__callout li {
  position: relative;
  padding-left: 10px;
}
.hud__callout li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  width: 4px;
  height: 4px;
  background: var(--color-brand-accent);
  border-radius: 50%;
  transform: translateY(-50%);
}
@media (max-width: 1023px) {
  .hud__badge { font-size: 9px; padding: 4px 7px; }
  .hud__callout { font-size: 9px; min-width: 86px; padding: 7px 10px; }
}
@media (max-width: 767px) {
  .hud__callout--tr { top: 8%; right: 8%; }
  .hud__callout--br { bottom: 8%; right: 8%; }
  .hud__badge--left { left: 8%; }
  .hud__badge--right { right: 4%; }
}

/* ─────────────────────────────────────────────────────────────────────────
   UNIFIED H2 STYLING
   Every section headline reads like the PROOF/stats headline
   (.stat-section__headline): display family, weight 500, 1.15 line-height,
   -0.02em tracking. Font-size is intentionally NOT set here, so each headline
   keeps its own scale — the display headlines (INTEGRATED C3, the CTA) stay
   large. Placed last so it wins the cascade over each headline's own rule.
   ───────────────────────────────────────────────────────────────────────── */
/* Every H2 on the page: unified style AND a single 36px size. */
.stat-section__headline,
.pain__headline,
.transition__headline,
.combo__h,
.families__headline,
.psuite__title,
.endcta__h {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--color-text-inverse);
}

/* ─────────────────────────────────────────────────────────────────────────
   DIFFERENTIATOR + EXPERTISE combined (ported from V2), dark mode.
   Header: headline left / bridging subhead right. Body: one 3×2 numbered grid
   with white hairline dividers. Transparent background (site provides navy).
   ───────────────────────────────────────────────────────────────────────── */
.combo {
  position: relative; z-index: 1;
  background: transparent; color: #fff;
  /* No bottom padding: the grid closes right on the next section's top line so
   * the vertical column dividers meet it. Each column keeps its own inner
   * padding-bottom for breathing room between the copy and the line. */
  padding: clamp(76px, 11vh, 140px) 0 0;
}
/* Width matches the .grid-frame side lines (center ±600px = 1200px) so the
 * grid's top border + row divider run all the way out to those side lines. */
/* Cyan accent glow (left-center) — as a ::before so the section-level
 * transparent-background rule can't override it. */
.combo::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background: radial-gradient(50% 46% at 32% 50%, rgba(47, 196, 219, 0.14), transparent 60%);
}
.combo__inner { position: relative; z-index: 1; max-width: 1200px; margin: 0 auto; padding: 0; }
@media (max-width: 1247px) { .combo__inner { padding: 0 clamp(20px, 5vw, 40px); } }
.combo__head {
  display: grid; grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(28px, 5vw, 72px); align-items: end;
  padding: 0 25px;   /* keep header text off the side frame lines */
}
.combo__h { text-transform: uppercase; margin: 0; max-width: 20ch; }
.combo__sub {
  font-family: var(--type-family-body); font-size: 16px; line-height: 1.6;
  color: rgba(255, 255, 255, 0.66); max-width: 52ch; margin: 0;
}
.combo__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  margin-top: clamp(48px, 7vh, 96px);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
}
.combo__col { padding: clamp(30px, 3.4vh, 46px) clamp(26px, 2.6vw, 46px); }
.combo__col:nth-child(3n+1) { padding-left: 25px; }   /* keep edge text off the frame lines */
.combo__col:nth-child(3n)   { padding-right: 25px; }
.combo__col:not(:nth-child(3n+1)) { border-left: 1px solid rgba(255, 255, 255, 0.12); }
.combo__col:nth-child(n+4)  { border-top: 1px solid rgba(255, 255, 255, 0.12); }
.combo__num {
  display: block; font-family: var(--type-family-display); font-weight: 200;
  font-size: clamp(34px, 3.4vw, 52px); line-height: 1; letter-spacing: -0.02em; color: #2FC4DB;
}
.combo__t {
  font-family: var(--type-family-display); font-weight: 400;
  font-size: clamp(19px, 1.7vw, 24px); line-height: 1.18; letter-spacing: -0.01em;
  color: #fff; margin: clamp(16px, 2.2vh, 26px) 0 0;
}
.combo__d {
  font-size: clamp(14px, 1.05vw, 16px); line-height: 1.62;
  color: rgba(255, 255, 255, 0.60); margin: clamp(10px, 1.5vh, 15px) 0 0;
}
@media (max-width: 900px) {
  .combo__head { grid-template-columns: 1fr; gap: var(--space-5); align-items: start; }
}
@media (max-width: 820px) {
  .combo__grid { grid-template-columns: 1fr; margin-top: clamp(32px, 5vh, 56px); }
  /* align the grid with the header text (header loses its 25px inset) and
     give every item symmetric breathing room above the number and below the
     copy, so the hairlines read as consistent row dividers */
  .combo__head { padding: 0; }
  .combo__col { padding: clamp(26px, 4.5vw, 36px) 0 clamp(30px, 5.5vw, 44px) !important; border-left: 0 !important; border-top: 1px solid rgba(255,255,255,0.12); }
  .combo__col:nth-child(1) { border-top: 0; padding-top: 0 !important; }
  .combo__col:last-child { padding-bottom: clamp(40px, 7vw, 56px) !important; }
}

/* ─────────────────────────────────────────────────────────────────────────
   UNIFIED H3 STYLING — every H3 matches the product-card title:
   22px, weight 500, -0.01em tracking, 1.2 line-height, sentence case.
   Font-size/weight/etc only; each heading keeps its own margins/max-width.
   Placed last so it wins the cascade over each heading's own rule.
   ───────────────────────────────────────────────────────────────────────── */
.pcard__name,
.pain__item-title,
.combo__t,
.prodcard__name {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--color-text-inverse);
}

/* ─────────────────────────────────────────────────────────────────────────
   FINAL CTA — ported from V2 (wireframe-globe space panel), dark mode.
   Copy left, canvas globe right (moved a bit left via wider globe column),
   gold edge bar. Headline uses the unified H2 style above.
   ───────────────────────────────────────────────────────────────────────── */
.endcta {
  position: relative; z-index: 2;   /* above the .grid-frame lines so its opaque bg covers them here */
  display: flex; align-items: stretch;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
  min-height: clamp(520px, 78vh, 780px);
  background:
    radial-gradient(95% 110% at 72% 44%, rgba(47, 196, 219, 0.14), transparent 50%),
    radial-gradient(120% 130% at 72% 48%, #16223a 0%, #0E1626 55%, #0E1626 100%);
  color: #fff; overflow: hidden;
}
/* Wraps left copy + globe as one pair so it can be capped/centered at
   1600px independently of .endcta__bar, which must stay pinned to the
   real viewport edge (see .endcta__bar below). */
.endcta__content {
  display: flex; align-items: stretch; flex: 1 1 auto;
  min-width: 0; max-width: 1600px; margin-inline: auto;
}
.endcta__left {
  flex: 1 1 50%; display: flex; align-items: center;
  padding: clamp(64px, 10vh, 120px) clamp(28px, 5vw, 92px);
  position: relative; z-index: 2;
}
.endcta__inner { max-width: 600px; }
.endcta__h { max-width: 20ch; margin: 0; }   /* size/weight from the unified H2 rule */
.endcta__sub {
  font-family: var(--type-family-body); font-size: 18px; line-height: 1.55;
  color: rgba(255, 255, 255, 0.66); max-width: 42ch; margin-top: clamp(18px, 2.6vh, 28px);
}
/* Two CTAs separated only by a whitespace text node read fine on one line,
   but the moment they wrap that space becomes a line break and they touch.
   Same flex row the hero and end-CTA already use. */
.cta-blade__btns { display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(12px, 1.4vw, 18px); }
.endcta__btns { display: flex; gap: clamp(12px, 1.4vw, 18px); flex-wrap: wrap; margin-top: clamp(28px, 4vh, 44px); }
.endcta__btn {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--type-family-eyebrow); font-size: 13px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; padding: 16px 30px; white-space: nowrap;
  transition: transform .2s, background .2s, box-shadow .2s, color .2s;
}
.endcta__btn .ar { transition: transform .2s; }
.endcta__btn:hover .ar { transform: translateX(4px); }
.endcta__btn--primary { background: var(--color-brand-accent); color: #0E1626; }
.endcta__btn--primary:hover { background: #FFD147; transform: translateY(-2px); }
.endcta__btn--ghost { background: transparent; color: #fff; box-shadow: inset 0 0 0 1.5px rgba(255,255,255,0.34); }
.endcta__btn--ghost:hover { background: rgba(255,255,255,0.08); box-shadow: inset 0 0 0 1.5px rgba(255,255,255,0.6); transform: translateY(-2px); }
.endcta__globe { flex: 1 1 48%; position: relative; z-index: 2; overflow: visible; background: transparent; }
/* Full-width dashed horizontal line through the globe's center, spanning the
 * whole section (behind the copy, globe wireframe, and gold bar). */
.endcta::after {
  content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(to right, rgba(47,196,219,0.20) 0 3px, transparent 3px 9px);
}
.endcta__globe::before { content: ""; position: absolute; inset: 0; background: radial-gradient(62% 60% at 48% 50%, rgba(47,196,219,0.16), transparent 72%); pointer-events: none; }
.endcta__sphere { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.dterm { position: absolute; left: clamp(18px, 5%, 40px); bottom: clamp(18px, 7%, 46px); z-index: 3; width: clamp(150px, 46%, 196px); padding: 1px; background: rgba(86,130,150,0.36); }
.dterm__inner { position: relative; background: rgba(9,16,28,0.78); backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px); padding: clamp(12px,2vw,15px) clamp(13px,2.2vw,17px); }
.dterm__row { display: flex; align-items: center; gap: 10px; font-family: var(--type-family-eyebrow); font-size: clamp(10px,0.9vw,12px); font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: rgba(208,224,242,0.92); padding: 4px 0; }
.dterm__dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: #568296; }
.dterm__dot--gold { background: var(--color-brand-accent); }
.dterm__dot--steel { background: #568296; }
.dterm__dot--white { background: #fff; }
.dterm__dot--mute { background: rgba(255,255,255,0.32); }
.dterm__dot--live { animation: dtermblink 1.8s steps(1,end) infinite; }
.dterm__cnr { position: absolute; width: 3px; height: 3px; border-radius: 50%; background: rgba(86,130,150,0.7); }
.dterm__cnr--tl { top: 5px; left: 5px; } .dterm__cnr--tr { top: 5px; right: 5px; }
.dterm__cnr--bl { bottom: 5px; left: 5px; } .dterm__cnr--br { bottom: 5px; right: 5px; }
@keyframes dtermblink { 0%,55% { opacity: 1; } 56%,100% { opacity: 0.28; } }
.endcta__bar { flex: 0 0 clamp(16px, 2.4vw, 38px); background: var(--color-brand-accent); position: relative; z-index: 2; }
@media (max-width: 989px) {
  .endcta { flex-direction: column; min-height: 0; }
  .endcta__content { flex-direction: column; max-width: none; }
  /* globe first (above the copy), centered, contained — a square box so the
     sphere never gets cropped as the viewport narrows */
  .endcta__globe {
    order: -1; flex: none; z-index: 3;
    width: min(400px, 82vw); height: min(400px, 82vw);
    margin: clamp(40px, 8vw, 64px) auto 0;
  }
  .endcta__left { flex: none; padding: clamp(32px,6vw,48px) clamp(22px,6vw,40px) clamp(56px,10vw,84px); }
  .endcta__inner { max-width: none; }
  .endcta__h { max-width: none; }
  .endcta__sub { max-width: 60ch; }
  .endcta__bar { flex: none; height: clamp(10px,2.4vw,16px); }
}
@media (max-width: 480px) { .endcta__btns { flex-direction: column; }
  .cta-blade__btns { flex-direction: column; } .endcta__btn { justify-content: center; } }

/* CTA orbital SVG — inline ring/satellite graphic used inside .endcta__globe
   (ported from missions.html so it's reusable across all end-CTA sections). */
.endcta__orbits { position: absolute; inset: 0; width: 100%; height: 100%; }
.endcta-sat { transform-box: view-box; animation: endctaOrbit 70s linear infinite; }
.endcta-sat--b { animation-duration: 90s; animation-direction: reverse; }
.endcta-sat--c { animation-duration: 110s; }
@keyframes endctaOrbit { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .endcta-sat { animation: none; } }

/* Telemetry variant of the CTA readout — two-column rows, tabular numbers,
   wider box than the base .dterm (which caps at 196px), centered on the
   section's dashed horizontal line (.endcta::after @ 50%). */
.dterm--telemetry {
  width: clamp(330px, 40%, 440px);
  left: 50%; top: 50%; bottom: auto;
  transform: translate(-50%, -50%);
}
.dterm--telemetry .dterm__inner { min-width: 0; padding: 22px 28px; }
.dterm--telemetry .dterm__row { display: flex; justify-content: space-between; align-items: center; gap: 34px; white-space: nowrap; padding: 7px 0; }
.dterm--telemetry .dterm__lbl { display: inline-flex; align-items: center; gap: 10px; }
.dterm--telemetry .dterm__lbl em { font-style: normal; color: rgba(255,255,255,0.35); margin-left: 5px; }
.dterm--telemetry .dterm__val { color: rgba(255,255,255,0.72); font-variant-numeric: tabular-nums; }

/* ─────────────────────────────────────────────────────────────────────────
   PRODUCT FAMILIES — V2 solutions-card style, dark mode, with product logos.
   Vertical card: category eyebrow, dark logo panel, headline + body, gold CTA.
   ───────────────────────────────────────────────────────────────────────── */
.prodgrid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(16px, 1.5vw, 24px);
}
@media (max-width: 1100px) { .prodgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .prodgrid { grid-template-columns: 1fr; } }
.prodcard {
  display: flex; flex-direction: column;
  background: #16223a;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.30);
  overflow: hidden;
}
.prodcard__cat {
  margin: 0;
  padding: clamp(18px, 1.7vw, 22px) clamp(18px, 1.6vw, 24px) clamp(14px, 1.4vw, 18px);
  font-family: var(--type-family-eyebrow); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: #2FC4DB; line-height: 1.4;
}
.prodcard__logo {
  background: #0a1120;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(30px, 3.2vw, 46px) clamp(20px, 2vw, 28px);
  min-height: clamp(150px, 14vw, 186px);
}
.prodcard__logo img {
  display: block; width: auto; height: auto;
  max-width: 88%; max-height: 50px; object-fit: contain;
}
.prodcard__body {
  flex: 1 1 auto;
  padding: clamp(20px, 1.8vw, 26px) clamp(18px, 1.6vw, 24px) clamp(20px, 1.8vw, 26px);
}
.prodcard__name { margin: 0; }   /* size from the unified H3 rule (22px) */
.prodcard__desc {
  margin: clamp(10px, 1.2vh, 14px) 0 0;
  font-size: 14px; line-height: 1.55; color: rgba(255, 255, 255, 0.60);
}
.prodcard__cta {
  margin-top: auto;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 14px clamp(18px, 1.6vw, 24px);
  background: #F5B31E; color: #0E1626;
  font-family: var(--type-family-eyebrow); font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.3;
  transition: background .2s ease;
}
.prodcard__cta:hover { background: #FFD147; }
.prodcard__cta .ar { transition: transform .2s ease; }
.prodcard__cta:hover .ar { transform: translateX(3px); }


/* ═════════════════════════════════════════════════════════════════════════
   CANONICAL HEADING SCALE — derived from the V3 homepage, 2026-07-08.
   Single source of truth for H1–H6 on EVERY page. Placed last in the file so
   it wins the cascade over per-component sizes. Component classes are listed
   alongside the elements so classed headings unify too.
   H1 56px (64 ≥1440) · H2 36px · H3 22px · H4 17px · H5 13px · H6 11px
   ═════════════════════════════════════════════════════════════════════════ */
:root {
  /* responsive tokens referenced by older component rules but never shipped */
  --type-size-h1-lg: 64px;
  --type-size-display-lg: 72px;
  --type-size-h2-lg: 36px;
}
h1, .hero__headline {
  font-family: var(--type-family-display);
  font-weight: 600;
  font-size: clamp(36px, 5vw, 56px);
  line-height: 1.05;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
}
@media (min-width: 1440px) { h1, .hero__headline { font-size: 64px; } }
h2,
.stat-section__headline, .pain__headline, .transition__headline, .combo__h,
.families__headline, .psuite__title, .endcta__h, .blade__title,
.section__header h2, .intro__headline, .section__headline {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--color-text-inverse);
}
h3, .pcard__name, .pain__item-title, .combo__t, .prodcard__name,
.feature-cell__title, .kp-card__title {
  font-family: var(--type-family-display);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--color-text-inverse);
}
h4 { font-family: var(--type-family-display); font-weight: 500; font-size: 17px; line-height: 1.25; letter-spacing: 0.04em; text-transform: uppercase; color: var(--color-text-inverse); }
h5 { font-family: var(--type-family-eyebrow); font-weight: 600; font-size: 13px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--color-brand-accent, #F5B31E); }
h6 { font-family: var(--type-family-eyebrow); font-weight: 600; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255,255,255,0.55); }


/* ═══════════════════════════════════════════════════════════════════════════
   HeliOS product-family components  (promoted from product-families/HeliOS/)
   Registered in .components/build.py — see components.html for live examples.

   .tband*          Trust band: labelled fact rows + orbit graphic
   .prod-*          Products-by-mission: numbered groups of accordion cards
   .proof-ticker*   Trusted-by logo reels: two counter-scrolling tracks
   .tick-list       Gold-tick bullet list used inside product cards
   .stat-strip--four / .stat__desc / .stat__foot   4-up numbered stat strip

   Base (dark) treatment lives here. The light-mode inversion used on the
   HeliOS page is scoped there via main .section[data-section="..."] so it
   stays a page choice, not a component default.
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Helios-page-only helpers (minimal additions — everything else reuses
   punch-styles.css components verbatim). ──────────────────────────────────
   1. .stat-strip--four / .stat__foot / .stat__desc — copied 1:1 from
      missions.html: four proof cards (homepage tape is 5-col) and a body
      line under each stat value anchored to the cell bottom.
   2. .tick-list          — plain hairline-tick bullet list used inside cards
                            (WHY summary points + product Key Features / Use
                            Cases). Token-only styling, no new visual idiom.
   3. .kp-card__points    — spacing modifier when a tick-list sits under a
                            kp-card body (top hairline + breathing room).
   4. .prod-group / .prod-card — layout scaffolding for the NEW
      products_by_mission section: mono eyebrow-style group label with a
      hairline rule (same recipe as .section__eyebrow + blade marker rule),
      and a two-column grid INSIDE a stock .kp-card surface (copy left,
      Key Features / Use Cases lists right). No new surfaces or colors. ──── */
@media (min-width: 768px)  { .stat-strip--four { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) {
.stat-strip--four { grid-template-columns: repeat(4, 1fr); }
}
@media (min-width: 768px) and (max-width: 1023px) {
.stat-strip--four .stat { border-left: none; border-top: 1px solid rgba(255,255,255,0.10); }
.stat-strip--four .stat:nth-child(odd) { border-left: none; }
.stat-strip--four .stat:nth-child(even) { border-left: 1px solid rgba(255,255,255,0.10); }
.stat-strip--four .stat:nth-child(-n+2) { border-top: none; }
}
.stat__foot { margin-top: auto; }
.stat__desc {
  font-size: var(--type-size-body-sm);
  line-height: 1.55;
  color: var(--color-text-dim);
  margin: var(--space-2) 0 0;
}
.tick-list { list-style: none; margin: 0; padding: 0; }
.tick-list li {
  position: relative;
  padding: 5px 0 5px 18px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--color-text-dim);
}
.tick-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 14px;
  width: 8px;
  height: 1px;
  background: var(--color-brand-accent);
}
.prod-group { margin-top: var(--space-10); }
.prod-group:first-of-type { margin-top: 0; }
.prod-group__label {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  font-family: var(--type-family-eyebrow);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-brand-accent);
  margin: 0 0 var(--space-6);
}
.prod-group__label::after { content: ""; flex: 1; height: 1px; background: rgba(255,255,255,0.12); }
.prod-group__num { color: rgba(255,255,255,0.40); }
.prod-stack { display: grid; gap: 0; }
.prod-stack .prod-acc { margin-bottom: -1px; border-radius: 0; }
/* boxes flush, borders collapse */
.prod-card { display: grid; grid-template-columns: 1fr; gap: var(--space-7); }
@media (min-width: 1024px) {
.prod-card { grid-template-columns: 5fr 6fr; gap: var(--space-9); padding: var(--space-8); }
}
.prod-card__main { display: flex; flex-direction: column; align-items: flex-start; }
.prod-card__lede {
  font-size: var(--type-size-body-lg);
  line-height: 1.5;
  color: var(--color-text-inverse);
  margin: 0 0 var(--space-4);
}
.prod-card__lists { display: grid; gap: var(--space-6); align-content: start; }
@media (min-width: 768px) {
.prod-card__lists { grid-template-columns: 1fr 1fr; }
}
.prod-card__list-label {
  color: #2FC4DB;
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin: 0 0 var(--space-3);
}
/* title on one line */
/* these cells have no short labels — the desc line plays the label role,
   so it takes the stat-label treatment from the other stat sections */
main .stat-section .stat__desc {
  font-family: var(--type-family-eyebrow);
  font-size: var(--type-size-body-sm);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-dim);
}
/* ── Trust strip — index layout: graphic left (placeholder for supplied
   artwork), grouped rule-lists right. ── */
.tband {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: var(--space-8) 96px;
  align-items: stretch;
  padding: var(--space-8) 0;
}
.tband__gfx {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-height: 480px;
}
.tband__gfx .tband-orb {
  position: relative; z-index: 1;
  width: auto; height: 100%; min-height: 620px; max-height: 760px; display: block;
}
.tband-orb .orb {
  transform-origin: 200px 320px;
  transform-box: view-box;
  animation: orbSpin 80s linear infinite;
}
.tband-orb .orb--2 { animation-duration: 115s; animation-direction: reverse; }
.tband-orb .orb--3 { animation-duration: 145s; }
.tband-orb .orb--4 { animation-duration: 95s; animation-direction: reverse; }
@keyframes orbSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
.tband-orb .orb { animation: none; }
}
@media (max-width: 1000px) {
.tband__gfx .tband-orb { min-height: 320px; max-height: 420px; }
}
/* vertical dashed axis — runs the full section, fading out top + bottom */
.tband__gfx::before {
  content: ""; position: absolute; left: 50%; top: -140px; bottom: -140px; width: 1px;
  background-image: repeating-linear-gradient(to bottom,
    rgba(255,255,255,0.5) 0, rgba(255,255,255,0.5) 2px, transparent 2px, transparent 4px);
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 22%, #000 78%, transparent);
  pointer-events: none;
}
@media (max-width: 1000px) {
.tband__gfx::before { top: -60px; bottom: -60px; }
}
.tband__lists {
  display: flex; flex-direction: column; justify-content: space-between;
  gap: 64px;
}
.tband__label {
  position: relative;
  font-family: var(--type-family-eyebrow); font-size: 12px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: #2FC4DB;
  margin: 0 0 6px;
}
.tband__items { list-style: none; margin: 0; padding: 0; }
.tband__items li {
  position: relative;
  font-family: var(--type-family-eyebrow); font-size: 11.5px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: rgba(255,255,255,0.72); line-height: 1.5;
  padding: 13px 0 11px;
  transition: color .25s ease, padding-left .3s cubic-bezier(0.22,0.61,0.36,1);
}
/* shortened base rule under each row */
.tband__items li::before {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px;
  width: 80%; background: rgba(255,255,255,0.14);
}
/* hover: text brightens, nudges right, rule underneath draws in cyan */
.tband__items li::after {
  content: ""; position: absolute; left: 0; bottom: 0; height: 1px;
  width: 80%; background: rgba(255,255,255,0.9);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .45s cubic-bezier(0.22,0.61,0.36,1);
}
.tband__items li:hover { color: #fff; padding-left: 10px; }
.tband__items li:hover::after { transform: scaleX(1); }
/* animate in: rows rise + fade, staggered, when the band scrolls into view */
.tband .tband__label,
.tband__items li {
  opacity: 0; transform: translateY(14px);
}
.tband__items li { transition: color .25s ease, padding-left .3s cubic-bezier(0.22,0.61,0.36,1), opacity .6s ease, transform .6s cubic-bezier(0.22,0.61,0.36,1); }
.tband .tband__label { transition: opacity .6s ease, transform .6s cubic-bezier(0.22,0.61,0.36,1); }
.tband.is-in .tband__label,
.tband.is-in .tband__items li { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
.tband .tband__label, .tband__items li { opacity: 1; transform: none; transition: none; }
}
@media (max-width: 1000px) {
.tband { grid-template-columns: 1fr; gap: var(--space-7); }
.tband__gfx { min-height: 260px; order: 2; }
.tband__lists { gap: 48px; order: 1; }
}
@media (min-width: 1248px) {
.prod-stack { margin-inline: calc(-1 * var(--space-6)); }
/* flush with the grid frame */
  .prod-stack .prod-acc { border-left: 0; border-right: 0; }
}
@media (min-width: 1248px) {
.prod-group__label { margin-right: calc(-1 * var(--space-6)); }
/* rule meets the right frame line */
  .prod-acc__icon { right: var(--space-6); }
}
.prod-acc { padding: 0; align-items: stretch; }
/* undo kp-card's flex-start shrink */
.prod-acc__summary, .prod-acc__inner { width: 100%; }
.prod-acc__summary {
  cursor: pointer; list-style: none;
  position: relative;   /* Safari ignores flex on <summary> — anchor the toggle absolutely */
  display: block;
  padding: var(--space-6) calc(var(--space-7) + 54px) var(--space-6) var(--space-7);
}
.prod-acc__summary::-webkit-details-marker { display: none; }
.prod-acc__title {
  font-family: var(--type-family-display); font-weight: 500;
  font-size: 22px; line-height: 1.2; letter-spacing: -0.01em;
  color: var(--color-text-inverse);
}
.prod-acc__icon {
  position: absolute; right: var(--space-7); top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.8);
  display: flex; align-items: center; justify-content: center;
  transition: background .2s ease, border-color .2s ease;
}
.prod-acc__icon::after {
  content: "+"; font-family: var(--type-family-eyebrow); font-size: 16px; font-weight: 600;
  color: #FFFFFF; line-height: 1;
}
.prod-acc[open] .prod-acc__icon, .prod-acc.is-expanded .prod-acc__icon {
  background: var(--color-brand-accent, #F5B31E);
  border-color: var(--color-brand-accent, #F5B31E);
}
.prod-acc[open] .prod-acc__icon::after, .prod-acc.is-expanded .prod-acc__icon::after { color: #0E1626; }
.prod-acc[open] .prod-acc__icon::after, .prod-acc.is-expanded .prod-acc__icon::after { content: "\2013"; }
.prod-acc__summary:hover .prod-acc__title { color: var(--color-brand-accent, #F5B31E); }
.prod-acc__inner {
  display: grid; grid-template-columns: 1fr; gap: var(--space-7);
  padding: 0 var(--space-7) var(--space-8);
  border-top: 1px solid rgba(255,255,255,0.08);
}
/* text block full width left; gold button anchored bottom-right opposite it */
.prod-acc__inner .prod-card__main {
  padding-top: var(--space-6);
  display: grid; grid-template-columns: minmax(0,1fr) auto;
  gap: 0 var(--space-9); align-items: end;
}
.prod-acc__inner .prod-card__lede,
.prod-acc__inner .kp-card__body { grid-column: 1; max-width: 72ch; }
.prod-acc__inner .prod-card__lede { margin-bottom: var(--space-2); }
.prod-acc__inner .prod-card__cta {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  margin: 0;
}
/* bulleted sections below, two columns, full width */
.prod-acc__inner .prod-card__lists { grid-template-columns: 1fr 1fr; }
@media (max-width: 767px) {
.prod-acc__inner .prod-card__main { grid-template-columns: 1fr; }
.prod-acc__inner .prod-card__cta { grid-column: 1; grid-row: auto; margin-top: var(--space-5); }
}
/* ── Trusted-by tickers — same treatment as the product overview page ── */
.proof-tickers { margin-bottom: var(--space-9); position: relative; }
.proof-ticker {
  display: flex; align-items: center; gap: var(--space-7);
  padding: var(--space-5) 0; border-bottom: 1px solid rgba(255,255,255,0.10);
}
.proof-ticker:first-child { border-top: 1px solid rgba(255,255,255,0.10); }
.proof-tickers__heading { /* centered over both reels, homepage label style */
  font-family: var(--type-family-eyebrow); font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--color-text-dim); text-align: center;
  margin: 0 0 var(--space-7);
}
.proof-ticker__label { /* homepage logo-cloud label treatment */
  flex: 0 0 auto; margin: 0; max-width: 220px;
  font-family: var(--type-family-eyebrow); font-size: var(--type-size-eyebrow);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--color-text-dim); line-height: 1.5;
}
.proof-ticker__window {
  flex: 1; overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 6%, #000 94%, transparent);
}
.proof-ticker__track {
  display: inline-flex; white-space: nowrap; width: max-content;
  animation: proofTick 70s linear infinite;
}
.proof-ticker__track--rev { animation-duration: 46s; animation-direction: reverse; }
.proof-ticker:hover .proof-ticker__track { animation-play-state: paused; }
.proof-ticker__item {
  font-family: var(--type-family-eyebrow); font-size: 12px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--color-text-dim); /* homepage .logo-cloud__item treatment */
  padding-right: 56px; position: relative;
}
.proof-ticker__item::after {
  content: ""; position: absolute; right: 26px; top: 50%; transform: translateY(-50%);
  width: 4px; height: 4px; border-radius: 50%; background: rgba(255,255,255,0.25);
}
.proof-ticker__item--logo { display: inline-flex; align-items: center; }
.proof-ticker__item--logo img {
  height: 44px; width: auto; object-fit: contain;
  filter: grayscale(1) invert(1);   /* dark seals -> light monochrome */
  mix-blend-mode: screen;
  opacity: 0.85;
}
.proof-ticker__item--white img { filter: none; height: 28px; }
/* Bimodal marks (dark ring/fill + light lettering, e.g. official seals) must NOT
   be inverted — invert flips the light details dark and the screen blend then
   erases them, leaving a muddy badge instead of a clean mark. Brightness lifts
   the whole mark toward white first, then screen drops the dark fill out against
   the section background while keeping the light detail visible. Keeps the row's
   44px height, unlike --white which is for wide wordmarks. */
.proof-ticker__item--light img { filter: grayscale(1) brightness(1.6); mix-blend-mode: screen; opacity: 0.92; }
.proof-ticker__item--sm img { height: 20px; }
@keyframes proofTick { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
.proof-ticker__track { animation: none; }
}
@media (min-width: 1248px) {
.proof-tickers { margin-inline: calc(-1 * var(--space-6)); }
.proof-ticker__label { padding-left: var(--space-6); }
}
@media (max-width: 1000px) {
.proof-ticker { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
/* Stacking flips the main axis, so flex:1 no longer sizes the window and
   align-items:flex-start shrinks it to the full track width — the marquee
   stops clipping and the logos run off-screen. Pin it back to the row. */
.proof-ticker__window { width: 100%; align-self: stretch; min-width: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════════
   CPAW product-page components  (promoted from product-families/HeliOS/cpaw/)
   Registered in .components/build.py — see components.html for live examples.

   .probsol* / .ps-*   Problem-vs-Solution split: two columns, numbered rows,
                       each column with its own fill graphic
   .blade__caps*       Capability blade: a named capability + its bullet list
   .crumbs             Breadcrumb trail for pages nested under a family
   .stat-rail*         Hairline rails flanking a stat strip
   .section__lead      Standfirst paragraph under a section headline

   Same placement rule as the HeliOS set: these load at the END of
   punch-styles.css because they override components defined earlier in it.
   ═══════════════════════════════════════════════════════════════════════ */
.crumbs {
  display: flex;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: var(--space-3);
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-dim);
  margin: 0 0 var(--space-6);
}
.crumbs a { color: var(--color-text-dim); text-decoration: none; transition: color var(--motion-duration-fast) ease; }
.crumbs a:hover { color: var(--color-brand-accent); }
.crumbs .crumbs__sep { color: rgba(255,255,255,0.25); }
.crumbs [aria-current] { color: var(--color-text-inverse); }
.feature-cell--statement { min-height: 220px; }
.section__headline--tight { margin-bottom: var(--space-5); }
.section__lead {
  font-size: var(--type-size-body-lg);
  line-height: 1.6;
  color: var(--color-text-dim);
  max-width: 62ch;
  margin: 0 0 var(--space-9);
}
.blade__caps {
  list-style: none;
  margin: var(--space-6) 0 0;
  padding: 0;
}
.blade__caps-label {
  font-family: var(--type-family-eyebrow);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.40);
  margin: var(--space-6) 0 var(--space-2);
}
.blade__caps li {
  position: relative;
  padding: var(--space-3) 0 var(--space-3) 22px;
  border-top: 1px solid rgba(255,255,255,0.10);
  font-size: var(--type-size-body-sm);
  line-height: 1.55;
  color: var(--color-text-dim);
}
.blade__caps li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: calc(var(--space-3) + 7px);
  width: 6px;
  height: 6px;
  background: var(--color-brand-accent);
}
.stat__value--text {
  font-size: 23px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  max-width: 16ch;
  font-variant-numeric: normal;
  color: var(--color-text-inverse);
}
@media (min-width: 1248px) {
.stat__value--text { font-size: 26px; }
}
.stat-strip--four .stat__value--text { margin-top: var(--space-5); min-height: 2.4em; }
/* Proof-section grid rails at +/-600 spanning the full section height, so the
   left/right lines continue above and below the card strip (the card borders
   only cover the card height; these carry the line through the rest). */
.stat-rail { position: absolute; top: 0; bottom: 0; left: 50%; width: 1px; background: rgba(255,255,255,0.12); z-index: 0; pointer-events: none; display: none; }
.stat-rail--l { transform: translateX(-600px); }
.stat-rail--r { transform: translateX(599px); }
@media (min-width: 1248px) {
.stat-rail { display: block; }
}
/* ── PROBLEM / SOLUTION — side-by-side ruled grid (problem left, solution right).
   Sentence-case headings; large body-copy rows separated by hairlines that run
   full-bleed to the +/-600 grid rails and meet a full-height center rule. Headers
   reserve equal height so 01 aligns; each row's content is vertically centered
   for equal padding above and below. ── */
.probsol { --ps-pad: clamp(var(--space-6), 3.2vw, var(--space-9));
  position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 0; align-items: stretch; }
.probsol__col { min-width: 0; display: flex; flex-direction: column; }
.probsol__col--problem  { padding-right: var(--ps-pad); }
.probsol__col--solution { padding-left:  var(--ps-pad); }
.probsol__col .section__eyebrow { margin-bottom: var(--space-5); }
.probsol__col .section__headline { text-transform: none; font-size: clamp(24px, 2.4vw, 32px); line-height: 1.18; letter-spacing: -0.02em; max-width: 26ch; min-height: 3.6em; margin-bottom: var(--space-6); }
.probsol__col--problem .section__eyebrow { color: rgba(255,255,255,0.55); }
.probsol__col--solution .section__eyebrow { color: var(--color-brand-accent); }
.ps-list { display: flex; flex-direction: column; flex: 0 0 auto; border-bottom: 1px solid rgba(255,255,255,0.13); }
.probsol__col--problem  .ps-list { margin-right: calc(-1 * var(--ps-pad)); }
.probsol__col--solution .ps-list { margin-left:  calc(-1 * var(--ps-pad)); }
.ps-item { display: flex; flex-direction: column; justify-content: center; flex: none; height: clamp(84px, 7vw, 112px); padding-block: var(--space-3); border-top: 1px solid rgba(255,255,255,0.13); box-sizing: border-box; }
.probsol__col--problem  .ps-item { padding-right: var(--ps-pad); }
.probsol__col--solution .ps-item { padding-left:  var(--ps-pad); }
.ps-item__row { display: flex; align-items: baseline; gap: var(--space-5); }
.ps-item__num { flex: none; font-family: var(--type-family-eyebrow); font-size: 12px; font-weight: 500; letter-spacing: 0.16em; color: rgba(255,255,255,0.38); }
.ps-item__text { margin: 0; font-size: clamp(15px, 1.15vw, 18px); line-height: 1.4; color: var(--color-text-inverse); }
.ps-fill { flex: 1 1 auto; min-height: clamp(140px, 16vw, 240px); position: relative; overflow: hidden; }
.probsol__col--problem .ps-fill { margin-right: calc(-1 * var(--ps-pad)); }
.ps-fill__svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
@media (max-width: 900px) {
.probsol { grid-template-columns: 1fr; }
.probsol__col--problem, .probsol__col--solution { padding-inline: 0; }
.probsol__col--solution { margin-top: var(--space-10); }
.probsol__col--problem .ps-list, .probsol__col--solution .ps-list { margin-inline: 0; }
.probsol__col--problem .ps-item, .probsol__col--solution .ps-item { padding-inline: 0; flex: none; height: auto; min-height: 0; padding-block: clamp(var(--space-5), 1.6vw, var(--space-7)); }
/* the trailing spacer only exists to keep the two columns level; stacked,
   it is just a hairline over dead space. */
.ps-item:empty { display: none; }
.ps-fill { display: none; }
}
