/* Home v2 (2026-11-04). Loaded after ../css/style.css and ../css/home.css.
   The page: topo hero -> wildfire problem -> the wheel -> the terrain solution
   -> the aircraft -> contact. One line language runs through it ("Contour
   Lift"): ink contours on cream, warmed to ember, lifted into the terrain,
   flattened into the dial under the craft. One light: cream day, dusk glow,
   clear morning, flat studio.
   Tokens are the site's (cream #fbfbf9, orange #e8722a, ink). The two ash
   steps are PLACEHOLDER values until the palette is picked. Nothing here
   touches the shared stylesheets. */

body.home.v2 {
  --ash-1: #ece7e1;   /* PLACEHOLDER */
  --ash-2: #d9d2ca;   /* PLACEHOLDER */
  --ember: #e8722a;
  background: var(--bg);
  transition: none;
}

/* ---------- fixed layers ----------
   topo (hero map) under everything; haze above the page, under the nav. */
.v2 .topo { position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%; pointer-events: none; transition: opacity 0.2s linear; }
.v2 main, .v2 .home-hero, .v2 .footer { position: relative; z-index: 1; }
/* still (reduced motion / ?reveal=all): the map is the hero's own backdrop, not a page-long layer */
/* no-motion keeps the map fixed: js/home-v2.js switches its heat and fade by scroll position, without tweens */

/* ---------- nav: one glass bubble (Ryan, 2026-11-06, after untillabs.com) ----------
   A single floating pill, 14px from the top, holding the wordmark, the six links and the
   action. Liquid glass over whatever is under it (the map, the cream, the fire), a bright rim
   along the top, a sheen top-left, a soft lift. Away on the way down, back on the way up.
   Under 1081px the shared bar and its menu sheet stay as they are. */
.v2 .nav { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; border-bottom: 0;
  transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1); }
.v2 .nav.scrolled { border-bottom: 0; }
.v2 .nav::before { content: none; }
.v2 .nav.nav-away { transform: translateY(calc(-100% - 20px)); }
.v2 .nav-bubble { display: none; }
.v2 .nav-cta, .v2 .nav-links-cta { font-size: 15px; letter-spacing: 0.01em; padding: 10px 20px; }   /* orange, as the site's (Ryan kept it, 2026-11-05) */
@media (min-width: 1081px) {
  /* Apple Liquid Glass, second take (Ryan, 2026-11-06: "more liquid glass like Apple, it sucks
     right now" — the first take read as brushed metal: a milky fill and four thick white rims).
     Now the glass is CLEAR: almost no fill, a light blur with strong saturation so the map or
     the page shows through in colour, and the thickness is carried by the edge alone — a thin
     rim lit from the top left and again from the bottom right (a conic ring in ::before, masked
     to the border), a faint catchlight across the top (::after), and the backdrop lensed along
     the rim by the refraction filter (#lg-refract, drawn by js/glass.js). The plain blur line
     before the url() one is the fallback for browsers that cannot reference a filter here. */
  .v2 .nav {
    top: 14px; left: var(--pad); right: var(--pad); height: 58px; max-width: 1180px; margin-inline: auto;
    gap: 16px; padding: 0 6px 0 20px; border-radius: 999px; isolation: isolate;
    background: linear-gradient(180deg, rgba(251, 251, 249, 0.9), rgba(251, 251, 249, 0.82) 55%, rgba(251, 251, 249, 0.86));   /* the home's white, on every page (Ryan, 2026-11-06) */
    -webkit-backdrop-filter: blur(12px) saturate(1.9) brightness(1.02); backdrop-filter: blur(12px) saturate(1.9) brightness(1.02);
    backdrop-filter: url(#lg-refract) blur(8px) saturate(1.9) brightness(1.02);
    border: 0;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.28),
      inset 0 -1px 0 rgba(255, 255, 255, 0.1),
      inset 0 14px 24px -18px rgba(255, 255, 255, 0.5),
      0 1px 1px rgba(16, 21, 27, 0.05),
      0 14px 36px -14px rgba(16, 21, 27, 0.28);
    transition: transform 0.26s cubic-bezier(0.22, 1, 0.36, 1), background 0.32s, box-shadow 0.32s;
  }
  .v2 .nav::before {   /* the rim: a 1px ring, bright where the light hits (top left, bottom right), near-clear between */
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none; padding: 1px;
    background: conic-gradient(from 150deg at 50% 50%,
      rgba(255, 255, 255, 0.95) 0deg, rgba(255, 255, 255, 0.22) 70deg, rgba(255, 255, 255, 0.12) 150deg,
      rgba(255, 255, 255, 0.85) 200deg, rgba(255, 255, 255, 0.2) 260deg, rgba(255, 255, 255, 0.14) 320deg, rgba(255, 255, 255, 0.95) 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); mask-composite: exclude;
  }
  .v2 .nav::after {   /* the catchlight: a soft band of light along the top, strongest at the left */
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    background:
      radial-gradient(70% 55% at 18% 0%, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0) 70%),
      radial-gradient(40% 60% at 88% 110%, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0) 60%);
  }
  /* once content runs under it the glass frosts (more blur, a whiter fill) so the links stay
     legible over cards and copy, the way a toolbar does; the rim and the lensing stay */
  .v2 .nav.nav-mat { background: linear-gradient(180deg, rgba(251, 251, 249, 0.9), rgba(251, 251, 249, 0.8) 55%, rgba(251, 251, 249, 0.86));
    -webkit-backdrop-filter: blur(28px) saturate(1.8) brightness(1.03); backdrop-filter: blur(28px) saturate(1.8) brightness(1.03);
    backdrop-filter: url(#lg-refract) blur(24px) saturate(1.8) brightness(1.03);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.7),
      inset 0 -1px 0 rgba(255, 255, 255, 0.3),
      0 1px 1px rgba(16, 21, 27, 0.05),
      0 14px 36px -14px rgba(16, 21, 27, 0.22); }
  .v2 .nav-brand { gap: 12px; margin-right: 0; min-height: 0; }
  .v2 .nav-brand .brand-mark { width: 36px; height: auto; }
  /* the mark draws itself left to right each time the pointer lands on the brand (Ryan,
     2026-11-06): the stroke is dashed to its own length and the offset runs down to zero; the
     ghost under it keeps the shape readable while the line travels. Still under reduced motion. */
  .v2 .brand-mark { overflow: hidden; display: block; }
  .v2 .brand-mark path { fill: none; stroke: var(--signal-bright); stroke-width: 68; stroke-linejoin: miter; stroke-miterlimit: 10; }
  .v2 .mark-ghost { opacity: 0; transition: opacity 0.2s ease; }
  .v2 .mark-draw { stroke-dasharray: 1000; stroke-dashoffset: 0; }
  .v2 .nav-brand:hover .mark-ghost { opacity: 0.18; }
  .v2 .nav-brand:hover .mark-draw { animation: mark-draw 0.9s cubic-bezier(0.22, 1, 0.36, 1) both; }
  @keyframes mark-draw { from { stroke-dashoffset: 1000; } to { stroke-dashoffset: 0; } }
  /* the wordmark follows the line (Ryan, 2026-11-06): the letters start as a faint ghost and
     fill to ink behind a thin orange front that sweeps left to right, starting as the mark's
     line crests the big peak and landing just after it finishes. */
  .v2 .nav-brand:hover .nav-wordmark {
    color: transparent; text-shadow: none;
    background: linear-gradient(90deg, var(--ink) 0 46%, var(--signal-bright) 49% 51%, rgba(16, 21, 27, 0.2) 54% 100%);
    background-size: 220% 100%; background-position: 100% 0;
    -webkit-background-clip: text; background-clip: text;
    animation: wordmark-fill 0.75s cubic-bezier(0.22, 1, 0.36, 1) 0.42s both;
  }
  @keyframes wordmark-fill { from { background-position: 100% 0; } to { background-position: 0% 0; } }
  /* the clear header's colour rules are more specific than the hover above and were holding the
     letters solid, so the fill never showed (Ryan, 2026-11-08: "add the effect on the logo to the
     VEXIL SYSTEMS as well"). These win in every state; over the dark sub-page heroes it fills white. */
  html .v2 .nav .nav-brand:hover .nav-wordmark,
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-brand:hover .nav-wordmark {
    color: transparent; text-shadow: none;
    background: linear-gradient(90deg, var(--wm-ink, var(--ink)) 0 46%, var(--signal-bright) 49% 51%, var(--wm-ghost, rgba(16, 21, 27, 0.2)) 54% 100%);
    background-size: 220% 100%; background-position: 100% 0;
    -webkit-background-clip: text; background-clip: text;
    animation: wordmark-fill 0.75s cubic-bezier(0.22, 1, 0.36, 1) 0.42s both;
  }
  html.nav-clear:not(.hero-mark) .v2 .nav:not(.nav-mat):not(.menu-open) { --wm-ink: #fff; --wm-ghost: rgba(255, 255, 255, 0.3); }
  @media (prefers-reduced-motion: reduce) { .v2 .nav-brand:hover .mark-draw { animation: none; } .v2 .nav-brand:hover .mark-ghost { opacity: 0; } .v2 .nav-brand:hover .nav-wordmark, html .v2 .nav .nav-brand:hover .nav-wordmark, html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-brand:hover .nav-wordmark { animation: none; color: var(--wm-ink, var(--ink)); background: none; } }
  .v2 .nav .nav-wordmark { font-size: 0.92rem; }
  /* the links run through the middle of the bubble; the current page is a lighter lens */
  .v2 .nav-links { margin: 0 auto; gap: 2px; padding: 0; background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
  .v2 .nav-links::before { content: none; }
  .v2 .nav-links a { font-size: 15px; font-weight: 500; letter-spacing: 0.01em; color: var(--ink); padding: 9px 15px; margin: 0; border-radius: 999px; transition: background-color 0.22s ease, color 0.22s ease; }
  .v2 .nav-links a.on-bubble, .v2 .nav-links a:hover { color: var(--ink); background: rgba(16, 21, 27, 0.06); }
  .v2 .nav-links a[aria-current="page"] { background: rgba(255, 255, 255, 0.72); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 1px 2px rgba(16, 21, 27, 0.08); }
  .v2 .nav-links a[aria-current="page"]::after { content: none; }
  .v2 .nav-links a.nav-links-cta { display: none; }
  /* the action: a pill at the right end of the bubble */
  .v2 .nav > .nav-cta { border-radius: 999px; padding: 11px 22px; }
}
@media (max-width: 1080px) { .v2 .brand-mark { width: 44px; height: auto; display: block; } .v2 .brand-mark path { fill: none; stroke: var(--signal-bright); stroke-width: 68; stroke-linejoin: miter; stroke-miterlimit: 10; } .v2 .mark-ghost { display: none; } }
@media (min-width: 1081px) and (prefers-reduced-transparency: reduce) {
  .v2 .nav { background: rgba(255, 255, 255, 0.94); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .v2 .nav::after { content: none; }
}
@media (prefers-reduced-motion: reduce) { .v2 .nav.nav-away { transform: none; } }

/* ---------- section index pill ---------- */
.sec-index {
  position: absolute; right: var(--pad); bottom: 18px;
  width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--hair-strong); border-radius: 50%;
  font-size: 12px; font-weight: 600; color: var(--muted);
  background: color-mix(in srgb, var(--bg) 60%, transparent);
}

/* ---------- 1. hero: the map is the hero ---------- */
.v2 .home-hero {
  position: relative;
  min-height: 100svh;
  display: grid; align-content: center;
  padding-top: var(--nav-h);
  padding-bottom: clamp(56px, 8vw, 96px);
}
/* the primary action stays the site's orange (Ryan, 2026-11-05); the second is an ink text link */
/* the second action is liquid glass (Ryan, 2026-11-06, "liquid glass apple"): a clear pill that
   blurs the map behind it, a bright rim along the top and left where the light lands, a
   specular sheen top-left, a soft lift. It brightens and rises under the pointer and presses
   on click. Near-solid under prefers-reduced-transparency. */
.v2 .btn-line { position: relative; isolation: isolate; overflow: hidden; gap: 8px; padding-inline: 22px 18px; color: var(--ink); text-shadow: none;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.58), rgba(255, 255, 255, 0.24) 55%, rgba(255, 255, 255, 0.42));
  border: 1px solid rgba(255, 255, 255, 0.8);
  -webkit-backdrop-filter: blur(18px) saturate(1.5) brightness(1.08); backdrop-filter: blur(18px) saturate(1.5) brightness(1.08);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), inset 1px 0 0 rgba(255, 255, 255, 0.55), inset 0 -1px 0 rgba(255, 255, 255, 0.3), inset 0 0 0 1px rgba(16, 21, 27, 0.04),
    0 1px 2px rgba(16, 21, 27, 0.06), 0 10px 24px -12px rgba(16, 21, 27, 0.32);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.28s, border-color 0.28s, background 0.28s; }
.v2 .btn-line::before { content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  background: radial-gradient(120% 90% at 18% 0%, rgba(255, 255, 255, 0.75), transparent 52%), linear-gradient(180deg, rgba(255, 255, 255, 0.3), transparent 40%); }
.v2 .btn-line:hover { transform: translateY(-1px); border-color: rgba(255, 255, 255, 0.98);
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.36) 55%, rgba(255, 255, 255, 0.55));
  box-shadow: inset 0 1px 0 #fff, inset 1px 0 0 rgba(255, 255, 255, 0.7), inset 0 -1px 0 rgba(255, 255, 255, 0.35), inset 0 0 0 1px rgba(16, 21, 27, 0.05),
    0 2px 4px rgba(16, 21, 27, 0.06), 0 16px 32px -14px rgba(16, 21, 27, 0.38); }
.v2 .btn-line:active { transform: scale(0.97); }
.v2 .btn-line::after { content: "\2192"; font-weight: 500; transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1); }
.v2 .btn-line:hover::after { transform: translateX(3px); }
@media (prefers-reduced-transparency: reduce) { .v2 .btn-line { background: rgba(255, 255, 255, 0.94); -webkit-backdrop-filter: none; backdrop-filter: none; } }
@media (prefers-reduced-motion: reduce) { .v2 .btn-line { transition: none; } .v2 .btn-line:hover { transform: none; } }
.v2 .home-hero-lede { color: var(--ink); font-weight: 400; font-size: 21px; line-height: 1.4; letter-spacing: 0; max-width: 44ch; }
/* first paint: the words settle in from 85% (never hidden); still under no-motion */
@keyframes v2-hero-in { from { opacity: 0.85; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.js:not(.no-motion) .v2 .home-hero-copy h1 { animation: v2-hero-in 0.48s cubic-bezier(0.22, 1, 0.36, 1) both; }
.js:not(.no-motion) .v2 .home-hero-lede { animation: v2-hero-in 0.48s cubic-bezier(0.22, 1, 0.36, 1) 0.06s both; }
.js:not(.no-motion) .v2 .home-hero-actions { animation: v2-hero-in 0.48s cubic-bezier(0.22, 1, 0.36, 1) 0.12s both; }
@media (prefers-reduced-motion: reduce) { .v2 .home-hero-copy h1, .v2 .home-hero-lede, .v2 .home-hero-actions { animation: none; } }
/* 2026-11-06: the hero holds while the colour fills the map (home-v2.js pins it), so the words
   sit on the finished green. They go from ink on the white page to white as the colour comes in
   (--tint, set by topo-v2.js), with a soft dark halo so they hold over the pale summits and the
   lit slopes as well as the shaded ones (Ryan). No box behind them. */
.v2 .home-hero-copy h1, .v2 .home-hero-lede {
  color: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink));
  text-shadow: 0 1px 2px rgba(10, 22, 12, calc(var(--tint, 0) * 0.45)), 0 2px 24px rgba(10, 22, 12, calc(var(--tint, 0) * 0.4));
}
.v2 .hero-cue { opacity: calc(1 - var(--tint, 0) * 0.6); }
/* the wordmark too, while the header is type on the map; ink again once the material is up */
.v2 .nav .nav-wordmark { color: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink)); text-shadow: 0 1px 2px rgba(10, 22, 12, calc(var(--tint, 0) * 0.4)); transition: color 0.32s cubic-bezier(0.22, 1, 0.36, 1), text-shadow 0.32s; }
.v2 .nav.nav-mat .nav-wordmark, .v2 .nav.menu-open .nav-wordmark { color: var(--ink); text-shadow: none; }
.v2 .home-hero-grid { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); align-items: end; }
.v2 .home-hero-copy h1 { max-width: 12ch; }
.v2 .home-hero-side { padding-bottom: 6px; }
/* the centred stack (default): eyebrow / headline / lede / buttons, centred, sized to hold
   the headline to three lines on a laptop */
html.hero-centre .v2 .home-hero { align-content: start; padding-top: calc(var(--nav-h) + 16vh); padding-bottom: clamp(72px, 10vw, 120px); }
html.hero-centre .v2 .home-hero-grid { display: block; }
html.hero-centre .v2 .home-hero-copy, html.hero-centre .v2 .home-hero-side { text-align: center; }
html.hero-centre .v2 .home-hero-copy h1 { max-width: 20ch; margin-inline: auto; font-size: clamp(40px, 5.3vw, 78px); line-height: 1.04; letter-spacing: -0.02em; text-wrap: balance; }
html.hero-centre .v2 .home-hero-side { padding-bottom: 0; }
html.hero-centre .v2 .home-hero-lede { margin: 22px auto 0; max-width: 44ch; text-wrap: balance; }
html.hero-centre .v2 .home-hero-actions { justify-content: center; margin-top: 36px; }
@media (max-width: 759px) { html.hero-centre .v2 .home-hero { align-content: center; padding-top: var(--nav-h); } }

/* the stacked hero, left-aligned: ?hero=stack */
html.hero-stack .v2 .home-hero { align-content: center; }
html.hero-stack .v2 .home-hero-grid { display: block; }
html.hero-stack .v2 .home-hero-copy h1 { max-width: 11ch; }
html.hero-stack .v2 .home-hero-side { padding-bottom: 0; }
html.hero-stack .v2 .home-hero-lede { margin-top: clamp(20px, 2.6vw, 30px); max-width: 44ch; }
html.hero-stack .v2 .home-hero-actions { margin-top: clamp(24px, 3vw, 34px); }

/* the centred headline only: ?hero=title */
html.hero-title .v2 .home-hero { padding-bottom: clamp(72px, 10vw, 120px); }
html.hero-title .v2 .home-hero-grid { display: block; }
html.hero-title .v2 .home-hero-copy { text-align: center; }
html.hero-title .v2 .home-hero-copy .eyebrow, html.hero-title .v2 .home-hero-lede { display: none; }
html.hero-title .v2 .home-hero-copy h1 { max-width: 13ch; margin: 0 auto; text-wrap: balance; }
html.hero-title .v2 .home-hero-side { padding-bottom: 0; }
html.hero-title .v2 .home-hero-actions { justify-content: center; margin-top: clamp(28px, 4vw, 44px); }

/* the panel hero: ?hero=panel. Headline and buttons top-left on a white panel that runs
   off the left edge, a hairline under it, the map reading around it (after Abatable) */
html.hero-panel .v2 .home-hero { align-content: start; padding-top: calc(var(--nav-h) + clamp(16px, 3vw, 40px)); padding-bottom: clamp(56px, 8vw, 96px); overflow: hidden; }
html.hero-panel .v2 .home-hero-grid { display: block; }
html.hero-panel .v2 .home-hero-copy .eyebrow, html.hero-panel .v2 .home-hero-lede { display: none; }
html.hero-panel .v2 .hero-panel {
  position: relative; display: inline-block;
  padding: clamp(28px, 4vw, 52px) clamp(36px, 6vw, 96px) clamp(30px, 4vw, 52px) var(--pad);
  margin-left: calc(-1 * var(--pad));
  background: rgba(255, 255, 255, 0.86);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hair); border-right: 1px solid var(--hair);
}
html.hero-panel .v2 .hero-panel::before {
  content: ""; position: absolute; top: 0; bottom: -1px; right: 100%; width: 100vw;
  background: inherit; border-bottom: 1px solid var(--hair);
}
html.hero-panel .v2 .home-hero-copy h1 { margin-top: 0; max-width: 12ch; line-height: 0.98; }
html.hero-panel .v2 .home-hero-side { padding-bottom: 0; }
html.hero-panel .v2 .home-hero-actions { margin-top: clamp(24px, 3vw, 36px); }
@media (max-width: 800px) {
  html.hero-panel .v2 .hero-panel { display: block; margin-right: calc(-1 * var(--pad)); padding-right: var(--pad); border-right: 0; }
}
/* one cue: a single ink line, fading at its foot */
/* the mark hero (default since 2026-11-07, Ryan, after valerann.com): the wordmark across the
   column under the nav, a line under each end, the headline + buttons bottom-left, the scroll
   note bottom-right. The wordmark is fitted to the column by js (fitMark); the clamp is the
   first paint. Ink -> white with --tint like the rest of the hero type. */
.hero-mark-wrap, .hero-scroll { display: none; }
html.hero-mark .v2 .home-hero { display: grid; grid-template-rows: auto 1fr; align-content: stretch; padding-top: calc(var(--nav-h) + 10px); padding-bottom: clamp(40px, 6vw, 72px); }
html.hero-mark .hero-mark-wrap { display: block; position: relative; z-index: 1; }
/* bigger (Ryan, 2026-11-07): the wordmark runs nearly edge to edge of the screen, not the column,
   with tighter tracking; on phones it stacks VEXIL over SYSTEMS so each line can be twice the size */
html.hero-mark .v2 .hero-mark-wrap { width: calc(100% - 2 * clamp(14px, 1.6vw, 28px)); max-width: none; margin-inline: auto; }
html.hero-mark .hero-mark { margin: 0; width: max-content; max-width: none; white-space: nowrap; font-family: "Michroma", sans-serif; font-weight: 400; font-size: clamp(22px, 8vw, 160px); line-height: 0.92; letter-spacing: 0.03em; text-transform: uppercase;
  color: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink));
  text-shadow: 0 1px 2px rgba(10, 22, 12, calc(var(--tint, 0) * 0.45)), 0 2px 28px rgba(10, 22, 12, calc(var(--tint, 0) * 0.4)); }
html.hero-mark .v2 .hero-foot { align-self: end; }
html.hero-mark .v2 .home-hero-grid { display: block; }
html.hero-mark .v2 .home-hero-copy h1 { max-width: 15ch; font-size: clamp(28px, 3.3vw, 50px); line-height: 1.04; letter-spacing: -0.02em; text-wrap: balance; }
html.hero-mark .v2 .home-hero-lede { display: none; }
html.hero-mark .v2 .home-hero-side { padding-bottom: 0; }
html.hero-mark .v2 .home-hero-actions { margin-top: clamp(18px, 2.4vw, 28px); }
html.hero-mark .hero-scroll { display: block; position: absolute; right: var(--pad); bottom: 28px; margin: 0; font-family: "Michroma", sans-serif; font-size: 10.5px; letter-spacing: 0.08em;
  color: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink)); opacity: 0.8; }
html.hero-mark .v2 .hero-cue { display: none; }
html.js.hero-mark:not(.no-motion) .hero-mark { animation: v2-hero-in 0.48s cubic-bezier(0.22, 1, 0.36, 1) both; }
@media (max-width: 759px) {
      html.hero-mark .hero-scroll { display: none; }
      html.hero-mark .hero-mark span { display: block; }
      html.hero-mark .hero-mark span + span { margin-top: 0.06em; }
      /* phones (Ryan, 2026-11-07: "positioning of text similar to v2, in the center"): the
         wordmark centred, the headline centred in the middle of the screen at v2's size */
      /* (later the same day) no big wordmark on phones; the name goes back in the bar beside the mark, as in v2 */
      html.hero-mark .hero-mark-wrap { display: none; }
      html.hero-mark .v2 .home-hero { grid-template-rows: 1fr; }
      html.nav-clear.hero-mark .v2 .nav .nav-wordmark, html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-wordmark { display: inline; color: var(--ink); text-shadow: none; }
      html.hero-mark .v2 .hero-foot { align-self: start; text-align: center; padding-top: 11svh; }
      html.hero-mark .v2 .home-hero-copy h1 { max-width: 460px; margin-inline: auto; font-size: 40px; line-height: 1.04; }
}
html.hero-mark .hero-mark-wrap, html.hero-mark .v2 .hero-foot, html.hero-mark .hero-scroll { position: relative; z-index: 1; }
html.hero-mark .hero-scroll { position: absolute; }
html.nav-clear .v2 .nav .nav-wordmark { color: var(--ink); text-shadow: none; }
/* the name beside the mark in the top left, at every width and on every page (Ryan, 2026-11-08:
   the big hero wordmark is gone, so the bar carries VEXIL SYSTEMS again); white over the dark
   sub-page heroes, ink on the home map and on the bar */
/* no bar over the photo (Ryan, 2026-11-07: "ditch the pill, just the text"): while it sits on
   the hero the nav is bare type, no fill, blur, rim or shadow (white over the dark sub-page heroes, ink over the home map); the links
   underline on hover. The white bar comes back once the hero has scrolled past (home-v2.js
   sets nav-mat at the hero's foot on this layout). The orange Contact button stays. */
/* the section links sit left, beside the mark, not centred (Ryan, 2026-11-07); Contact stays right */
@media (min-width: 1081px) { html.nav-clear .v2 .nav-links { margin: 0 auto 0 12px; } }
@media (min-width: 1081px) {
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) {
    background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open)::before,
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open)::after { opacity: 0; }
  html.nav-clear .v2 .nav::before, html.nav-clear .v2 .nav::after { transition: opacity 0.32s; }
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-wordmark,
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45); }
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a:hover,
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a[aria-current="page"] {
    color: #fff; background: none; box-shadow: none; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; }
}
/* the home hero is the cream map again (2026-11-07, the film parked): the bare nav type is ink there */
@media (min-width: 1081px) {
  html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a,
  html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a:hover,
  html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a[aria-current="page"] { color: var(--ink); text-shadow: none; }
}
/* the centred hero (Ryan, 2026-11-08: "get rid of the VEXIL SYSTEMS wide and just put Setting the
   standard ... in the middle with some other stuff similar to the v2 position"): no wordmark,
   the headline, lede and the two buttons stacked in the middle of the screen at v2's size. The
   wordmark markup and the rules above stay, hidden, so it can come back. */
html.hero-mark .hero-mark-wrap { display: none; }
html.hero-mark .v2 .home-hero { grid-template-rows: 1fr; }
html.hero-mark .v2 .hero-foot { align-self: center; text-align: center; padding-top: 0; }
html.hero-mark .v2 .home-hero-copy h1 { max-width: 20ch; margin-inline: auto; font-size: clamp(40px, 5.3vw, 78px); line-height: 1.04; }
html.hero-mark .v2 .home-hero-lede { display: block; margin: 22px auto 0; max-width: 44ch; text-wrap: balance; }
html.hero-mark .v2 .home-hero-actions { display: flex; justify-content: center; margin-top: 36px; }
html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-wordmark { color: var(--ink); text-shadow: none; }   /* ink over the home map */
@media (max-width: 759px) {
  html.hero-mark .v2 .hero-foot { align-self: center; padding-top: 0; }
  html.hero-mark .v2 .home-hero-copy h1 { max-width: 460px; font-size: 40px; }
  html.hero-mark .v2 .home-hero-lede { margin-top: 18px; }
  html.hero-mark .v2 .home-hero-actions { margin-top: 26px; flex-wrap: wrap; gap: 10px; }
}
/* the phone bar sits straight on the hero: white wordmark and menu lines until the material comes up */
@media (max-width: 1080px) {
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-wordmark { color: #fff; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); }
  html.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-menu-btn span { background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); }
  html.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-menu-btn span { background: var(--ink); box-shadow: none; }   /* ink over the home map */
}
.v2 .hero-cue { position: absolute; left: var(--pad); bottom: 24px; width: 1px; height: 32px; background: linear-gradient(var(--ink), transparent); }

/* ---------- 2. problem: the same map, with fire on it ---------- */
.v2 .v2-problem {
  position: relative;
  padding: 0;
  min-height: 40svh;   /* map space between the hero and the summaries; was ~130svh + padding (Ryan, 2026-11-08: "move the tech section up") */
  overflow: hidden;
  color: var(--ink);
}
.v2 .v2-problem .col { position: relative; z-index: 1; }
.v2 .v2-problem-copy {
  max-width: 640px;
  padding: clamp(24px, 3vw, 40px);
  margin-left: calc(-1 * clamp(24px, 3vw, 40px));
  position: relative;
  border-radius: 22px;
  /* liquid glass, about 80% glass (Ryan, 2026-11-05): the map shows through a heavy blur,
     a specular rim light along the top edge, a sheen top-left, a soft lift. The blur is what
     keeps the copy legible (>= 4.5:1 measured on the live page). */
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.2));
  -webkit-backdrop-filter: blur(28px) saturate(1.7);
  backdrop-filter: blur(28px) saturate(1.7);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.75),
    inset 0 -1px 0 rgba(255, 255, 255, 0.18),
    inset 1px 0 0 rgba(255, 255, 255, 0.35),
    inset -1px 0 0 rgba(255, 255, 255, 0.2),
    0 1px 1px rgba(16, 21, 27, 0.05),
    0 16px 40px rgba(16, 21, 27, 0.1);
}
.v2 .v2-problem-copy::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(90% 60% at 12% 0%, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0) 60%);
}
.v2 .v2-problem-copy > * { position: relative; }
/* the small orange labels need a deeper orange on the glass (4.5:1 over the blurred map) */
.v2 .v2-problem-copy .eyebrow, .v2 .v2-problem-copy .breaks li b { color: #7f3a0c; }
@media (prefers-reduced-transparency: reduce) {
  .v2 .v2-problem-copy { background: rgba(251, 251, 249, 0.94); -webkit-backdrop-filter: none; backdrop-filter: none; }
  .v2 .v2-problem-copy::before { content: none; }
}
.v2 .v2-problem .home-h2 { max-width: 16ch; }
.breaks { list-style: none; margin-top: 28px; border-top: 1px solid var(--hair); }
.breaks li { display: grid; grid-template-columns: 96px 1fr; gap: 16px; padding: 14px 0; border-bottom: 1px solid var(--hair); }
.breaks b { font-family: "Michroma", sans-serif; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--signal); padding-top: 4px; }
.breaks p { font-size: 0.98rem; line-height: 1.45; color: var(--muted); }
.breaks p strong { font-weight: 600; color: var(--ink); }
/* the word reveal starts faint on the scrim */
.home-motion .word-reveal .w { color: rgba(16, 21, 27, 0.2); }

/* ---------- 3. the wheel: kept; graded between dusk and morning ---------- */
.v2 .wheel-sec { margin-top: 0; }
.v2 .wheel-bg img { opacity: 0.5; filter: saturate(0.5) sepia(0.25); }
.v2 .wheel-sec::before { background: linear-gradient(to right, rgba(36, 28, 25, 0.86), rgba(36, 28, 25, 0.5)); }
.v2 .wheel-sec { background: #241c19; }

/* ---------- 4. solution: the story beside the section cut, then the ground ----------
   Left: three step rows. Right: the section cut, sticky, played by the scroll
   (the row nearest the middle of the screen is the active one). Below, the
   terrain model full width, there to be explored; nothing drives it. */
.v2 .v2-solution { padding-top: clamp(80px, 11vw, 150px); padding-bottom: 0; }
.v2-sol-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: clamp(24px, 4vw, 72px);
  align-items: start;
}
.v2-sol-copy { padding-top: 8px; }
.v2-sol-copy .home-h2 { max-width: 14ch; }
.sol-steps { list-style: none; margin-top: clamp(36px, 5vw, 64px); border-top: 1px solid var(--hair); }
.sol-step {
  display: grid; grid-template-columns: 44px 1fr; gap: 14px; align-items: start;
  width: 100%; text-align: left; font-family: inherit; color: var(--ink);
  background: none; border: 0; border-bottom: 1px solid var(--hair);
  padding: 26px 0; min-height: 0; cursor: pointer;
  opacity: 0.42; transition: opacity 0.3s ease;
}
.sol-step:hover, .sol-step.is-on { opacity: 1; }
.sol-step:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; border-radius: 6px; }
.sol-num { font-family: "Michroma", sans-serif; font-size: 11px; letter-spacing: 0.12em; color: var(--faint); padding-top: 5px; transition: color 0.2s ease; }
.sol-step.is-on .sol-num { color: var(--signal); }
.sol-step h3 { font-size: var(--t-h3); font-weight: 600; line-height: 1.15; }
.sol-step p { margin-top: 8px; font-size: 0.98rem; line-height: 1.45; color: var(--muted); max-width: 36ch; }
.sol-status { display: inline-flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--faint); }
.sol-status::before { content: ""; width: 7px; height: 7px; background: var(--hair-strong); }
.sol-step.is-on .sol-status::before { background: var(--signal-bright); }
@media (min-width: 1024px) {
  .sol-step { min-height: 44vh; padding: 36px 0; }
  .v2 .v2-sol-media { position: sticky; top: calc(var(--nav-h) + 16px); }
  .sol-steps { padding-bottom: 10vh; }
}
.v2-sol-media { margin: 0; }
.v2 .v2-sol-media .mark-plus, .v2 .v2-sol-frame .mark-plus { z-index: 7; }

/* the section cut: the diagram card */
.cut-wrap { padding: 18px 22px 16px; border: 1px solid var(--hair); border-radius: 20px; background: #fff; }
.cut-head { display: flex; justify-content: space-between; gap: 12px; font-family: "Michroma", sans-serif; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); }
.cut-head #cutStage { color: var(--signal); transition: opacity 0.2s ease; }
.cut { display: block; width: 100%; height: auto; margin-top: 10px; color: var(--ink); }
.cut-ground { fill: rgba(16, 21, 27, 0.07); }
.cut-crest { fill: none; stroke: rgba(16, 21, 27, 0.45); stroke-width: 1; }
.cut-los { stroke: rgba(16, 21, 27, 0.55); stroke-width: 1.3; stroke-dasharray: 3 4; opacity: 0; transition: opacity 0.5s ease; }
.cut-los-ghost { stroke: rgba(16, 21, 27, 0.55); stroke-width: 1.3; stroke-dasharray: 3 4; opacity: 0; transition: opacity 0.5s ease; }
.cut-flight { fill: none; stroke: var(--signal-bright); stroke-width: 1; stroke-dasharray: 2 5; opacity: 0; transition: opacity 0.5s ease; }
.cut-link-a, .cut-link-b { fill: none; stroke: var(--signal-bright); stroke-width: 1.8; transition: stroke-dashoffset 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.cut-link-b { transition-delay: 0.5s; }
.cut-block { opacity: 0; transition: opacity 0.4s ease; }
.cut-block circle { fill: #fff; stroke: var(--ink); stroke-width: 1.2; }
.cut-block path { fill: none; stroke: var(--ink); stroke-width: 1.4; }
.cut-op, .cut-cmd { fill: var(--hair-strong); transition: fill 0.25s ease; }
.cut-relay { fill: var(--hair-strong); transition: fill 0.25s ease; }
.cut text { font-family: inherit; font-size: 11px; font-weight: 600; fill: var(--faint); text-anchor: middle; }
.cut .cut-t-los { font-size: 10px; fill: var(--ink); opacity: 0; transition: opacity 0.4s ease; }
/* the states play in order: s1 operators, s2 command, s3 relay (cumulative) */
.cut.s1 .cut-op, .cut.s2 .cut-cmd, .cut.s3 .cut-relay { fill: var(--signal-bright); }
.cut.s1 .cut-los, .cut.s1 .cut-block, .cut.s1 .cut-t-los { opacity: 1; }
.cut.s2 .cut-los-ghost { opacity: 0.35; }
.cut.s2 .cut-flight { opacity: 1; }
.cut.s3 .cut-link-a, .cut.s3 .cut-link-b { stroke-dashoffset: 0 !important; }
.cut.s3 .cut-los, .cut.s3 .cut-los-ghost { opacity: 0.18; }
.cut.s3 .cut-block, .cut.s3 .cut-t-los { opacity: 0.35; }
.cut.s3 .cut-flight { opacity: 0.35; }
.cut-readout { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 18px; margin-top: 14px; border-top: 1px solid var(--hair); }
.cut-readout div { padding: 12px 0 2px; border-right: 1px solid var(--hair); padding-right: 14px; }
.cut-readout div:last-child { border-right: 0; }
.cut-readout dt { font-family: "Michroma", sans-serif; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); }
.cut-readout dd { margin-top: 6px; font-size: 0.92rem; font-weight: 600; line-height: 1.3; color: var(--faint); transition: color 0.25s ease, opacity 0.25s ease; }
.cut-readout div.is-on dd { color: var(--ink); }
.cut-readout div.is-new dd { animation: ro-in 0.45s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes ro-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.cut-note { margin-top: 10px; font-size: 0.74rem; color: var(--faint); }

/* the ground, full width, after the story */
.v2-sol-model { margin-top: clamp(64px, 8vw, 120px); }
.v2-sol-model-head { display: flex; align-items: baseline; gap: 18px 28px; flex-wrap: wrap; margin-bottom: 18px; }
.v2-sol-model-title { font-size: var(--t-h3); font-weight: 600; }
.v2-sol-model-hint { margin-left: auto; font-size: 0.86rem; color: var(--faint); }
.v2-sol-frame { position: relative; }
.v2 .home-ground .model, .v2 .model {
  --panel-w: min(380px, 38%);
  height: clamp(560px, calc(100vh - var(--nav-h) - 28px), 980px);
  margin-top: 0;
  border-radius: 20px;
  clip-path: inset(calc((1 - var(--reveal)) * 9%) calc((1 - var(--reveal)) * 7%) round calc(20px + (1 - var(--reveal)) * 24px));
}
.v2 .model .pin { width: 240px; }
.v2 .ground-note { margin-top: 12px; }
/* ---------- 5. the aircraft: a pinned stage ---------- */
.v2 .v2-product { padding-top: clamp(96px, 13vw, 180px); padding-bottom: clamp(64px, 8vw, 120px); }
.v2 .v2-product .home-head { margin-bottom: clamp(28px, 4vw, 48px); }
.pstage {
  position: relative;
  height: 90vh; min-height: 560px;
  display: grid; grid-template-rows: 1fr auto;
  background: var(--bg);
}
.pstage-scene { position: relative; min-height: 0; }
.dial { position: absolute; left: 50%; bottom: 0; width: min(92vw, 760px); transform: translateX(-50%); pointer-events: none; }
.dial svg { display: block; width: 100%; height: auto; overflow: visible; }
.dial-arc { fill: none; stroke: var(--hair); stroke-width: 1; }
.dial-tick { stroke: var(--hair-strong); stroke-width: 1; }
.dial-tick.major { stroke: var(--ink); }
.dial-pointer { stroke: var(--signal-bright); stroke-width: 1.5; transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1); }
.dial-pointer-dot { fill: var(--signal-bright); }
#craftScene {
  position: absolute; left: 50%; top: 46%;
  width: min(92vw, 820px); height: min(58vh, 520px);
  transform: translate(-50%, -50%);
  display: block;
}
.craft-poster {
  position: absolute; left: 50%; top: 46%;
  width: min(92vw, 820px); height: min(58vh, 520px);
  transform: translate(-50%, -50%);
  object-fit: contain; display: none;
}
.pstage.is-poster .craft-poster { display: block; }
.pstage.is-poster #craftScene { display: none; }
.step-label {
  position: absolute; left: 50%; bottom: 22px; transform: translateX(-50%);
  font-family: "Michroma", sans-serif; font-size: 11px; letter-spacing: 0.22em; color: var(--muted);
  white-space: nowrap;
}
.step-label span { color: var(--ink); display: inline-block; min-width: 7ch; text-align: center; }
.pstage-foot { position: relative; z-index: 2; }
.specs {
  list-style: none;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--hair-strong); border-bottom: 1px solid var(--hair);
  background: var(--bg);
}
.spec {
  position: relative;
  display: grid; align-content: start; gap: 6px;
  padding: 22px 20px 24px;
  text-align: left; font-family: inherit; color: var(--ink);
  background: none; border: 0; border-left: 1px solid var(--hair);
  cursor: pointer; opacity: 0.35; transition: opacity 0.3s ease;
}
.spec:first-child { border-left: 0; }
.spec.is-on, .spec:hover { opacity: 1; }
.spec:focus-visible { outline: 2px solid var(--ink); outline-offset: -4px; }
.spec-step { font-family: "Michroma", sans-serif; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--faint); }
.spec.is-on .spec-step { color: var(--signal); }
.spec-value { font-size: clamp(26px, 3vw, 40px); font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; margin-top: 10px; color: var(--ink); }
.spec.is-on .spec-value { color: var(--signal-bright); }
.spec-label { font-family: "Michroma", sans-serif; font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); min-height: 1.4em; }
.spec-note { font-size: 0.8rem; line-height: 1.4; color: var(--muted); }
.specs-note { margin-top: 10px; font-size: 0.74rem; color: var(--faint); }
/* the plain list under the stage: the four moves in words; the whole story under reduced motion */
.steps-list { list-style: none; margin-top: clamp(40px, 6vw, 72px); display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.steps-list li { padding: 22px 0 0; border-top: 1px solid var(--hair); }
.steps-list b { font-family: "Michroma", sans-serif; font-size: 10px; letter-spacing: 0.12em; color: var(--signal); }
.steps-list h3 { margin-top: 10px; font-size: var(--t-h3); }
.steps-list p { margin-top: 8px; font-size: 0.95rem; line-height: 1.45; color: var(--muted); }
.v2-product.no-pin .pstage { height: auto; min-height: 0; }
.v2-product.no-pin .pstage-scene { height: min(70vw, 520px); }
.v2-product.no-pin .dial { display: none; }

/* ---------- contact ---------- */
/* the night map, as on the page headers, with the lines glowing white (Ryan, 2026-11-08). The
   wash rules are copied from blog.css (not loaded on the home); the form stays a white card so
   it reads as easily as before, the words around it go cream */
.v2 #contact { position: relative; isolation: isolate; overflow: hidden; color: #f4efe1;
  --w1: 18, 24, 31; --w2: 36, 44, 54; --deep: 8, 11, 15; --topo: 255, 255, 255; --pool: 70, 86, 104; }
.v2 #contact .wash { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; background: rgb(var(--deep)); }
.v2 #contact .wash-bg { position: absolute; inset: -20%; filter: saturate(0.6);
  background:
    radial-gradient(46% 58% at 18% 42%, rgba(var(--w2), 0.9), rgba(var(--w2), 0) 70%),
    radial-gradient(40% 54% at 76% 28%, rgba(var(--w2), 0.7), rgba(var(--w2), 0) 70%),
    linear-gradient(180deg, rgb(var(--deep)) 0%, rgb(var(--w1)) 50%, rgb(var(--w2)) 100%); }
.v2 #contact .wash-pools { position: absolute; inset: -15%; filter: blur(90px); mix-blend-mode: screen; opacity: 0.35;
  background:
    radial-gradient(28% 34% at 30% 30%, rgba(var(--pool), 0.9), rgba(var(--pool), 0) 70%),
    radial-gradient(22% 30% at 68% 62%, rgba(var(--pool), 0.75), rgba(var(--pool), 0) 70%); }
.v2 #contact .topo-wash, .v2 #contact .topo-live { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: screen;
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,0.3) 0%, #000 18%, #000 82%, rgba(0,0,0,0.3) 100%);
          mask-image: linear-gradient(180deg, rgba(0,0,0,0.3) 0%, #000 18%, #000 82%, rgba(0,0,0,0.3) 100%); }
.v2 #contact .topo-wash { opacity: 0.8; filter: blur(7px); }   /* the halo */
.v2 #contact .topo-live { opacity: 0.85; }                       /* the filament */
.v2 #contact .eyebrow { color: rgba(244, 239, 225, 0.7); }
.v2 #contact .page-h2 { color: #f4efe1; }
.v2 #contact .contact-lede { color: rgba(244, 239, 225, 0.72); }
.v2 #contact .contact-form { background: #fff; border-color: rgba(255, 255, 255, 0.6); box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.55); color: var(--ink); }
.v2 #contact .contact-side-label { color: rgba(244, 239, 225, 0.6); }
.v2 #contact .contact-side-link { color: #f4efe1; border-color: rgba(244, 239, 225, 0.25); }
.v2 #contact .contact-side-link:hover, .v2 #contact .contact-side-link:focus-visible { color: var(--signal-bright); border-color: var(--signal-bright); }
.v2 #contact .contact-nojs, .v2 #contact .contact-nojs a { color: #f4efe1; }

/* ---------- smaller screens ---------- */
@media (max-width: 1023px) {
  .v2-sol-grid { grid-template-columns: 1fr; }
  .v2 .v2-sol-model { display: none; }   /* the ground is a desktop piece: no terrain on phones (Ryan, 2026-11-04) */
  .sol-steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; border-top: 0; margin-top: 24px; }
  .sol-step { grid-template-columns: 1fr; gap: 6px; padding: 14px 16px; border: 1px solid var(--hair); border-radius: 14px; opacity: 1; }
  .sol-step.is-on { border-color: var(--signal-bright); }
  .sol-step p { display: none; }
  .sol-step h3 { font-size: 1rem; }
  .sol-status { margin-top: 6px; }
  .v2 .model { height: clamp(460px, 70vh, 760px); }
  .cut-readout { gap: 0 12px; }
  .v2-sol-model-hint { margin-left: 0; }
}
@media (max-width: 800px) {
  .v2 .home-hero-grid { grid-template-columns: 1fr; align-items: start; }
  .v2 .v2-problem { min-height: 0; padding-bottom: 0; }
  .v2 .v2-problem-copy { margin-left: 0; padding: 20px; }
  .breaks li { grid-template-columns: 1fr; gap: 4px; }
  .sol-steps { grid-template-columns: 1fr; }
  .specs { grid-template-columns: 1fr 1fr; }
  .spec { border-left: 0; border-top: 1px solid var(--hair); }
  .spec:nth-child(1), .spec:nth-child(2) { border-top: 0; }
  .spec:nth-child(even) { border-left: 1px solid var(--hair); }
  .steps-list { grid-template-columns: 1fr 1fr; }
  .pstage { height: auto; min-height: 0; }
  .pstage-scene { height: 64vw; }
  #craftScene, .craft-poster { width: 100%; height: 100%; }
}
@media (max-width: 560px) {
  .specs, .steps-list { grid-template-columns: 1fr; }
  .spec:nth-child(2) { border-top: 1px solid var(--hair); }
  .spec:nth-child(even) { border-left: 0; }
}

/* ---------- reduced motion: final states everywhere ---------- */
@media (prefers-reduced-motion: reduce) {
  .v2 .topo, .v2 .nav, .dial-pointer, .spec, .sol-step, .cut-link-a, .cut-link-b, .cut-los { transition: none; }
  .sol-step { opacity: 1; }
  .cut-readout div.is-new dd { animation: none; }
  .spec { opacity: 1; }
  .v2 .model { clip-path: none; }
}

/* the footer's legal links sit on their own row under the page links (Ryan, 2026-11-08) */
.v2 .footer-legal { margin-top: 0; }

/* ---------- the pages, in brief (2026-11-08): one section per page, the same shape each time ---------- */
.v2 .sum { position: relative; z-index: 1; }   /* the contours carry on behind the summaries; topo-v2.js fades the fires and route out first */
.v2 .sum:has(+ .contact) {   /* the last summary, before Contact */  padding-bottom: clamp(64px, 9vw, 120px); }
.v2 .sum .sum-grid { border-top: 1px solid var(--hair); padding-top: clamp(40px, 5vw, 64px); }
.sum-grid { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(32px, 6vw, 96px); align-items: start; }
.v2 .sum .home-h2 { max-width: 16ch; }
.sum-link { display: inline-block; margin-top: 22px; color: var(--signal); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; transition: color 0.2s; }
.sum-link:hover { color: var(--ink); }

.sum-parts { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.sum-parts li { display: grid; grid-template-columns: 9.5em 1fr; gap: 4px 20px; align-items: baseline; padding: 20px 0; border-top: 1px solid var(--hair); }
.sum-parts li:last-child { border-bottom: 1px solid var(--hair); }
.sum-parts .mono { grid-row: span 2; font-size: 10.5px; letter-spacing: 0.08em; color: var(--muted); text-transform: uppercase; }
.sum-parts b { font-size: clamp(26px, 2.6vw, 38px); font-weight: 600; letter-spacing: -0.03em; line-height: 1; }
.sum-parts p { margin: 6px 0 0; color: var(--muted); max-width: 44ch; }

.sum-stats { display: grid; grid-template-columns: repeat(3, auto); justify-content: start; gap: clamp(20px, 3vw, 44px); margin: 0; }
.sum-stats div { border-top: 1px solid var(--hair); padding-top: 12px; }
.sum-stats dt { font-size: clamp(32px, 3.4vw, 52px); font-weight: 600; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; }
.sum-stats dd { margin: 6px 0 0; font-size: 14px; line-height: 1.35; color: var(--muted); max-width: 17ch; }
.sum-stages { list-style: none; margin: clamp(32px, 4vw, 48px) 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); position: relative; }
.sum-stages::before { content: ""; position: absolute; left: 6px; right: 6px; top: 6px; border-top: 2px dashed var(--signal-bright); opacity: 0.55; }
/* the arrowhead at the end of the dashed line (Ryan, 2026-11-08): the road keeps going past 2029 */
.sum-stages::after { content: ""; position: absolute; right: 2px; top: 2px; width: 10px; height: 10px; box-sizing: border-box; border-top: 2px solid var(--signal-bright); border-right: 2px solid var(--signal-bright); transform: rotate(45deg); opacity: 0.8; }
.sum-stages li { position: relative; padding-top: 24px; }
.sum-stages li::before { content: ""; position: absolute; left: 0; top: 0; width: 10px; height: 10px; border-radius: 50%; background: var(--bg); border: 2px solid var(--signal-bright); }
.sum-stages b { display: block; font-size: clamp(26px, 2.6vw, 38px); font-weight: 600; letter-spacing: -0.04em; line-height: 1; }
.sum-stages span { display: block; margin-top: 6px; font-size: 14px; color: var(--signal); font-weight: 600; }

.sum-people { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 18px 16px; }
.sum-person img { display: block; width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; border-radius: 50%; }
.sum-person b { display: block; margin-top: 12px; font-size: 15px; font-weight: 600; line-height: 1.2; }
.sum-person .sum-person-role { display: block; margin-top: 3px; font-size: 13px; line-height: 1.3; color: var(--muted); }
/* LinkedIn on hover, the same move as the Our Team page: the photo blurs and darkens and a Connect pill comes up in it (Ryan, 2026-11-08) */
.sum-person-link { display: block; color: inherit; text-decoration: none; border-radius: 12px; }
.sum-person-link:focus-visible { outline: 3px solid rgba(232, 114, 42, 0.55); outline-offset: 4px; }
.sum-person-photo { position: relative; display: block; border-radius: 50%; overflow: hidden; background: var(--ink); isolation: isolate; transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1); }
.sum-person-photo picture { display: block; }
.sum-person-photo img { transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1), filter 0.5s; }
.sum-person-veil { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; opacity: 0; transform: translateY(6px); transition: opacity 0.4s cubic-bezier(0.22, 1, 0.36, 1), transform 0.5s cubic-bezier(0.22, 1, 0.36, 1); }
.sum-person-veil .person-connect { display: inline-flex; align-items: center; padding: 0; background: none; color: #fff; font-size: 14px; font-weight: 600; text-shadow: 0 1px 10px rgba(0, 0, 0, 0.45); letter-spacing: -0.005em; transition: transform 0.2s; }
.sum-person-veil .person-connect .ext { display: none; }   /* just the word "Connect", white, no bubble (Ryan, 2026-11-08) */
.sum-person-link:hover .sum-person-photo, .sum-person-link:focus-visible .sum-person-photo { transform: translateY(-3px); }
.sum-person-link:hover img, .sum-person-link:focus-visible img { transform: scale(1.06); filter: blur(8px) brightness(0.62) saturate(0.9); }
.sum-person-link:hover .sum-person-veil, .sum-person-link:focus-visible .sum-person-veil { opacity: 1; transform: none; }
.sum-person-link:hover b, .sum-person-link:focus-visible b { color: var(--signal); }
.sum-person-link:active .person-connect { transform: scale(0.97); }
@media (prefers-reduced-motion: reduce) { .sum-person-photo, .sum-person-photo img, .sum-person-veil { transition: none; } .sum-person-link:hover .sum-person-photo { transform: none; } }

.sum-event { display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: 22px; align-items: center; padding: 14px; border: 1px solid var(--hair); border-radius: 22px; background: #fff; color: var(--ink); text-decoration: none; transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.28s; }
.sum-event:hover { transform: translateY(-2px); box-shadow: 0 18px 40px -28px rgba(16, 21, 27, 0.35); }
.sum-event img { display: block; width: 100%; height: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: 76% 50%; border-radius: 14px; }
.sum-event-body { display: grid; gap: 8px; padding-right: 10px; }
.sum-event-body .mono { font-size: 10.5px; letter-spacing: 0.08em; color: var(--muted); }
.sum-event-body b { font-size: clamp(20px, 1.8vw, 26px); font-weight: 600; letter-spacing: -0.02em; line-height: 1.15; }
.sum-event-body span:last-child { color: var(--muted); font-size: 15px; line-height: 1.45; }

@media (max-width: 900px) {
  .sum-grid { grid-template-columns: 1fr; }
  .sum-parts li { grid-template-columns: 1fr; }
  .sum-parts .mono { grid-row: auto; }
  .sum-stats { grid-template-columns: 1fr 1fr; }
  /* three on top, the last two centred under them (Ryan, 2026-11-08): a six-column grid, each
     person two columns wide, the fourth starting one column in */
  .sum-people { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .sum-people > li { grid-column: span 2; }
  .sum-people > li:nth-child(4) { grid-column: 2 / span 2; }
  .sum-event { grid-template-columns: 1fr; }
}

/* ---------- THE FILM (back 2026-11-08; js/film.js, markup in index.html #film) ----------
   One fixed layer over the topo map, behind the hero and the gap. From the bottom: the ridges
   still (the rise's last frame), the hero (its still + the loop), the rise (scrubbed by the
   scroll), the scrim. film.js sets the layer opacities and --tint (white type over the film).
   html.film-on is set in the head unless ?film=off. */
.film { display: none; }
html.film-on .v2 .film { display: block; position: fixed; inset: 0; z-index: 0; pointer-events: none; background: #0f1a12; }
html.film-on .film > *, html.film-on .film-hero > * { position: absolute; inset: 0; width: 100%; height: 100%; display: block; margin: 0; }
html.film-on .film img, html.film-on .film video { width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%; display: block; filter: saturate(0.92) contrast(1.03); }
html.film-on .film-loop { opacity: 0; transition: opacity 0.6s ease; }   /* fades in over its own first frame once it plays */
html.film-on .film-loop.is-on { opacity: 1; }
html.film-on .film-rise { opacity: 0; }
/* the scrim: darker under the nav and behind the centred headline, so the white type holds */
html.film-on .film-scrim {
  background: radial-gradient(ellipse 70% 46% at 50% 52%, rgba(8, 14, 10, 0.42), rgba(8, 14, 10, 0) 100%),
              linear-gradient(180deg, rgba(8, 14, 10, 0.5) 0%, rgba(8, 14, 10, 0.12) 22%, rgba(8, 14, 10, 0.1) 78%, rgba(8, 14, 10, 0.35) 100%); }
@media (prefers-reduced-motion: reduce) { html.film-on .film video { display: none; } }
/* the gap under the hero is longer with the film, so the camera has room to rise and hold */
html.film-on .v2 .v2-problem { min-height: 130svh; }
/* the clear nav over the film: white type (and white menu lines) following --tint, as on the
   dark sub-page heroes; ink again once the bar's material comes up */
html.film-on.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) .nav-wordmark,
html.film-on.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a,
html.film-on.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a:hover,
html.film-on.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-links a[aria-current="page"] {
  color: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink)); text-shadow: 0 1px 3px rgba(0, 0, 0, calc(var(--tint, 0) * 0.45)); }
html.film-on.nav-clear.hero-mark .v2 .nav:not(.nav-mat):not(.menu-open) .nav-menu-btn span { background: color-mix(in oklab, #ffffff calc(var(--tint, 0) * 100%), var(--ink)); }
html.film-on.nav-clear .v2 .nav:not(.nav-mat):not(.menu-open) { --wm-ink: #fff; --wm-ghost: rgba(255, 255, 255, 0.3); }
/* the outline button is clear glass on the map; over the forest it needs a solid face to read */
html.film-on .v2 .home-hero-actions .btn-line { background: rgba(255, 255, 255, 0.94); color: var(--ink); border-color: transparent; text-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
/* the rise and its end still under a light soft focus (film.js eases --rb 0 -> 1.6px as the camera
   rises; Ryan, 2026-11-08: the smoke clip is 720p and looks blurry, mask it "but not too blurry").
   A matching scale-up keeps the blurred edges off the screen. */
html.film-on .film video.film-rise, html.film-on .film .film-end img {
  filter: saturate(0.92) contrast(1.03) blur(calc(var(--rb, 0) * 1px));
  transform: scale(calc(1 + var(--rb, 0) * 0.012)); }
/* the dissolve: a full-frame backdrop blur over the film, built up by film.js (--hb, 0 -> 28px)
   after a short look at the smoke, before the film fades to the map. A backdrop blur keeps the
   frame's edges clean where a filter on the video would pull in the dark background. */
html.film-on .film-haze { -webkit-backdrop-filter: blur(calc(var(--hb, 0) * 1px)); backdrop-filter: blur(calc(var(--hb, 0) * 1px)); }
/* a shorter gap: the smoke is a glimpse now, not a hold */
html.film-on .v2 .v2-problem { min-height: 110svh; }
/* the scroll cue was removed (Ryan, 2026-11-08: "just get rid of the scroll UI"); the text note's rules above stay hidden */

/* ---------- the phone/tablet menu (Ryan, 2026-11-08: "improve the look of the hamburger dropdown") ----------
   A full-screen sheet: large page names on hairline rows, each ending in an orange dot (arrows until 2026-11-08), the current page's dot ringed; the rows rise in one after
   another; the orange Contact button sits at the foot of the screen. */
@media (max-width: 1080px) {
  .v2 .nav .nav-links { padding: calc(var(--nav-h) + clamp(24px, 6svh, 56px)) var(--pad) max(28px, calc(env(safe-area-inset-bottom) + 20px)); }
  .v2 .nav .nav-links a:not(.nav-links-cta) {
    display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 0;
    font-size: clamp(28px, 8.4vw, 42px); font-weight: 600; letter-spacing: -0.025em; line-height: 1.05;
    padding: clamp(14px, 2.6svh, 22px) 2px; margin: 0;
    color: var(--ink); background: none; border-radius: 0; box-shadow: none; text-shadow: none;
    border-bottom: 1px solid var(--hair);
  }
  .v2 .nav .nav-links a:not(.nav-links-cta)::before { content: none; }   /* no numbers (Ryan, 2026-11-08) */
  /* no arrows; only the page you are on gets the orange dot (Ryan, 2026-11-08). The other rows keep
     the dot's space, transparent, so the text lines up */
  .v2 .nav .nav-links a:not(.nav-links-cta)::after {
    content: ""; width: 8px; height: 8px; border-radius: 50%; background: transparent;
    transition: transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .v2 .nav .nav-links a:not(.nav-links-cta):active { color: var(--signal); }
  .v2 .nav .nav-links a[aria-current="page"]::after { background: var(--signal-bright); box-shadow: 0 0 0 4px rgba(232, 114, 42, 0.22); }
  /* Contact: the orange button at the foot of the screen */
  .v2 .nav .nav-links a.nav-links-cta { margin-top: auto; padding: 18px 16px; font-size: 1.05rem; border-radius: 999px; }
  /* the rows rise in one after another (style.css carries the base transition) */
  .v2 .nav .nav-links a { transform: translateY(18px); }
  .v2 .nav.menu-open .nav-links a { transform: none; }
  .v2 .nav.menu-open .nav-links a:nth-of-type(6) { transition-delay: 0.28s; }
}
@media (max-width: 1080px) and (prefers-reduced-motion: reduce) { .v2 .nav .nav-links a { transform: none; } }


/* contact: cream words on the night map (--tx stays 1; the night fill arrives first) */
.v2 #contact { --tx: 1; }   /* --tx: the words, which flip ink -> cream quickly in the middle */
.v2 #contact .page-h2 { color: color-mix(in oklab, #f4efe1 calc(var(--tx) * 100%), var(--ink)); }
.v2 #contact .eyebrow { color: color-mix(in oklab, rgba(244, 239, 225, 0.7) calc(var(--tx) * 100%), var(--faint)); }
.v2 #contact .contact-lede { color: color-mix(in oklab, rgba(244, 239, 225, 0.72) calc(var(--tx) * 100%), var(--muted)); }
.v2 #contact .contact-side-label { color: color-mix(in oklab, rgba(244, 239, 225, 0.6) calc(var(--tx) * 100%), var(--faint)); }
.v2 #contact .contact-side-link { color: color-mix(in oklab, #f4efe1 calc(var(--tx) * 100%), var(--ink));
  border-color: color-mix(in oklab, rgba(244, 239, 225, 0.25) calc(var(--tx) * 100%), var(--hair)); }
/* soften the top edge: the night map rises out of the paper instead of starting on a straight line */
.v2 #contact .wash { -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 240px); mask-image: linear-gradient(180deg, transparent 0, #000 240px); }

/* the night fill (Ryan, 2026-11-08; js/home-v2.js): a fixed night map that fills the screen from the
   bottom up between the team summary and Contact. Over the page map (z 0, after #topo), under the
   summaries (.sum is z 1) and Contact (later in the page). */
.v2 .night-fill { position: fixed; inset: 0; z-index: 0; pointer-events: none; visibility: hidden; overflow: hidden;
  --w1: 18, 24, 31; --w2: 36, 44, 54; --deep: 8, 11, 15; --topo: 255, 255, 255;
  background: rgb(var(--deep)); clip-path: inset(100% 0 0 0); }
.v2 .night-fill .wash-bg { position: absolute; inset: -20%; filter: saturate(0.6);
  background:
    radial-gradient(46% 58% at 18% 42%, rgba(var(--w2), 0.9), rgba(var(--w2), 0) 70%),
    radial-gradient(40% 54% at 76% 28%, rgba(var(--w2), 0.7), rgba(var(--w2), 0) 70%),
    linear-gradient(180deg, rgb(var(--deep)) 0%, rgb(var(--w1)) 50%, rgb(var(--w2)) 100%); }
/* the page map, copied in and inverted: ink -> white lines, the paper halos under its labels -> dark */
.v2 .night-fill .night-lines, .v2 .night-fill .night-glow { position: absolute; inset: 0; width: 100%; height: 100%; mix-blend-mode: screen; }
.v2 .night-fill .night-lines { filter: invert(1) brightness(1.1); opacity: 0.95; }
.v2 .night-fill .night-glow { filter: invert(1) blur(5px) brightness(2.6); opacity: 0; transition: opacity 1.6s ease; }
.v2 .night-fill.is-contact .night-glow { opacity: 1; }   /* the glow comes on at Contact only */
.v2 .night-edge { position: fixed; left: 0; right: 0; top: 0; z-index: 0; height: 1px; pointer-events: none; visibility: hidden;
  background: rgba(255, 255, 255, 0.7); box-shadow: 0 0 22px 3px rgba(255, 255, 255, 0.28); will-change: transform; }
/* the team's words turn cream as the fill passes them (--tx per block, set by js) */
.v2 #team .home-head, .v2 #team .sum-person, .v2 #team .sum-grid { --tx: 0; }
.v2 #team .home-h2 { color: color-mix(in oklab, #f4efe1 calc(var(--tx) * 100%), var(--ink)); }
.v2 #team .home-lede { color: color-mix(in oklab, rgba(244, 239, 225, 0.72) calc(var(--tx) * 100%), var(--muted)); }
.v2 #team .sum-person b { color: color-mix(in oklab, #f4efe1 calc(var(--tx) * 100%), var(--ink)); }
.v2 #team .sum-person-role { color: color-mix(in oklab, rgba(244, 239, 225, 0.6) calc(var(--tx) * 100%), var(--muted)); }
.v2 #team .sum-grid { border-top-color: color-mix(in oklab, rgba(244, 239, 225, 0.18) calc(var(--tx) * 100%), var(--hair)); }

/* the footer: a solid colour, no map behind it (Ryan, 2026-11-08) */
.v2 .footer { background: var(--bg); }
/* with the fill running, Contact shows the fill's night map instead of its own, so the two are one
   map, one colour (Ryan, 2026-11-08). Without js or under ?reveal=all, Contact keeps its own. */
html.night-on .v2 #contact .wash { display: none; }

/* the contact card: a cool grey-white (was cream, read off against the blue-black night) instead of pure white, so it sits softer on the night (Ryan, 2026-11-08) */
.v2 #contact .contact-form { background: #e3e7eb; border-color: rgba(228, 234, 240, 0.35); box-shadow: 0 30px 70px -34px rgba(0, 0, 0, 0.45); }
.v2 #contact .contact-form input, .v2 #contact .contact-form textarea { background: #f2f4f6; }
.v2 #contact .contact-form select { background-color: #f2f4f6; }

/* the lockup in the map space after the hero (trial, Ryan 2026-11-08): the mark over VEXIL / SYSTEMS,
   set left, in the logo's face. The mark draws in and the words rise when it arrives (.is-in, js). */
.v2 .v2-problem:has(.problem-lockup) { display: flex; flex-direction: column; justify-content: flex-end; }
.v2 .problem-lockup { --film-a: 0; display: flex; flex-direction: column; align-items: flex-start; padding-block: clamp(40px, 6vw, 80px) clamp(12px, 1.6vw, 24px); }   /* lower, close above the roadmap rule (Ryan, 2026-11-08) */   /* at the foot of the map space, on the white map, clear of the film fading out */
.v2 .lockup-mark { width: clamp(90px, 9vw, 150px); height: auto; overflow: visible; }
.v2 .lockup-mark path { fill: none; stroke: var(--signal-bright); stroke-width: 34; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1000; stroke-dashoffset: 1000; transition: stroke-dashoffset 1.4s cubic-bezier(0.22, 1, 0.36, 1); }
.v2 .lockup-word { margin: clamp(14px, 1.6vw, 22px) 0 0; display: flex; flex-direction: column; font-family: "Michroma", sans-serif; font-size: clamp(40px, 6.4vw, 104px); line-height: 1.04; letter-spacing: 0.06em;
  color: color-mix(in oklab, #fff calc(var(--film-a) * 100%), var(--ink)); text-shadow: 0 2px 30px rgba(0, 0, 0, calc(var(--film-a) * 0.35)); }   /* white over the film, ink on the map (js) */
.v2 .lockup-word span { display: block; opacity: 0; transform: translateY(18px); transition: opacity 0.9s cubic-bezier(0.22, 1, 0.36, 1), transform 0.9s cubic-bezier(0.22, 1, 0.36, 1); }
.v2 .lockup-word span + span { transition-delay: 0.12s; }
.v2 .problem-lockup:not(.is-in) .lockup-mark path { transition-duration: 0.7s; }   /* leaving is quicker than arriving */
.v2 .problem-lockup:not(.is-in) .lockup-word span { transition-duration: 0.5s; transition-delay: 0s; }
.v2 .problem-lockup.is-in .lockup-mark path { stroke-dashoffset: 0; }
.v2 .problem-lockup.is-in .lockup-word span { opacity: 1; transform: none; }
html:not(.js) .v2 .lockup-mark path, .v2 .problem-lockup.is-still .lockup-mark path { stroke-dashoffset: 0; transition: none; }
html:not(.js) .v2 .lockup-word span, .v2 .problem-lockup.is-still .lockup-word span { opacity: 1; transform: none; transition: none; }

/* the logo to the left of the words, not above (Ryan, 2026-11-08): one row, the mark as tall as the two lines */
.v2 .problem-lockup { flex-direction: row; align-items: center; gap: clamp(18px, 2.4vw, 40px); }
.v2 .problem-lockup .lockup-word { order: 2; margin: 0; }
.v2 .problem-lockup .lockup-mark { order: 1; width: clamp(110px, 13vw, 220px); }
/* lower still: the summary after it gives up most of its top padding, so the lockup sits just over the roadmap rule */
.v2 .v2-problem:has(.problem-lockup) + .sum { padding-top: clamp(16px, 2vw, 28px); }

/* phones: the lockup fits the width (Ryan, 2026-11-08 mobile audit) */
@media (max-width: 700px) {
  .v2 .problem-lockup { gap: 14px; }
  .v2 .problem-lockup .lockup-mark { width: 17vw; flex: none; }
  .v2 .lockup-word { font-size: 8.2vw; letter-spacing: 0.03em; }
}

/* team on phones (Ryan, 2026-11-08): two centred on top, three under them */
@media (max-width: 700px) {
  .sum-people { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 26px 18px; }
  .sum-people > li, .sum-people > li:nth-child(4) { grid-column: span 2; }
  .sum-people > li:nth-child(1) { grid-column: 2 / span 2; }
  .sum-people > li:nth-child(2) { grid-column: 4 / span 2; }
  /* photos only on the home page, and smaller (Ryan, 2026-11-08); names and roles live on Team.
     The link keeps its aria-label, so each photo still reads as the person and goes to LinkedIn */
  .sum-people { width: calc(100vw - 24px); max-width: none; margin-left: calc(50% - 50vw + 12px); gap: 12px 10px; }   /* a little past the text column, so the photos are bigger */
  .sum-person b, .sum-person .sum-person-role, .sum-person-veil { display: none; }
}

/* phones (Ryan, 2026-11-08): less scroll between the end of the video and the first summary; film.js
   times the fade from where the summary starts, so the fade moves up with it */
@media (max-width: 700px) { html.film-on .v2 .v2-problem { min-height: 75svh; } }

/* the home's team photos in black and white (Ryan, 2026-11-08); colour stays on the Team page. On the
   picture, not the img, so the hover's blur on the img still stacks with it */
.sum-person-photo picture { filter: grayscale(1) contrast(1.06); }

/* the home's team: names only, no titles (Ryan, 2026-11-08); the titles stay on the Team page */
.sum-person .sum-person-role { display: none; }

/* phones (Ryan, 2026-11-08): the three stats in one line, not two rows; the figures scale with the
   screen so "62,500+" still fits a third of it */
@media (max-width: 700px) {
  .sum-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
  .sum-stats dt { font-size: min(6.4vw, 32px); letter-spacing: -0.03em; white-space: nowrap; }
  .sum-stats dd { font-size: 12.5px; }
}

/* phones (2026-11-08, speed): Contact's drifting, 90px-blurred light pools are off, as on the
   section heroes (css/blog.css) */
@media (max-width: 1023px) {
  .v2 #contact .wash-pools { display: none; }
}

/* phones (2026-11-08, speed): the film without its filters. The soft-focus blur and colour filter
   on the playing video, and the full-screen backdrop blur it dissolved through, were redone on
   every frame; on a phone the film plays clean and fades out to the map on opacity alone. Same
   breakpoint as film.js's phone sources (759px). */
@media (max-width: 759px) {
  html.film-on .film img, html.film-on .film video,
  html.film-on .film video.film-rise, html.film-on .film .film-end img { filter: none; transform: none; }
  html.film-on .film-haze { -webkit-backdrop-filter: none; backdrop-filter: none; }
}


/* the speed tier's light mode (js/main.js, 2026-11-08): no refraction filter on the glass. The url()
   backdrop filter re-runs a displacement pass over the map every frame, which a machine without a
   GPU cannot afford; the plain frost is what other browsers already show. */
html.tier-lite .v2 .nav { backdrop-filter: blur(12px) saturate(1.9) brightness(1.02); }
html.tier-lite .v2 .nav.nav-mat { backdrop-filter: blur(28px) saturate(1.8) brightness(1.03); }
/* and the film without its filters, as on phones (the video's soft focus and the dissolve's
   full-screen backdrop blur are redone every frame) */
html.tier-lite.film-on .film img, html.tier-lite.film-on .film video,
html.tier-lite.film-on .film video.film-rise, html.tier-lite.film-on .film .film-end img { filter: none; transform: none; }
html.tier-lite.film-on .film-haze { -webkit-backdrop-filter: none; backdrop-filter: none; }

