/* ============================================================================
   JABALI — Component & layout styles  ·  Helvetis "Cinematic field"
   Requires tokens.css (loaded first). Dependency-free. Desktop-first.
   Breakpoints:  Desktop > 1100px  ·  Tablet 720–1100px  ·  Mobile < 720px

   Structural language (2026-07 redesign):
     · No HUD marks, no frame rails, no card boxes.
     · Content block = ONE 1px top rule + padding-top. Red top rule = featured.
     · Panels (--cc-panel + hairline) are reserved for FORMS only.
     · Media is frameless and full-bleed; the black page is the frame.
     · Section rhythm is plain black (--section-y), never a separator line.
   Components consume tokens only — do not hard-code values here.
   ============================================================================ */

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--cc-bg);
  color: var(--cc-ink);
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  font-size: var(--fs-16);
  line-height: var(--lh-ui);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;   /* full-bleed escapes must not widen the document */
}
img { display: block; max-width: 100%; }
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; }
::selection { background: var(--acc); color: var(--btn-fg); }

/* ---- focus (keyboard only) ---- */
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible,
select:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--r-sharp);
}

/* ============================================================
   STRUCTURE — full-bleed page, per-block measures, black rhythm
   ============================================================ */
.frame { width: 100%; }

/* A content section: no top border, no rails. The gap below IS the rhythm.
   The gutter grows past --pad on wide screens so content stops at
   --measure-wide, while every child keeps the SAME left edge (constraining the
   section, not each child, is what keeps grids and headers aligned). */
.sec {
  position: relative;
  padding: 0 var(--gutter) var(--section-y);
}
/* Pages with no hero (legal, privacy, 404) open directly with a .sec, so their
   heading would sit under the fixed header. Give them the header height back. */
.sec--page { padding-top: calc(var(--nav-h) + 88px); }
@media (max-width: 720px) { .sec--page { padding-top: calc(var(--nav-h) + 48px); } }

/* Re-entry after a full-bleed band (or the figures strip) re-opens the rhythm. */
.bleed + .sec, .figures + .sec { padding-top: var(--section-y-top); }
.sec--tight { padding-bottom: calc(var(--section-y) * 0.6); }

/* Escape hatch: children that must run edge-to-edge inside a padded .sec.
   100vw alone over-shoots by the scrollbar on classic-scrollbar setups, and
   negative --gutter margins under-shoot (the % inside --gutter resolves
   against the parent content box for margins). app.js publishes the real
   scrollbar width as --sbw, so (100vw - --sbw) is the exact visual viewport;
   no-JS falls back to 0 (correct wherever scrollbars overlay). */
/* Doubled class: .media-band declares width:100% later in this file, which
   previously beat this rule and left the payloads band at content width while
   its negative margins still applied. Specificity here is order-independent. */
.bleed-out.bleed-out {
  max-width: none;
  width: calc(100vw - var(--sbw, 0px));
  margin-left: calc(50% - (100vw - var(--sbw, 0px)) / 2);
  margin-right: calc(50% - (100vw - var(--sbw, 0px)) / 2);
}
/* A section that OPENS on full-bleed media: the media is its own top rhythm. */
.sec--band { padding-top: 0; }
.sec--band > .bleed-out:first-child { margin-top: 0; }
.sec--band > .cap-grid { margin-top: 96px; }

/* eyebrow / section marker — numbered with a midpoint, no tick, no rule */
.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--tr-eyebrow);
  text-transform: uppercase;
  color: var(--cc-ink-3);
  font-weight: var(--fw-medium);
  display: block;
  margin: 0;
}
.eyebrow--plain { color: var(--cc-ink-3); }

.secnum { font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label); color: var(--cc-ink-3); }

/* section header block */
.sec-head { margin-bottom: 72px; }
.sec-head__main { max-width: var(--measure); }
h1, h2, h3, h4 { margin: 0; font-weight: var(--fw-semibold); letter-spacing: var(--tr-heading); line-height: var(--lh-heading); }

.h-display { font-size: var(--fs-h2-sm); font-weight: var(--fw-bold);
  letter-spacing: var(--tr-display); line-height: var(--lh-display); }
.h2 { font-size: var(--fs-h2); font-weight: var(--fw-bold); margin-top: 22px;
  letter-spacing: var(--tr-display); line-height: var(--lh-display); text-wrap: balance; }
.h2--md { font-size: var(--fs-h2-md); }
.h2--sm { font-size: var(--fs-h2-sm); }
.h2--xs { font-size: var(--fs-h2-xs); }
.h3 { font-size: var(--fs-h3); font-weight: var(--fw-bold); letter-spacing: var(--tr-display); line-height: 1.08; }

/* MEGA band statements — centred, uppercase, over media only */
.h-mega {
  font-family: var(--font-mega); font-weight: var(--mega-weight); text-transform: uppercase;
  font-size: var(--fs-mega); line-height: var(--lh-mega); letter-spacing: var(--tr-mega);
  text-align: center; margin: 0;
}
.h-mega--sm { font-size: var(--fs-mega-sm); }

/* Display type over media gets a plain drop shadow (no emboss highlight).
   Hero adds a longer halo so the H1 holds over an open plate. */
.h-mega { text-shadow: var(--shadow-display); }
.hero h1 { text-shadow: none; }
.hero__li {
  filter:
    drop-shadow(0 2px 6px rgba(5,6,7,0.45))
    drop-shadow(0 10px 28px rgba(5,6,7,0.38));
}

.lede { font-size: var(--fs-lede); line-height: var(--lh-lede); color: var(--cc-ink-2); max-width: 60ch; }

/* Selective emphasis. Body copy carries `**phrase**` markers in lang/*.php,
   rendered as <strong> by the $md helper (app/Core/View.php), so a reader can
   scan a section and pick up the load-bearing claim without reading it. It is
   one weight step plus the ink step the paragraph gave up (body copy sits at
   --cc-ink-body / --cc-ink-2), never a colour: brand red on an inline phrase
   reads as a link, and a second accent per paragraph would break the <5% ink
   budget the accent is reserved for. Two emphasised phrases per paragraph is
   the ceiling; past that nothing stands out. */
p strong, li strong, dd strong { font-weight: var(--fw-semibold); color: var(--cc-ink); }
/* The FAQ's direct-answer lead is already set semibold as a whole, so emphasis
   inside it has to step again to register. */
.faq__lead strong, .qa__lead strong { font-weight: var(--fw-bold); }

/* Wrapping. Two different problems, two different values:
   - `balance` on short display type (<= ~4 lines), where the browser evens the
     lines out and no line is left carrying one word.
   - `pretty` on running copy, which only reworks the LAST few lines, so it
     clears widows and stranded short words without re-flowing the paragraph
     (and without `balance`'s line cap, which silently gives up on long text).
   Engines that support neither ignore both and wrap greedily, as before. */
.h3, .h-mega, .mcard__title, .cred-card__title, .feat__title, .variant__name,
.faq__q .qt, .qa__q, .next-cta__note, .gate__meta, .footer__col-t,
.spec-head__cta, .apphero h1 { text-wrap: balance; }
.lede, .cap__desc, .mcard__desc, .mcard__meta, .cred-card__body, .spec-head__note,
.feat__desc, .variant__desc, .faq__lead, .faq__rest, .qa__a, .qa__lead, .qa__rest,
.config__body, .next-cta__sub, .footer__blurb, .appintro__note, .hero__sub,
.prose-block__body p, .prose p, .hint, .figures__l, .muted { text-wrap: pretty; }

/* Over media the muted steps do not survive: lift every ink one stop so each
   text-over-media zone keeps >= 4.5:1 whatever the frame underneath. */
.hero .eyebrow, .apphero .crumbs { color: var(--cc-ink-2); }
/* Band eyebrows sit high in the frame, where the scrim is still opening and the
   plate can be bright sky: measured 4.33:1 at ink-2 over the ridge photograph,
   so they take one more stop (5.25:1). */
.media-band .eyebrow { color: rgba(243,245,247,0.82); }
.muted { color: var(--cc-ink-2); }

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-15);
  /* Explicit line-height: <a> inherits the body's while <button> gets the UA's
     'normal', which rendered same-class buttons 59px vs 61px tall. */
  line-height: 1.25;
  padding: 15px 24px; border-radius: var(--r-sharp); border: 1px solid transparent;
  cursor: pointer; letter-spacing: 0.01em; white-space: nowrap;
  transition: background-color var(--dur-2), border-color var(--dur-2), color var(--dur-2), transform 80ms;
}
.btn svg { width: 16px; height: 16px; }
.btn--primary { background: var(--acc); color: var(--btn-fg); border-color: var(--acc); }
.btn--primary:hover { background: var(--acc-hover); border-color: var(--acc-hover); }
.btn--primary:active { background: var(--acc-press); border-color: var(--acc-press); transform: scale(.99); }
/* Glass ghost: legible over media without becoming a second solid button. */
.btn--ghost {
  background: rgba(5,6,7,0.30); color: var(--cc-ink);
  border-color: rgba(243,245,247,0.35);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.btn--ghost:hover { border-color: rgba(243,245,247,0.70); background: rgba(243,245,247,0.06); }
.btn--ghost:active { transform: scale(.99); }
.btn--sm { padding: 10px 15px; font-size: var(--fs-12); }
.btn--lg { padding: 17px 28px; font-size: var(--fs-16); }
.btn--block { width: 100%; }
.btn[disabled] { opacity: .4; cursor: not-allowed; }

/* Used on both <a> and <button> (e.g. #backStep1): reset button chrome so the
   UA default (white pill) never shows through. */
.link-arrow {
  display: inline-flex; align-items: center; gap: 9px;
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--font-mono); font-size: var(--fs-12); letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--acc-hi); font-weight: var(--fw-medium);
  transition: gap var(--dur-2) var(--ease-out), color var(--dur-2);
}
.link-arrow:hover { gap: 13px; }

/* ============================================================
   HEADER — floats transparent over the hero media, then condenses
   ============================================================ */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 80;
  background: transparent; border-bottom: 1px solid transparent;
  transition: background-color var(--dur-3) var(--ease-io), border-color var(--dur-3) var(--ease-io),
              -webkit-backdrop-filter var(--dur-3), backdrop-filter var(--dur-3);
}
/* Scrolled state: a quiet bar, so nav + CTA survive a long page. */
.nav.is-stuck {
  background: rgba(5,6,7,0.72);
  -webkit-backdrop-filter: saturate(150%) blur(14px); backdrop-filter: saturate(150%) blur(14px);
  border-bottom-color: var(--cc-line);
}
.nav__in { width: 100%; height: var(--nav-h); padding: 0 var(--gutter);
  display: flex; align-items: center; gap: 36px; }
.brand { display: flex; align-items: center; gap: 12px; }
.brand__mark { width: 26px; height: 26px; }
.brand__word { font-family: var(--font-brand); font-weight: var(--fw-bold); font-size: 25px;
  letter-spacing: 0.01em; line-height: 1; text-transform: lowercase; }
/* By-line: one line — "by helvetis" + round Swiss flag (provenance mark). */
.brand__by { display: flex; align-items: center; gap: 8px; padding-left: 14px; margin-left: 2px;
  border-left: 1px solid var(--cc-line-strong); }
.brand__by-txt { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--cc-ink-3); line-height: 1; }
.brand__by .brand__helvetis { font-family: var(--font-brand); font-weight: var(--fw-bold);
  font-size: 14px; line-height: 1; letter-spacing: 0.01em; color: var(--cc-ink);
  text-transform: lowercase; opacity: .92; }
.brand__flag { width: 13px; height: 13px; flex-shrink: 0; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(243, 245, 247, 0.14); }

.nav__links { display: flex; align-items: center; gap: 0; margin-left: auto; }
.nav__links a { font-size: var(--fs-15); color: var(--cc-ink-2); transition: color var(--dur-1);
  padding: 12px 17px; position: relative; }
.nav__links a:hover, .nav__links a.active { color: var(--cc-ink); }
/* Subtle hairline separator between menu items. */
.nav__links a + a::before { content: ""; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%); width: 1px; height: 13px; background: var(--cc-line-strong); }

/* Language: plain text, red underline on the active locale. */
.lang { display: flex; align-items: center; gap: 14px; font-family: var(--font-mono);
  font-size: var(--fs-mono); letter-spacing: 0.1em; }
.lang a, .lang button { background: none; border: 0; padding: 4px 0; cursor: pointer;
  /* font: inherit matters: <button> does not inherit font by default, so the
     header's "EN" rendered at the UA's 13.33px serif metrics. */
  font: inherit; letter-spacing: inherit;
  color: var(--cc-ink-3); text-transform: uppercase; border-bottom: 1px solid transparent;
  transition: color var(--dur-1), border-color var(--dur-1); }
.lang a:hover, .lang button:hover { color: var(--cc-ink); }
.lang .on, .lang a[aria-current] { color: var(--cc-ink); border-bottom-color: var(--acc); }

/* Header language menu (2026-07-16 review): globe button, dropdown list.
   Opens on hover / keyboard focus via CSS; app.js adds click toggle (.open). */
.lang--menu { position: relative; }
.lang--menu .lang__btn { display: inline-flex; align-items: center; gap: 7px;
  border: 1px solid var(--cc-line-strong); border-radius: var(--r-pill);
  padding: 7px 12px; color: var(--cc-ink-2); }
.lang--menu .lang__btn:hover, .lang--menu.open .lang__btn { color: var(--cc-ink); border-color: var(--cc-mark); }
.lang__btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.lang__btn .lang__chev { width: 10px; height: 10px; transition: transform var(--dur-1); }
.lang--menu:hover .lang__chev, .lang--menu.open .lang__chev { transform: rotate(180deg); }
.lang__list { position: absolute; top: 100%; right: 0; padding: 8px; margin: 6px 0 0;
  min-width: 150px; list-style: none; background: var(--cc-panel);
  border: 1px solid var(--cc-line-strong); border-radius: var(--r-sharp);
  display: none; z-index: 60; }
/* Bridge the hover gap between button and list so the menu does not flicker. */
.lang__list::before { content: ""; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
.lang--menu:hover .lang__list, .lang--menu:focus-within .lang__list,
.lang--menu.open .lang__list { display: block; }
.lang__list a { display: block; padding: 10px 12px; border-bottom: 0;
  font-size: 12px; letter-spacing: 0.04em; text-transform: none; color: var(--cc-ink-2); }
.lang__list a:hover { color: var(--cc-ink); background: var(--cc-panel-2); }
.lang__list a[aria-current] { color: var(--cc-ink); border-left: 2px solid var(--acc);
  border-bottom: 0; padding-left: 10px; }

.nav__cta { display: flex; align-items: center; gap: 18px; }
.burger { display: none; background: none; border: 0; width: 44px; height: 44px; cursor: pointer;
  align-items: center; justify-content: center; color: var(--cc-ink); }

/* ============================================================
   HERO — full-viewport media, statement bottom-left
   ============================================================ */
/* Viewport-height (the 900px artboard IS the full viewport at 1440x900); svh so
   mobile browser chrome cannot crop the CTA pair. */
.hero { position: relative; height: 100svh; min-height: 560px; max-height: 1040px;
  overflow: hidden; display: flex; flex-direction: column; }
.hero__media { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; background: var(--cc-bg); }
.hero__media .media { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__scrim { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--scrim-hero); }
/* Phones: the statement climbs into the mid-frame, so the well starts earlier
   than desktop. Still no trough — the aircraft has to read. */
@media (max-width: 768px) {
  .hero__scrim { background: var(--scrim-hero-mobile); }
}

.hero__in { position: relative; z-index: 3; flex: 1; width: 100%;
  padding: var(--nav-h) var(--gutter) 72px;
  display: flex; flex-direction: column; justify-content: flex-end; }
.hero__main { width: 100%; }
.hero__body { max-width: none; }
/* Two engineered lines (2026-07 bolder pass): each i18n segment owns its block,
   so the keyword phrase never breaks mid-phrase and each block can take the
   masked entrance. max-width goes: the segments ARE the measure now. */
.hero h1 { font-size: var(--fs-hero); font-weight: var(--fw-bold); line-height: var(--lh-hero);
  letter-spacing: var(--tr-hero); max-width: none; margin-top: 0; }
/* overflow:hidden masks the reveal. Side/top pad gives the display halo room
   so it does not clip to the line box. Bottom 0.18em is for descenders (g, y);
   the negative margin cancels that pad BETWEEN lines. After the entrance,
   overflow goes visible so the bloom is not a hard rectangle. */
.hero__line { display: block; overflow: visible; padding: 32px 40px 0.18em; margin: -32px -40px 0; }
.hero__line:not(:last-child) { margin-bottom: calc(-32px - 0.18em); }
.hero__li { display: block; text-wrap: balance; }
/* The value clause carries the brand accent, tying the headline to the CTA and
   giving the two-line H1 a deliberate two-tone hierarchy. Flat colour (not a
   background-clip:text gradient) so glyph descenders fill fully — bg-clip only
   paints ink inside the element box and would shave the y/g tails. */
.hero h1 em { font-style: normal; color: var(--acc-hi); }
/* CTA pair (left) + sub-paragraph (right) share the closing row. */
.hero__foot { display: flex; align-items: flex-end; justify-content: space-between; gap: 48px; margin-top: 44px; }
.hero__cta { display: flex; gap: 12px; flex-wrap: wrap; }
.hero__sub { margin: 0; max-width: 42ch; text-align: right; font-size: 17px;
  line-height: var(--lh-body); color: rgba(243,245,247,0.90);
  text-shadow: 0 1px 14px rgba(5,6,7,0.70); }

/* telemetry line — at most one per band */
.telem { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-2); display: inline-flex; align-items: center; gap: 12px; }
.dot { width: 7px; height: 7px; border-radius: var(--r-pill); background: var(--acc);
  box-shadow: 0 0 10px var(--acc); animation: pulse 2.4s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* ============================================================
   FIGURES STRIP — quiet band under the hero
   ============================================================ */
.figures { padding: 44px var(--gutter); border-bottom: 1px solid var(--cc-line); }
/* An instrument panel, so the cells sit on a GRID at every width. A centred
   flex-wrap was ragged once the spans made the values wider: five items wrapped
   3 + 2 with the second row floating under the gap in the first and the right
   half of the band empty. Grid keeps the cells in columns instead. */
.figures__in { margin: 0; display: grid; grid-template-columns: repeat(5, auto);
  justify-content: center; align-items: start; gap: 28px clamp(36px, 4vw, 88px); text-align: center; }
.figures__i { display: flex; flex-direction: column; gap: 8px; }
/* margin: 0 kills the UA's 40px <dd> indent, which pushed every value's centre
   20px right of its label. The variant cards reset their dds; this one must too. */
/* nowrap because every cell is a SPAN ("170 to 850 km"): left to wrap, the unit
   or the second bound drops to its own line and the figure stops reading as one
   value. The cell count steps down at the breakpoints below instead. */
.figures__v { margin: 0; font-size: 28px; font-weight: var(--fw-semibold); letter-spacing: -0.02em;
  line-height: 1; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* line-height:1 aligns the BOXES, not the glyphs: cap-only values ("E · EX · X")
   have a shorter ink height than digits, and a descender ("kg") reaches ~6px
   lower, so the gap down to each label varied per cell. Trimming the box to cap
   height and the alphabetic baseline makes every value optically identical.
   Older engines keep the untrimmed box, which is the current behaviour. */
@supports (text-box: trim-both cap alphabetic) {
  .figures__v { text-box: trim-both cap alphabetic; }
  .figures__i { gap: 12px; }
}
.figures__l { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tr-label);
  text-transform: uppercase; color: var(--cc-ink-3); }
/* Narrow desktop: step the value size and gap down together so five spans stay
   on one line, rather than orphaning the fifth. Must follow the base rules. */
@media (max-width: 1150px) {
  .figures__in { gap: 24px clamp(26px, 3.2vw, 40px); }
  .figures__v { font-size: 24px; }
}
/* Below ~1020px five cells would need sub-25px gaps to hold one line, which reads
   as cramped rather than composed (1024 misses a single row by one pixel). Two
   even columns instead: the four numeric figures form a 2 x 2 block and the
   variants cell, which is the key to them, spans the full width beneath. */
@media (max-width: 1020px) {
  .figures__in { grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 520px; margin-inline: auto; gap: 32px 40px; }
  .figures__i:last-child { grid-column: 1 / -1; }
}
/* Phones: two columns would clip the widest value, so one figure per line. */
@media (max-width: 480px) {
  .figures__in { grid-template-columns: minmax(0, 1fr); max-width: none; row-gap: 28px; }
}

/* ============================================================
   CONTENT BLOCKS — a top rule, never a box
   ============================================================ */
.cap-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 48px;
  list-style: none; margin-block: 0; padding: 0; border: 0; }
.cap-grid--3 { grid-template-columns: repeat(3, 1fr); gap: 48px 64px; }
.cap {
  border-top: 1px solid var(--cc-line-strong); padding: 24px 0 0;
  display: flex; flex-direction: column; background: none;
}
.cap--acc { border-top-color: var(--acc); }
.cap__n { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label);
  color: var(--cc-ink-3); margin: 0 0 14px; }
.cap__title, .cap__title--sm { text-wrap: balance; font-size: var(--fs-block); font-weight: var(--fw-semibold);
  letter-spacing: 0; line-height: var(--lh-block); margin: 0; }
.cap__desc { margin: 12px 0 0; font-size: var(--fs-body); color: var(--cc-ink-body); line-height: var(--lh-body); }
/* Payload cards with a technical-illustration slot: faint engineering grid
   behind a transparent line drawing, then title and copy. */
.cap__ill { margin: 18px 0 22px; aspect-ratio: 4 / 3; display: flex; align-items: center;
  justify-content: center; padding: 18px; background:
    repeating-linear-gradient(0deg,   transparent 0 27px, rgba(243, 245, 247, 0.035) 27px 28px),
    repeating-linear-gradient(90deg,  transparent 0 27px, rgba(243, 245, 247, 0.035) 27px 28px),
    var(--cc-panel);
  border: 1px solid var(--cc-line); border-radius: var(--r-sharp); overflow: hidden; }
.cap__ill picture { width: 100%; height: 100%; display: block; }
.cap__ill img { width: 100%; height: 100%; object-fit: contain;
  /* Drawings ship on pure black; lighten lets the panel + grid read through. */
  mix-blend-mode: lighten;
  transition: transform 0.6s cubic-bezier(0.2, 0.6, 0.2, 1); }
.cap--ill:hover .cap__ill img { transform: scale(1.05); }
@media (prefers-reduced-motion: reduce) { .cap--ill:hover .cap__ill img { transform: none; } }

/* ============================================================
   FULL-BLEED MEDIA BANDS — frameless; the page black is the frame
   ============================================================ */
.bleed { padding: 0; border: 0; }
.media-band { position: relative; width: 100%; min-height: var(--band-h); overflow: hidden;
  display: flex; align-items: center; justify-content: center; }
.media-band--short { min-height: var(--band-h-short); }
.media-band--head { min-height: 760px; align-items: flex-end; justify-content: flex-start; }
/* VTOL band: copy anchored bottom-left at a deliberately SMALL size so the
   centred aircraft in the footage stays unobstructed; app.js glides it in
   from the centre, shrinking as it settles (transform-origin bottom-left).
   width: fit-content is load-bearing — as a full-width block the copy's box
   is "centred" already and the glide measures ~0px (2026-07-16 review fix). */
.media-band--vtol { align-items: flex-end; justify-content: flex-start; }
/* VTOL band (2026-07 audit): the legibility work moves from the scrim to the
   type, so the take-off footage stays visible. Light wash only; every text
   block in the band carries its own shadow instead. */
.media-band--vtol .media-band__scrim { background: linear-gradient(180deg,
  rgba(5,6,7,0.40) 0%, rgba(5,6,7,0.12) 30%, rgba(5,6,7,0.28) 68%, rgba(5,6,7,0.86) 100%); }
.media-band--vtol .media-band__copy { text-shadow: 0 1px 4px rgba(0,0,0,0.75), 0 4px 24px rgba(0,0,0,0.55); }
/* The lede is the smallest text over the lightest scrim zone: brighter ink and
   a tighter core shadow carry it at worst-case pixels. */
.media-band--vtol .media-band__copy .lede { color: rgba(243,245,247,0.92);
  text-shadow: 0 1px 3px rgba(0,0,0,0.85), 0 2px 14px rgba(0,0,0,0.6); }
.media-band--vtol .media-band__copy { text-align: left; margin: 0; width: fit-content;
  will-change: transform; transform-origin: left bottom; }
.media-band--vtol .h-mega { font-size: clamp(2rem, 4.6vw, 4.25rem); line-height: 0.92; }
.media-band--vtol .media-band__copy .lede { margin: 18px 0 0; max-width: 40ch;
  font-size: var(--fs-15); }
.media-band .media { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Payloads band: the thermal feed is taller than the window so JS can slide
   it behind the heading (real parallax, not a 20px nudge). */
.media-band.media-band--head .media {
  inset: auto; top: -22%; left: 0; width: 100%; height: 144%;
  will-change: transform;
}
.media-band--head .media-band__in { will-change: transform; }
@media (prefers-reduced-motion: reduce) {
  .media-band.media-band--head .media { top: 0; height: 100%; will-change: auto; }
  .media-band--head .media-band__in { will-change: auto; }
}
.media-band__scrim { position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--scrim-band); }
/* one telemetry line, top-left */
.media-band__top { position: absolute; z-index: 3; top: 40px; left: var(--gutter); right: var(--gutter); }
.media-band__in { position: relative; z-index: 3; width: 100%; padding: var(--gutter); }
/* Corner label: a band eyebrow anchored top-left, where the band scrim is
   darkest, instead of floating over the image subject. */
.media-band__tag { position: absolute; top: var(--gutter); left: var(--gutter); z-index: 3;
  margin: 0; color: var(--cc-ink-2); }
/* The statement needs the full band width (a ch cap here would resolve against
   the container's 16px and wrap the MEGA type mid-word); the lede is capped. */
.media-band__copy { max-width: none; margin: 0 auto; text-align: center; }
.media-band__copy .eyebrow { margin-bottom: 26px; }
.media-band__copy .lede { color: rgba(243,245,247,0.80); margin: 30px auto 0; max-width: 48ch; }
/* header-over-media variant (payloads): bottom-left, not centred */
.media-band--head .media-band__copy { max-width: var(--measure); margin: 0; text-align: left; }
.media-band--head .media-band__copy .lede { margin-left: 0; margin-right: 0; }

/* ============================================================
   SPECIFICATIONS — two-speed: variant summary + full comparison
   ============================================================ */
.spec-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 64px; margin-bottom: 72px; }
/* Cap the measure so the line breaks at a word space, never inside "fixed-wing"
   ("...the Jabali fixed- / wing VTOL drones" read as a typo). */
.spec-head .h2 { max-width: 21ch; }
.spec-head__side { max-width: 38ch; }
.spec-head__note { max-width: 38ch; margin: 0; font-size: var(--fs-body); line-height: var(--lh-body); color: var(--cc-ink-2); }
.spec-head__cta { margin: 26px 0 0; }

/* Plan-view drawing. Line art on black, so it needs no frame; capped so it
   reads as a technical mark, not a photograph. The drawings are alpha
   PNG/WebP (white ink, no background), so they sit directly on the page
   black with no rectangle edge and no blend trickery. */
.variant__plan img { display: block; width: 100%; max-width: 236px; height: auto; }
.variant--acc { border-top-color: var(--acc); }
.variant__top { display: flex; align-items: center; gap: 12px; }
.variant__name { font-size: 30px; font-weight: var(--fw-bold); letter-spacing: var(--tr-tile); line-height: 1; margin: 0; }
.powerbadge { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-mono);
  font-size: 11px; letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--cc-ink-3);
  border: 1px solid var(--cc-line-strong); border-radius: var(--r-pill); padding: 4px 9px; }
.powerbadge svg { width: 11px; height: 11px; flex-shrink: 0; }
/* Power-source colour coding: battery electric vs hybrid fuel. */
.powerbadge--electric { color: var(--power-electric); border-color: color-mix(in srgb, var(--power-electric) 40%, transparent); }
.powerbadge--hybrid   { color: var(--power-fuel);     border-color: color-mix(in srgb, var(--power-fuel) 40%, transparent); }
.variant__desc { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); margin: 16px 0 0; }
.variant__u { font-family: var(--font-mono); font-size: var(--fs-12); font-weight: var(--fw-regular);
  color: var(--cc-ink-3); margin-left: 5px; letter-spacing: 0; }

/* Plans, identity and figures share three equal columns.
   Parameter name lives in each cell, to the right of the value. */
.spectable-plans { display: grid; grid-template-columns: repeat(3, 1fr);
  align-items: end; justify-items: center; margin: 0 0 28px; }
.spectable-plans .variant__plan { margin: 0; padding: 24px 16px 0; width: 100%;
  display: flex; justify-content: center;
  border-top: 1px solid var(--cc-line-strong); }
.spectable-plans .variant__plan--electric { border-top-color: var(--power-electric); }
.spectable-plans .variant__plan--hybrid { border-top-color: var(--power-fuel); }
.spectable-plans .variant__plan img { margin-inline: auto; }
.spectable-fold { position: relative; margin-top: 0; }
.spectable-fold__s { display: none; width: 100%; height: 56px; margin: 0; padding: 0;
  background: none; border: 0; cursor: pointer; color: var(--cc-ink-2);
  align-items: center; justify-content: center; }
.js .spectable-fold__s { display: flex; }
.spectable-fold__disc { width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--cc-ink) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--cc-ink) 16%, transparent);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  transition: background var(--dur-2) var(--ease-out), transform var(--dur-3) var(--ease-out); }
.spectable-fold__s:hover { color: var(--cc-ink); }
.spectable-fold__s:hover .spectable-fold__disc {
  background: color-mix(in srgb, var(--cc-ink) 14%, transparent);
  transform: scale(1.06); }
.spectable-fold__chev { width: 18px; height: 18px; display: block;
  transition: transform var(--dur-3) var(--ease-out); }
.spectable-fold__s[aria-expanded="true"] .spectable-fold__chev { transform: rotate(180deg); }
.spectable-wrap { margin: 0; padding: 0; --spectable-peek: 28rem; }
.js .spectable-fold .spectable-wrap { max-height: var(--spectable-peek); overflow: hidden;
  transition: max-height 560ms var(--ease-out); }
.js .spectable-fold:not(.is-open) .spectable thead th { position: static; }
.js .spectable-fold::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 13rem; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom, transparent 0%, var(--cc-bg) 70%);
  opacity: 1; transition: opacity 560ms var(--ease-out); }
.js .spectable-fold:has([aria-expanded="true"])::after { opacity: 0; }
.js .spectable-fold:not(.is-open) .spectable-fold__s { position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 2; height: 13rem; transform: none; align-items: flex-end; padding-bottom: 18px; }
.js .spectable-fold.is-open .spectable-fold__s { position: static; transform: none; margin-top: 12px;
  height: 56px; align-items: center; padding-bottom: 0; }
.js .spectable-fold.is-open .spectable-wrap { overflow: visible; max-height: none; }
.spectable { width: 100%; table-layout: fixed; border-collapse: collapse;
  font-variant-numeric: tabular-nums; }
.spectable th, .spectable td { padding: 14px 16px; vertical-align: middle; min-width: 0; }
.spectable thead th { position: sticky; top: var(--nav-h); z-index: 4;
  background: var(--cc-bg); padding-top: 4px; padding-bottom: 20px;
  border-bottom: 1px solid var(--cc-line-strong); text-align: center; font-weight: var(--fw-regular); }
.spectable-id { padding-top: 0; }
.spectable-id .variant__top { justify-content: center; }
.spectable-id .variant__name { font-size: 30px; }
.spectable-id .variant__desc { margin-top: 8px; text-align: center; }
.spectable tbody td { font-weight: var(--fw-semibold);
  line-height: var(--lh-data); letter-spacing: -0.02em; color: var(--cc-ink); }
.spectable tbody td .variant__u { font-family: var(--font-mono); font-size: var(--fs-12); font-weight: var(--fw-regular);
  color: var(--cc-ink-3); margin: 0; letter-spacing: 0; }
.spectable__pair { display: grid; grid-template-columns: 1fr 1fr; column-gap: 8px;
  align-items: baseline; }
.spectable__v { text-align: right; font-size: 1.5rem; }
.spectable__meta { display: grid; grid-template-columns: 3.75em 1fr; column-gap: 8px;
  align-items: baseline; text-align: left; min-width: 0; }
.spectable__k { text-align: left; font-family: var(--font-mono); font-size: 10px; font-weight: var(--fw-regular);
  letter-spacing: var(--tr-label-2); text-transform: uppercase; color: var(--cc-ink-3); }
.spectable tbody tr:nth-child(odd) > * { background: rgba(243,245,247,0.045); }
.spectable tbody tr:nth-child(even) > * { background: rgba(243,245,247,0.02); }
.spectable tbody td { border-top: 1px solid var(--cc-line);
  transition: background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out); }
.spectable__k { transition: color var(--dur-2) var(--ease-out); }
@media (hover: hover) {
  .spectable tbody tr:hover > * {
    background-color: color-mix(in srgb, var(--acc) 5%, transparent);
    background-image: linear-gradient(var(--acc-line), var(--acc-line));
    background-size: 100% 1px;
    background-repeat: no-repeat;
    background-position: top left;
  }
  .spectable tbody tr:hover .spectable__k {
    color: var(--acc-hi);
  }
}
.spectable-cta { margin: 28px 0 8px; padding-top: 28px; border-top: 1px solid var(--cc-line-strong);
  display: flex; justify-content: center; }
.cmp-todo { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: 0.08em;
  color: var(--acc-hi); border: 1px dashed var(--acc-line); border-radius: var(--r-sharp); padding: 2px 7px; }

/* mobile variant switcher — hidden on desktop, where all three read side by side */
.vswitch { display: none; margin-bottom: 32px; border: 1px solid var(--cc-line-strong); border-radius: var(--r-sharp); overflow: hidden; }
.vswitch__b { flex: 1; background: none; border: 0; border-left: 1px solid var(--cc-line-strong);
  color: var(--cc-ink-2); font-family: var(--font-mono); font-size: var(--fs-12); letter-spacing: 0.06em;
  padding: 0 8px; min-height: 44px; cursor: pointer; transition: background var(--dur-2), color var(--dur-2); }
.vswitch__b:first-child { border-left: 0; }
.vswitch__b.on { background: var(--acc); color: var(--btn-fg); }

/* Fine print closes the data block; the gap below it separates data from the
   gallery. Sibling margins collapse, so this single value owns the whole gap. */
.specs__note { margin: 44px 0 0; }
/* studio photography under the data */
.spec-shot { margin-top: 96px; }
.spec-shot img { width: 100%; height: 720px; object-fit: cover; }
.spec-crops { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; margin-top: 24px; }
.spec-crops img { width: 100%; height: 420px; object-fit: cover; }
/* Gallery hover: a slow, quiet zoom on the studio photography. */
.spec-shot, .spec-crops picture, .sec-media { overflow: hidden; display: block; }
.spec-shot img, .spec-crops img, .sec-media img { transition: transform 0.8s cubic-bezier(0.2, 0.6, 0.2, 1); }
.spec-shot:hover img, .spec-crops picture:hover img, .sec-media:hover img { transform: scale(1.05); }
@media (prefers-reduced-motion: reduce) {
  .spec-shot img, .spec-crops img, .sec-media img { transition: none; }
  .spec-shot:hover img, .spec-crops picture:hover img, .sec-media:hover img { transform: none; }
}

/* ============================================================
   APPLICATIONS — full-bleed clickable image tiles
   ============================================================ */
.mgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px;
  background: var(--cc-bg); border: 0; list-style: none; margin-block: 0; padding: 0; }
.mcard { position: relative; aspect-ratio: 16 / 10; overflow: hidden; padding: 0; border: 0;
  display: flex; align-items: flex-end; }
/* Resource links: bordered learn-more buttons for pillar/spoke resources. */
.res-links { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 30px; }
/* Applications intro: ISR paragraph left, labelled resource column right. */
.app-intro { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 40px 64px; align-items: start; margin-top: 34px; }
.app-intro .lede { max-width: 62ch; }
.res-links--stack { flex-direction: column; margin-top: 14px; }
.res-links--stack .res-link { justify-content: space-between; gap: 16px; }
@media (max-width: 900px) {
  .app-intro { grid-template-columns: minmax(0, 1fr); gap: 32px; }
}
.res-link { display: inline-flex; align-items: center; gap: 10px; padding: 15px 22px;
  border: 1px solid var(--cc-line-strong); border-radius: var(--r-sharp);
  font-size: var(--fs-15); color: var(--cc-ink-2);
  transition: color var(--dur-1), border-color var(--dur-1), background var(--dur-1); }
.res-link svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--acc-hi);
  transition: transform var(--dur-1); }
.res-link:hover { color: var(--cc-ink); border-color: var(--acc-line); background: var(--cc-panel); }
.res-link:hover svg { transform: translateX(3px); }
/* Grid variant (sub-pages): uniform button widths, arrow pinned right. */
.res-links--grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.res-links--grid .res-link { justify-content: space-between; gap: 16px; }
.res-links--grid .res-link span { min-width: 0; }

.mcard__media { position: absolute; inset: 0; margin: 0; border: 0; z-index: 0; }
.mcard__media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: auto;
  transition: transform var(--dur-4) var(--ease-out); }
.mcard:hover .mcard__media img { transform: scale(1.02); }
.mcard::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--scrim-tile); }
.mcard__body { position: relative; z-index: 2; padding: 40px; width: 100%; }
/* Sits highest in the overlay, where the scrim is still opening, so it is
   lifted well past the muted step it would use on black (measured, not guessed). */
.mcard__meta { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: rgba(243,245,247,0.86); margin: 0 0 18px; }
.mcard__title { font-size: var(--fs-tile); font-weight: var(--fw-semibold); letter-spacing: var(--tr-tile);
  line-height: var(--lh-tile); margin: 0; }
.mcard__title a { color: inherit; }
.mcard__link::after { content: ""; position: absolute; inset: 0; z-index: 3; }
.mcard:hover .mcard__title a { color: #fff; }
.mcard__desc { margin: 14px 0 0; font-size: var(--fs-body); color: var(--cc-ink-2);
  line-height: var(--lh-body); max-width: 52ch; }
.mcard__cta { margin: 22px 0 0; }
/* Stretched link (2026-07 audit): the title anchor was a 38px-tall target; the
   pseudo-element makes the whole tile tappable without changing the markup. */
.mcard { position: relative; }
.mcard__link::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.mcard__link:focus-visible { outline: none; }
.mcard:has(.mcard__link:focus-visible) { box-shadow: var(--shadow-focus); }
/* The whole tile is the link, so the arrow reacts to the tile's hover. */
.mcard:hover .link-arrow { gap: 13px; }

/* ============================================================
   CREDIBILITY — photo / panel split
   ============================================================ */
.cred-split { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
/* The portrait plate is 2:3, so left to itself it dictates a very tall row.
   Pinning the image inside the cell makes the COPY set the height instead. */
.cred-split__media { position: relative; margin: 0; height: 100%; min-height: 0; overflow: hidden; }
.cred-split__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cred-split__panel { background: var(--cc-panel); padding: 96px 64px; }
.cred-entries { margin-top: 64px; display: flex; flex-direction: column; gap: 44px; }
.cred-card { border-top: 1px solid var(--cc-line-strong); padding: 24px 0 0; background: none; }
.cred-card__label { font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--cc-ink-3); margin: 0 0 14px; }
.cred-card__title { font-size: var(--fs-block); font-weight: var(--fw-semibold); line-height: var(--lh-block); margin: 0; }
.cred-card__body { margin: 12px 0 0; font-size: var(--fs-body); color: var(--cc-ink-body); line-height: var(--lh-body); }

/* ============================================================
   IN-SECTION MEDIA
   ============================================================ */
.sec-media { margin: 64px 0 0; position: relative; }
.sec-media img, .sec-media video { display: block; width: 100%; height: 640px; object-fit: cover; border: 0; }
.sec-media figcaption { font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label-2); text-transform: uppercase; color: var(--cc-ink-3); margin-top: 12px; }

/* ============================================================
   FORMS — panels are for forms only
   ============================================================ */
.panel { background: var(--cc-panel); border: 1px solid var(--cc-line); border-radius: var(--r-sharp); box-shadow: none; }
/* Next-step CTA: the primary conversion panel. Accent hairline, a soft red
   glow behind the action, section-scale breathing room above and below. */
.next-cta { margin: calc(var(--section-y) * 0.66) 0; padding: 56px 60px;
  display: flex; align-items: center; justify-content: space-between; gap: 48px;
  flex-wrap: wrap; position: relative; overflow: hidden;
  border-color: var(--acc-line);
  background:
    radial-gradient(560px 240px at 88% 60%, var(--acc-tint), transparent 72%),
    var(--cc-panel); }
/* Homepage: the panel closes Applications. Match the air below it to the
   space above it, instead of stacking the panel margin on .sec padding. */
#applications { padding-bottom: calc(var(--section-y) * 0.66); }
#applications .next-cta { margin-bottom: 0; }
.next-cta__copy { max-width: 54ch; }
.next-cta__label { margin: 0 0 14px; font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--acc-hi); }
.next-cta__label::before { content: ""; display: inline-block; width: 22px; height: 1px;
  background: var(--acc); vertical-align: middle; margin-right: 12px; }
.next-cta__note { margin: 0; font-size: var(--fs-lede); line-height: var(--lh-lede);
  color: var(--cc-ink); font-weight: var(--fw-medium, 500); max-width: 44ch;
  white-space: pre-line; }
.next-cta .btn { flex-shrink: 0; }
.next-cta__sub { margin: 12px 0 0; font-size: var(--fs-15); line-height: var(--lh-body);
  color: var(--cc-ink-2); max-width: 50ch; white-space: pre-line; }
.next-cta__actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; flex-shrink: 0; }
@media (max-width: 720px) {
  .next-cta { padding: 40px 28px; }
  /* The descriptive per-page CTAs ("Discuss your <mission>") run long, and FR/ES
     expand them ~20% further; on a phone the fixed nowrap button overshot the
     panel. Full-width stacked buttons that wrap their own label hold any
     language. Scoped to this block so the short global .btn stays nowrap. */
  .next-cta__actions { width: 100%; align-items: stretch; }
  .next-cta__actions .btn { width: 100%; white-space: normal; text-align: center; }
}

.field { display: flex; flex-direction: column; gap: 10px; position: relative; }
.identity { display: flex; flex-direction: column; gap: 16px; }
/* Inline legal links inside form fine print: same visual size, but the box is
   padded out (and margin-compensated) so the tap target clears 44px. */
.lbl a { display: inline-block; padding: 14px 4px; margin: -14px -4px; }
.field label, .lbl, .lbl-field { font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label-2); text-transform: uppercase; color: var(--cc-ink-3); }
.field-opt { font-family: var(--font-mono); font-size: 0.625rem; font-weight: var(--fw-medium);
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--cc-ink-4); pointer-events: none; }
.lbl-field .field-opt { margin-left: 0.55em; vertical-align: 0.08em; }
.field__box { position: relative; display: block; }
.field__box .field-opt { position: absolute; right: 16px; top: 50%; transform: translateY(-50%); }
.field__box:has(.select) .field-opt { right: 36px; }
.field__box:has(.textarea) .field-opt,
.field__box:has(textarea) .field-opt { top: 16px; transform: none; }
.field__box:has(.field-opt) .input { padding-right: 5.75rem; }
.field__box:has(.select):has(.field-opt) .select { padding-right: 6.75rem; }
.field__box:has(.input:not(:placeholder-shown)) .field-opt,
.field__box:has(.textarea:not(:placeholder-shown)) .field-opt,
.field__box:has(textarea:not(:placeholder-shown)) .field-opt,
.field__box:has(.select option:checked:not([value=""])) .field-opt { opacity: 0; }
.field .req { color: var(--acc); }
.input, .select, .textarea {
  background: var(--cc-panel-2); border: 1px solid rgba(243,245,247,0.14); color: var(--cc-ink);
  font-family: var(--font-display); font-size: var(--fs-16); padding: 14px 16px;
  border-radius: var(--r-sharp); width: 100%;
  transition: border-color var(--dur-2), box-shadow var(--dur-2), background var(--dur-2);
}
.input::placeholder, .textarea::placeholder { color: var(--cc-ink-4); }
/* Native <select> has no ::placeholder; the empty required option is the
   stand-in, so colour it like an input placeholder until a real value is
   chosen. option { color } keeps the open list at full ink. */
.select:required:invalid,
.select:has(option[value=""]:checked) { color: var(--cc-ink-4); }
.select option { color: var(--cc-ink); }
.input:hover, .select:hover, .textarea:hover { border-color: rgba(243,245,247,0.24); }
.input:focus, .select:focus, .textarea:focus { border-color: var(--acc); box-shadow: 0 0 0 4px var(--acc-tint); outline: none; }
.select { appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23889' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; padding-right: 38px; cursor: pointer; }
.field.invalid .input, .field.invalid .select, .field.invalid .textarea { border-color: var(--err); }
.field .err-msg { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--err);
  letter-spacing: 0.04em; display: none; }
.field.invalid .err-msg { display: block; }

/* Phone: country-code picker + national number as one control. */
.phone-split { display: flex; align-items: stretch; position: relative;
  background: var(--cc-panel-2); border: 1px solid rgba(243,245,247,0.14);
  border-radius: var(--r-sharp);
  transition: border-color var(--dur-2), box-shadow var(--dur-2); }
.phone-split:hover { border-color: rgba(243,245,247,0.24); }
.phone-split:focus-within { border-color: var(--acc); box-shadow: var(--shadow-focus); }
.field.invalid .phone-split { border-color: var(--err); }
.phone-cc { position: relative; flex: 0 0 7.25rem; min-width: 0;
  border-right: 1px solid rgba(243,245,247,0.14); }
.phone-split .select, .phone-split .input, .phone-split .phone-cc__query {
  background: transparent; border-color: transparent; box-shadow: none; border-radius: 0; }
.phone-split .select:hover, .phone-split .input:hover,
.phone-split .select:focus, .phone-split .input:focus,
.phone-split .phone-cc__query:focus { border-color: transparent; box-shadow: none; }
.phone-split .select:focus-visible, .phone-split .input:focus-visible,
.phone-split .phone-cc__query:focus-visible { box-shadow: none; }
.phone-split .input { flex: 1; min-width: 0; }
.phone-cc__native { width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.js .phone-cc__native { position: absolute; width: 1px; height: 1px; opacity: 0;
  pointer-events: none; overflow: hidden; }
.phone-cc__query { width: 100%; padding: 14px 28px 14px 16px;
  font-family: var(--font-display); font-size: var(--fs-16); color: var(--cc-ink);
  background: transparent; border: 0; border-radius: 0; }
.phone-cc__query::placeholder { color: var(--cc-ink-4); }
.phone-cc__query.is-empty { color: var(--cc-ink-4); }
.phone-cc__chev { position: absolute; right: 10px; top: 50%; width: 14px; height: 14px;
  transform: translateY(-50%); pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23889' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; }
.phone-cc.is-open .phone-cc__chev { color: var(--cc-ink); }
.phone-cc__panel { display: none; position: absolute; left: 0; right: 0; top: calc(100% + 6px);
  z-index: 40; background: var(--cc-panel); border: 1px solid var(--cc-line-strong);
  border-radius: var(--r-sharp); box-shadow: var(--shadow-pop); overflow: hidden; }
.phone-cc__panel.is-open { display: block; }
.phone-cc__panel.is-up { top: auto; bottom: calc(100% + 6px); }
.phone-cc__list { list-style: none; margin: 0; padding: 6px 0; max-height: min(18rem, 50vh);
  overflow-y: auto; }
.phone-cc__opt { display: flex; align-items: baseline; gap: 12px; padding: 8px 14px;
  cursor: pointer; font-size: var(--fs-15); color: var(--cc-ink); }
.phone-cc__opt[hidden] { display: none !important; }
.phone-cc__opt:hover, .phone-cc__opt.is-active { background: var(--cc-panel-2); }
.phone-cc__opt.is-selected { color: var(--acc-hi); }
.phone-cc__dial { flex: 0 0 3.5rem; font-family: var(--font-mono); font-size: var(--fs-12);
  letter-spacing: 0.04em; color: var(--cc-ink-3); }
.phone-cc__opt.is-selected .phone-cc__dial, .phone-cc__opt.is-active .phone-cc__dial { color: inherit; }
.phone-cc__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.phone-cc__empty { display: none; margin: 0; padding: 14px; font-size: var(--fs-14);
  color: var(--cc-ink-3); }
.phone-cc__panel.is-empty .phone-cc__empty { display: block; }
.phone-cc__panel.is-empty .phone-cc__list { display: none; }
@media (prefers-reduced-motion: reduce) {
  .phone-split, .phone-cc__opt { transition: none; }
}

/* Form <select> menus. Same panel language as the phone-code picker so the
   open list is a dark, formatted surface rather than the OS control. Native
   <select> remains the no-JS control. */
.select-ui { position: relative; display: block; }
.js .select-ui__native { position: absolute; width: 1px; height: 1px; opacity: 0;
  pointer-events: none; overflow: hidden; }
.select-ui__btn, .select-ui__query {
  appearance: none; background: var(--cc-panel-2); border: 1px solid rgba(243,245,247,0.14); color: var(--cc-ink);
  font-family: var(--font-display); font-size: var(--fs-16); padding: 14px 38px 14px 16px;
  border-radius: var(--r-sharp); width: 100%; text-align: left; cursor: pointer;
  transition: border-color var(--dur-2), box-shadow var(--dur-2), background var(--dur-2); }
.select-ui__query { cursor: text; }
.select-ui__btn.is-empty, .select-ui__query.is-empty { color: var(--cc-ink-4); }
.select-ui__query::placeholder { color: var(--cc-ink-4); }
.select-ui__btn:hover, .select-ui__query:hover { border-color: rgba(243,245,247,0.24); }
.select-ui.is-open .select-ui__btn, .select-ui.is-open .select-ui__query,
.select-ui__btn:focus, .select-ui__query:focus {
  border-color: var(--acc); box-shadow: 0 0 0 4px var(--acc-tint); outline: none; }
.field.invalid .select-ui__btn, .field.invalid .select-ui__query { border-color: var(--err); }
.field__box:has(.field-opt) .select-ui__btn,
.field__box:has(.field-opt) .select-ui__query { padding-right: 6.75rem; }
.select-ui__chev { position: absolute; right: 14px; top: 50%; width: 14px; height: 14px;
  transform: translateY(-50%); pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23889' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; }
.field__box:has(.field-opt) .select-ui__chev { right: 14px; }
.select-ui__panel { display: none; position: absolute; left: 0; right: 0; top: calc(100% + 6px);
  z-index: 40; background: var(--cc-panel); border: 1px solid var(--cc-line-strong);
  border-radius: var(--r-sharp); box-shadow: var(--shadow-pop); overflow: hidden; }
.select-ui__panel.is-open { display: block; }
.select-ui__panel.is-up { top: auto; bottom: calc(100% + 6px); }
.select-ui__list { list-style: none; margin: 0; padding: 6px 0; max-height: min(18rem, 50vh);
  overflow-y: auto; }
.select-ui__opt { display: block; padding: 10px 16px; cursor: pointer;
  font-size: var(--fs-15); line-height: 1.35; color: var(--cc-ink); }
.select-ui__opt[hidden] { display: none !important; }
.select-ui__opt:hover, .select-ui__opt.is-active { background: var(--cc-panel-2); }
.select-ui__opt.is-selected { color: var(--acc-hi); }
.select-ui__opt.is-placeholder { color: var(--cc-ink-4); }
.select-ui__empty { display: none; margin: 0; padding: 14px; font-size: var(--fs-14);
  color: var(--cc-ink-3); }
.select-ui__panel.is-empty .select-ui__empty { display: block; }
.select-ui__panel.is-empty .select-ui__list { display: none; }
.field:has(.select-ui.is-open), .field:has(.phone-cc.is-open) { z-index: 6; }
@media (prefers-reduced-motion: reduce) {
  .select-ui__btn, .select-ui__query, .select-ui__opt { transition: none; }
}

/* Explanatory copy beside a field. Deliberately NOT an error: no red, no icon,
   no error state, and it never blocks a submission. It is sentence case in the
   body font, not the uppercase mono of a label, so it reads as us talking
   rather than as a system message. */
.hint { font-size: var(--fs-14); line-height: 1.5; color: var(--cc-ink-2); margin: 0; }
.identity-note { margin: 0 0 16px; }
.field .hint { margin-top: -2px; }

/* Personal-inbox caption. Unfolds from the email field when the domain is
   free-mail. Green glass, not an error: it invites a company address. Grid
   rows ease the height both ways; the card fades and lifts with it. */
.mail-tip { display: grid; grid-template-rows: 0fr; margin: 0;
  transition: grid-template-rows 360ms var(--ease-io); }
/* Collapsed tip is still a .field flex item, so cancel that 10px gap or the
   email/org row sits 10px lower than every other row. */
.mail-tip:not(.is-on) { margin-top: -10px; }
.mail-tip.is-on { grid-template-rows: 1fr; }
.mail-tip__clip { overflow: hidden; min-height: 0; }
.mail-tip__card { position: relative; margin: 8px 0 0; padding: 10px 12px 11px;
  background: color-mix(in srgb, var(--power-electric) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--power-electric) 42%, transparent);
  border-radius: var(--r-sharp); font-size: var(--fs-14); line-height: 1.45;
  color: var(--cc-ink);
  opacity: 0; transform: translateY(-6px);
  transition: opacity 360ms var(--ease-io), transform 360ms var(--ease-io); }
.mail-tip.is-on .mail-tip__card { opacity: 1; transform: none; }
.mail-tip__card::before { content: ""; position: absolute; left: 18px; top: -5px;
  width: 8px; height: 8px;
  background: color-mix(in srgb, var(--power-electric) 22%, var(--cc-panel));
  border-left: 1px solid color-mix(in srgb, var(--power-electric) 42%, transparent);
  border-top: 1px solid color-mix(in srgb, var(--power-electric) 42%, transparent);
  transform: rotate(45deg); }

/* The free-mail branch. Revealed by app.js on email blur; without JS it stays
   hidden and the server simply does not receive those fields. Website and
   LinkedIn stay optional either way. */
.identity-extra[hidden] { display: none; }
.identity-extra { display: block; }

/* chips — the only pills besides power tags and the mobile CTA */
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { font-family: var(--font-mono); font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--cc-ink-2);
  background: var(--cc-panel-2); border: 1px solid transparent; border-radius: var(--r-pill); padding: 10px 16px;
  cursor: pointer; transition: background var(--dur-1), color var(--dur-1), border-color var(--dur-1), transform var(--dur-1);
  user-select: none; min-height: 40px; display: inline-flex; align-items: center; }
.chip:hover { background: #171b22; color: var(--cc-ink); }
.chip:active { transform: scale(0.97); }
.chip.on { background: var(--acc); border-color: var(--acc); color: var(--btn-fg); }

/* ---- spec-sheet gate ---- */
.gate { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; max-width: 1200px; align-items: start;
  background: none; border: 0; border-radius: 0; box-shadow: none; }
.gate__l { padding: 0; border: 0; }
.gate__open { display: none; margin-top: 28px; }
.gate__open-slot { display: grid; grid-template-rows: 1fr; min-width: 0;
  transition: grid-template-rows 480ms var(--ease-out); }
.gate__open-clip { overflow: hidden; min-height: 0; }
.gate__slot { min-width: 0; display: grid; grid-template-rows: 1fr;
  transition: grid-template-rows 560ms var(--ease-out); }
.gate__slot-clip { overflow: hidden; min-height: 0; min-width: 0; }
.gate__r { background: var(--cc-panel); border: 1px solid var(--cc-line); border-radius: var(--r-sharp);
  padding: 44px; display: flex; flex-direction: column; gap: 20px;
  transition: opacity 480ms var(--ease-out), transform 560ms var(--ease-out); }
/* JS: collapsed until Get specification sheet. Columns stay 1fr 1fr so the
   copy never reflows; the form fades in. No-JS keeps the form in view.
   Inbound #spec (hero, footer) sets html.spec-open in <head> so the panel is
   already open on first paint. */
.js #spec .gate__open { display: inline-flex; }
.js #spec .gate { row-gap: 0; }
.js #spec .gate__slot { grid-template-rows: 0fr; }
.js #spec .gate__r { opacity: 0; transform: translate3d(16px, 0, 0); }
.js #spec.is-open .gate__open-slot,
html.spec-open #spec .gate__open-slot { grid-template-rows: 0fr; }
.js #spec.is-open .gate__r,
html.spec-open #spec .gate__r { opacity: 1; transform: none; }
.js #spec.is-open .gate__slot,
html.spec-open #spec .gate__slot { grid-template-rows: 1fr; }
.js #spec.is-open .gate,
html.spec-open #spec .gate { row-gap: 80px; }

/* Turnstile: native widget is an iframe we cannot restyle. Pin it to the
   300×65 "normal" size (not flexible/full-width), clip the 1px white frame
   Cloudflare draws in dark theme, and sit it as a quiet chip above the CTA. */
.turnstile { width: fit-content; max-width: 100%; line-height: 0; overflow: hidden;
  color-scheme: dark; border-radius: var(--r-sharp); clip-path: inset(1px round 2px); }
.turnstile .cf-turnstile { width: 300px; max-width: 100%; }
.gate__row { display: flex; flex-direction: column; gap: 20px; }
.gate__row .field { flex: 1; }
.gate__meta { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); margin-top: 32px; }

/* ---- quotation (two-step) ---- */
.panel--quote { max-width: var(--measure-form); margin: 0 auto; padding: 48px; }
.quote { position: relative; }
/* Both steps and the action row share the contact-form column so Email
   is not a 440px box and Turnstile sits beside the CTA. The panel is
   sized to that column plus 48px pad, so the grey frame is even. */
#quote #step1,
#quote #step2,
#quote #stepDone,
#quote .quote-foot { max-width: var(--measure-lead); margin-inline: auto; }
.quote-stack { display: flex; flex-direction: column; gap: 16px; }
.quote-foot { display: flex; align-items: center; gap: 16px; margin-top: 24px; width: 100%; }
.quote-foot__end { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-left: auto; min-width: 0; }
#quote .quote-foot .btn--lg { min-height: 65px; flex-shrink: 0; }
#quote .quote-foot .turnstile { flex: 0 0 auto; height: 65px; }
@media (max-width: 520px) {
  #quote .quote-foot { flex-wrap: wrap; }
  #quote .quote-foot__end { width: 100%; margin-left: 0; }
}
.field label.same-as { display: inline-flex; align-items: center; gap: 8px; margin: 0;
  font-family: var(--font-display); font-size: var(--fs-14); font-weight: var(--fw-regular);
  letter-spacing: 0; text-transform: none; color: var(--cc-ink-3); cursor: pointer; }
.same-as input { margin: 0; }
.quote__rail { display: flex; align-items: center; gap: 18px; margin-bottom: 40px; }
.stepdot { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); white-space: nowrap; }
.progress { height: 2px; background: var(--cc-line-strong); flex: 1; position: relative; overflow: hidden; }
.progress > i { position: absolute; left: 0; top: 0; bottom: 0; width: 50%; background: var(--acc);
  transition: width var(--dur-3) var(--ease-out); }

.step { display: none; border: 0; margin: 0; padding: 0; min-width: 0; }
.step.on { display: block; animation: stepin var(--dur-3) var(--ease-out); }
@keyframes stepin { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

.cfg-group { padding: 28px 0; border-top: 1px solid var(--cc-line); }
.cfg-group:first-child { border-top: none; padding-top: 4px; }
.cfg-group__h { display: flex; align-items: baseline; gap: 12px; margin-bottom: 18px; }
.cfg-group__n { font-family: var(--font-mono); font-size: var(--fs-mono); color: var(--cc-ink-3); letter-spacing: var(--tr-label-2); }
.cfg-group__t { font-size: var(--fs-15); font-weight: var(--fw-semibold); }
.cfg-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.cfg-row.cfg-row--fill { grid-template-columns: 1fr; }
@media (min-width: 1101px) {
  .cfg-row.cfg-row--fill:has(> .field:not([hidden]) + .field:not([hidden])) {
    grid-template-columns: 1fr 1fr;
  }
}

.cfg-more { border-top: 1px solid var(--cc-line); margin-top: 6px; }
.cfg-more__sum { display: inline-flex; align-items: center; gap: 10px; padding: 24px 0 4px; cursor: pointer;
  font-size: var(--fs-15); font-weight: var(--fw-semibold); color: var(--cc-ink); list-style: none; }
.cfg-more__sum::-webkit-details-marker { display: none; }
.cfg-more__sum::before { content: "+"; font-family: var(--font-mono); font-size: 16px; line-height: 1; color: var(--acc); }
.cfg-more[open] > .cfg-more__sum::before { content: "\2212"; }
.cfg-more__sum:hover { color: var(--acc-hi); }
.cfg-more > .cfg-group:first-of-type { border-top: none; }

/* success states */
.done { text-align: center; padding: 24px 0; }
.done__ring { width: 56px; height: 56px; border-radius: var(--r-pill); border: 1px solid var(--acc);
  display: inline-flex; align-items: center; justify-content: center; color: var(--acc); margin-bottom: 28px; }
.done__ring svg { width: 24px; height: 24px; }
.done__ref { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); margin-top: 28px; }

/* ============================================================
   FAQ
   ============================================================ */
.faq { border-top: 1px solid var(--cc-line-strong); max-width: 960px; margin: 0 auto; }
.faq__item { border-bottom: 1px solid var(--cc-line); }
.faq__q { display: flex; align-items: center; gap: 24px; width: 100%; background: none; border: none;
  color: var(--cc-ink); text-align: left; padding: 26px 0; cursor: pointer; font-family: var(--font-display); }
.faq__q .qt { font-size: 20px; font-weight: var(--fw-semibold); letter-spacing: 0; line-height: 1.3; flex: 1; }
.faq__q .qi { color: var(--cc-mark); transition: transform var(--dur-3) var(--ease-out), color var(--dur-2); flex-shrink: 0; }
.faq__q .qi svg { width: 18px; height: 18px; display: block; }
.faq__item.open .qi { transform: rotate(45deg); color: var(--acc); }
/* Expand/collapse via grid rows (0fr -> 1fr): no scrollHeight caching, and open
   panels reflow correctly on resize. Spacing lives on the children because any
   padding on the clipped wrapper would leak while collapsed. */
.faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-3) var(--ease-io); }
.faq__item.open .faq__a { grid-template-rows: 1fr; }
/* Answers read as a bold one-line "direct answer" + relaxed follow-up. */
.faq__lead { margin: 4px 0 0; font-size: var(--fs-15); line-height: var(--lh-lede);
  font-weight: var(--fw-semibold); color: var(--cc-ink); max-width: 62ch; }
.faq__rest { margin: 14px 0 0; font-size: var(--fs-15); line-height: 1.8;
  color: var(--cc-ink-body); max-width: 62ch; }
.faq__a__in { overflow: hidden; min-height: 0; font-size: var(--fs-15); line-height: var(--lh-lede);
  color: rgba(243,245,247,0.65); max-width: 70ch; }
.faq__a__in > :last-child { margin-bottom: 36px; }

/* ============================================================
   FOOTER — quiet centred close
   ============================================================ */
/* Footer (2026-07-16 redesign): brand column + link columns, giant cropped
   ghost wordmark, fine-print bottom bar. The black page stays the frame. */
.footer { position: relative; padding: 24px var(--gutter) 0; text-align: left; overflow: hidden; }
.footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 56px 64px;
  padding-bottom: 96px; }
.footer__brandrow { display: flex; align-items: center; gap: 12px; margin: 0; }
.footer__brandrow .footer__mark { width: 28px; height: 28px; margin: 0; }
.footer__word { font-family: var(--font-brand); font-weight: var(--fw-bold); font-size: 34px;
  letter-spacing: 0.01em; line-height: 1; text-transform: lowercase; margin: 0; }
.footer__brand .footer__blurb { margin: 20px 0 0; max-width: 46ch; text-align: left;
  font-size: var(--fs-15); line-height: var(--lh-body); color: var(--cc-ink-2); }
.footer__brand .footer__contact { display: flex; flex-direction: column; align-items: flex-start;
  gap: 12px; margin-top: 32px; }
.footer__brand .footer__contact a, .footer__brand .footer__contact span {
  display: inline-flex; align-items: center; gap: 10px; }
.footer__brand .footer__contact svg { width: 14px; height: 14px; flex-shrink: 0;
  color: var(--cc-ink-3); }
.footer__col { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.footer__col-t { margin: 0 0 14px; font-family: var(--font-mono); font-size: var(--fs-mono);
  letter-spacing: var(--tr-label); text-transform: uppercase; color: var(--cc-ink-3); }
.footer__col a { font-size: var(--fs-15); color: var(--cc-ink-2); display: inline-flex;
  align-items: center; min-height: 38px; transition: color var(--dur-1), transform var(--dur-1); }
.footer__col a:hover { color: var(--cc-ink); transform: translateX(3px); }
.footer__giant { margin: 0 0 -0.36em; font-family: var(--font-brand); font-weight: var(--fw-bold);
  text-transform: lowercase; font-size: clamp(110px, 21vw, 320px); line-height: 0.9;
  letter-spacing: -0.015em; text-align: center; color: rgba(243, 245, 247, 0.045);
  user-select: none; pointer-events: none; }
/* Normal inline flow: as an inline-flex with gap, the text, the company link and
   the trailing period became separate flex items, printing a 12px gap before
   the period ("Helvetis ."). */
.footer__bot-brand { display: inline; }
.footer__bot-brand img { opacity: 0.7; vertical-align: middle; margin-right: 12px; }
.footer__blurb { max-width: 52ch; margin: 22px auto 0; font-size: var(--fs-body);
  line-height: var(--lh-body); color: var(--cc-ink-3); }
.footer__nav { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px 36px; margin-top: 40px; }
.footer__nav a { font-size: var(--fs-15); color: var(--cc-ink-2); display: inline-flex; align-items: center; min-height: 44px; }
.footer__nav a:hover { color: var(--cc-ink); }
.footer__contact { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px 28px; margin-top: 18px;
  font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); }
.footer__contact a:hover { color: var(--cc-ink); }
.footer__bot { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 16px;
  padding-top: 26px; border-top: 1px solid var(--cc-line); text-align: left;
  font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: 0.08em; color: var(--cc-ink-3); }
.footer__bot a { color: var(--cc-ink-3); display: inline-flex; align-items: center; min-height: 44px; }
/* Parent-company link sits inline in the copyright line, so it must not take
   the 44px block treatment the other footer links get. */
.footer__company { display: inline; min-height: 0; color: var(--cc-ink-2); border-bottom: 1px solid var(--cc-line-strong); }
.footer__company:hover { color: var(--cc-ink); border-bottom-color: var(--cc-ink); }
.footer__bot a:hover { color: var(--cc-ink); }
.footer__bot-r { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
/* Between the burger breakpoint and ~1280 the five-item nav plus the CTA runs
   out of room in FR/ES (measured -2px slack at 1101 in French), so the item
   padding steps down before anything can collide. */
@media (max-width: 1280px) and (min-width: 1101px) {
  .nav__links a { padding-left: 11px; padding-right: 11px; }
}

@media (max-width: 1100px) { .footer__grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 720px)  { .footer__grid { grid-template-columns: 1fr; gap: 44px; padding-bottom: 64px; } }

/* ============================================================
   SUB-PAGES (application spokes + guide)
   ============================================================ */
.apphero { position: relative; min-height: clamp(560px, 72vh, 700px); overflow: hidden; display: flex; align-items: flex-end; }
/* "Configured for <mission>" module: statement + actions left, live
   family-maximum figures right, in the home spec-block data language. */
.config { display: grid; grid-template-columns: minmax(0, 7fr) minmax(280px, 4fr);
  gap: 44px 80px; padding: 52px 56px; align-items: center; }
.config__body { margin: 0; font-size: var(--fs-lede); line-height: var(--lh-lede);
  color: var(--cc-ink); max-width: 44ch; }
.config__actions { margin-top: 30px; display: flex; gap: 14px; flex-wrap: wrap; }
.config__home { margin: 24px 0 0; font-size: 13px; }
.config__home a { color: var(--cc-ink-3); transition: color var(--dur-1); }
.config__home a:hover { color: var(--cc-ink); }
.config__figs { margin: 0; border-left: 1px solid var(--cc-line-strong); padding-left: 48px; }
.config__fig { display: flex; justify-content: space-between; align-items: baseline;
  gap: 20px; padding: 15px 0; }
.config__fig + .config__fig { border-top: 1px solid var(--cc-line); }
.config__fig dt { font-family: var(--font-mono); font-size: 10px; letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); }
.config__fig dd { margin: 0; font-size: var(--fs-data); font-weight: var(--fw-semibold);
  color: var(--cc-ink); white-space: nowrap; }
.config__note { margin: 16px 0 0; font-family: var(--font-mono); font-size: 10px;
  letter-spacing: var(--tr-label-2); text-transform: uppercase; color: var(--cc-ink-3); }
@media (max-width: 900px) {
  .config { grid-template-columns: 1fr; padding: 36px 28px; }
  .config__figs { border-left: 0; padding-left: 0; border-top: 1px solid var(--cc-line-strong); padding-top: 8px; }
}

/* Contained image break on sub-pages: framed, capped height, quiet zoom. */
.app-break { position: relative; margin: 0; height: clamp(300px, 40vw, 440px); overflow: hidden;
  border: 1px solid var(--cc-line); border-radius: var(--r-sharp); }
.app-break img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 28%; display: block;
  transition: transform 0.8s cubic-bezier(0.2, 0.6, 0.2, 1); }
.app-break:hover img { transform: scale(1.04); }
.app-break__tag { position: absolute; left: 22px; bottom: 20px; z-index: 2; }
.app-break::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(5, 6, 7, 0.55), transparent 42%); }
@media (prefers-reduced-motion: reduce) { .app-break:hover img { transform: none; } }
.apphero__media { position: absolute; inset: 0; margin: 0; z-index: 0; }
.apphero__media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: auto; border: 0; }
.apphero::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--scrim-page); }
.apphero__in { position: relative; z-index: 2; width: 100%; padding: var(--nav-h) var(--gutter) 72px; }
.apphero h1 { font-size: clamp(2.5rem, 5.8vw, 5.25rem); font-weight: var(--fw-bold);
  line-height: var(--lh-display); letter-spacing: var(--tr-display); max-width: 18ch; margin-top: 22px;
  text-shadow: var(--shadow-display); }
.apphero .hero__cta { margin-top: 40px; }

.crumbs { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label-2);
  text-transform: uppercase; color: var(--cc-ink-3); display: flex; gap: 10px; align-items: center; }
.crumbs a { color: var(--cc-ink-3); }
.crumbs a:hover { color: var(--cc-ink); }
.crumbs [aria-current="page"] { color: var(--cc-ink-2); }

.appintro { max-width: calc(var(--measure) + 2 * var(--pad)); margin: 0 auto; padding: 140px var(--pad) 120px; text-align: center; }
.appintro .lede { font-size: clamp(1.125rem, 1.4vw, 1.375rem); max-width: none; margin: 0; }
/* Brand note: the "supplied and integrated by Helvetis" line. Reads exactly
   like the intro lede, on its own line, with a soft highlighter behind the
   key phrases (2026-07-16 review: no panel, no border). */
.appintro__note { margin: 26px auto 0; padding: 0; border: 0; background: none;
  max-width: none; text-align: center; font-weight: var(--fw-regular);
  font-size: clamp(1.125rem, 1.4vw, 1.375rem); line-height: var(--lh-lede);
  color: var(--cc-ink-2); }
.appintro__note strong { background: var(--acc-tint); color: var(--cc-ink);
  font-weight: var(--fw-semibold); padding: 1px 7px 2px; border-radius: 3px;
  box-decoration-break: clone; -webkit-box-decoration-break: clone; }

/* capability blocks on a sub-page reuse .cap-grid / .cap */
.feat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 48px; background: none; border: 0; }
.feat { background: none; border-top: 1px solid var(--cc-line-strong); padding: 24px 0 0; }
.feat__n { font-family: var(--font-mono); font-size: var(--fs-mono); letter-spacing: var(--tr-label);
  color: var(--cc-ink-3); margin: 0 0 14px; }
.feat__title { font-size: var(--fs-block); font-weight: var(--fw-semibold); line-height: var(--lh-block); margin: 0; }
.feat__desc { margin: 12px 0 0; font-size: var(--fs-body); color: var(--cc-ink-body); line-height: var(--lh-body); }

/* prose sections: heading (1fr) | paragraphs (1.2fr) */
.split { display: grid; grid-template-columns: 1fr 1.2fr; gap: 64px; align-items: start; }
/* Prose layout (2026-07-16 refactor): top-rule editorial rows — a compact
   sticky heading rail on the left, a wide readable body column on the right.
   Kills the old 45% heading column that wasted half the row. */
.prose-cols { display: grid; gap: 96px; max-width: none; }
.prose-block { display: grid; grid-template-columns: minmax(220px, 300px) minmax(0, 1fr);
  gap: 32px 96px; align-items: start; border-top: 1px solid var(--cc-line); padding-top: 30px; }
.prose-block h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); letter-spacing: var(--tr-display);
  line-height: 1.08; position: sticky; top: 110px; }
.prose-block__body { max-width: 74ch; }
.prose-block .lede { font-size: 17px; line-height: var(--lh-prose); max-width: none; }
/* Keyword highlights inside prose and intros are the sitewide `p strong` rule
   (TYPE section). Only .appintro__note deviates, with its highlighter wash. */
/* Media slot inside a prose body: labelled placeholder until real media lands. */
.prose-media { margin: 30px 0 6px; aspect-ratio: 16 / 7; display: flex; align-items: center;
  justify-content: center; padding: 16px; overflow: hidden;
  background:
    repeating-linear-gradient(0deg,  transparent 0 27px, rgba(243, 245, 247, 0.03) 27px 28px),
    repeating-linear-gradient(90deg, transparent 0 27px, rgba(243, 245, 247, 0.03) 27px 28px),
    var(--cc-panel);
  border: 1px solid var(--cc-line); border-radius: var(--r-sharp); }
.prose-media img { width: 100%; height: 100%; object-fit: contain; }
/* Photo variant: full-bleed inside the frame (no engineering grid), quiet zoom. */
.prose-media--photo { padding: 0; aspect-ratio: 16 / 9; background: var(--cc-panel); }
.prose-media--photo picture { width: 100%; height: 100%; display: block; }
.prose-media--photo img { object-fit: cover; transition: transform 0.8s cubic-bezier(0.2, 0.6, 0.2, 1); }
.prose-media--photo:hover img { transform: scale(1.04); }
@media (prefers-reduced-motion: reduce) { .prose-media--photo:hover img { transform: none; } }

.qa { border-top: 1px solid var(--cc-line-strong); max-width: var(--measure); }
.qa__item { padding: 24px 0 26px; border-bottom: 1px solid var(--cc-line); }
.qa__q { font-size: var(--fs-block); font-weight: var(--fw-semibold); line-height: var(--lh-block); }
.qa__a { margin-top: 12px; font-size: var(--fs-15); line-height: var(--lh-lede); color: var(--cc-ink-body); max-width: 72ch; }
/* Direct-answer treatment (home FAQ pattern) for sub-page Q&As. */
.qa__lead { margin: 12px 0 0; font-size: var(--fs-15); line-height: var(--lh-lede);
  font-weight: var(--fw-semibold); color: var(--cc-ink); max-width: 62ch; }
.qa__rest { margin: 10px 0 0; font-size: var(--fs-15); line-height: 1.8;
  color: var(--cc-ink-body); max-width: 62ch; }

.related-links { list-style: none; margin: 24px 0 0; padding: 0; display: flex; flex-direction: column;
  gap: 18px; align-items: flex-start; }

/* ============================================================
   MOBILE FLOATING CTA — the only pill in the system
   ============================================================ */
.fab {
  display: none; position: fixed; right: 24px; bottom: 24px; z-index: 90;
  background: var(--acc); color: var(--btn-fg); border: 0; border-radius: var(--r-pill);
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-15);
  padding: 15px 24px; min-height: 48px; align-items: center; gap: 10px;
  box-shadow: var(--shadow-pill);
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity var(--dur-3) var(--ease-out), transform var(--dur-3) var(--ease-out);
}
.fab svg { width: 15px; height: 15px; }
.fab.is-on { opacity: 1; transform: none; pointer-events: auto; }
.fab:active { background: var(--acc-press); }

/* ============================================================
   MOBILE MENU
   ============================================================ */
.mobile-menu { display: none; }

@media (max-width: 1100px) {
  :root { --pad: 40px; --section-y: 120px; --section-y-top: 130px; }
  .cap-grid, .feat-grid { grid-template-columns: repeat(2, 1fr); gap: 40px; }
  .cap-grid--3 { grid-template-columns: repeat(2, 1fr); }
  .cred-split { grid-template-columns: 1fr; }
  /* Stacked: the image is its own band again, so the CELL carries the height
     (the pinned img contributes none) and the picture fills it. */
  .cred-split__media { height: 420px; }
  .cred-split__panel { padding: 64px var(--pad); }
  .gate { grid-template-columns: 1fr; gap: 48px; }
  .js #spec.is-open .gate,
  html.spec-open #spec .gate { row-gap: 48px; }
  .split, .prose-block { grid-template-columns: 1fr; gap: 24px; }
  .prose-block h2 { position: static; }
  .prose-cols { gap: 72px; }
  .cfg-row { grid-template-columns: 1fr; }
  .spec-head { flex-direction: column; align-items: flex-start; gap: 28px; }
  .hero__foot { flex-direction: column; align-items: flex-start; gap: 32px; }
  .hero__sub { text-align: left; }
  .spec-shot img { height: 460px; }
  .spec-crops img { height: 260px; }
  /* Touch targets: 44px on every real control. The tile links already stretch
     across their whole tile via .mcard__link::after, so they are exempt. */
  .brand, a.link-arrow, .footer__contact a, .crumbs a, .lbl a, .skip-link {
    min-height: 44px; display: inline-flex; align-items: center;
  }
  /* collapse nav to burger */
  /* .brand__by stays visible on mobile (2026-07-16 review: the Swiss
     provenance mark must always show); only nav links and lang collapse. */
  .nav__links, .lang { display: none; }
  .brand__by { padding-left: 10px; gap: 6px; }
  .brand__by .brand__helvetis { font-size: 12px; }
  .nav__cta .btn--primary { display: none; }
  .burger { display: inline-flex; }
  .fab { display: inline-flex; }
  .mobile-menu { display: block; position: fixed; inset: 0; z-index: 200; background: var(--cc-bg);
    transform: translateX(100%); transition: transform var(--dur-3) var(--ease-out); padding: 24px 20px; }
  .mobile-menu.open { transform: none; }
  .mobile-menu__top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40px; }
  .mobile-menu a { display: block; font-size: 30px; font-weight: var(--fw-semibold); letter-spacing: -0.02em;
    padding: 14px 0; border-bottom: 1px solid var(--cc-line); }
  .mobile-menu .m-lang { display: flex; gap: 8px; margin-top: 28px; }
  .mobile-menu .m-cta { margin-top: 28px; }
}

@media (max-width: 720px) {
  :root { --pad: 20px; --section-y: 90px; --section-y-top: 96px; --band-h: 620px; --band-h-short: 560px; }
  .hero { min-height: 620px; height: 100svh; max-height: none; }
  .hero__in { padding-bottom: 48px; }
  .hero h1 { max-width: none; }
  .hero__cta { width: 100%; }
  .hero__cta .btn { flex: 1; }
  .figures { padding: 32px var(--pad); }
  .figures__in { gap: 24px 44px; }
  .figures__v { font-size: 24px; }
  .cap-grid, .feat-grid, .cap-grid--3 { grid-template-columns: 1fr; gap: 36px; }
  .sec-head { margin-bottom: 44px; }
  .media-band--head { min-height: 520px; }
  .media-band__in { padding: var(--gutter) var(--gutter) 40px; }
  .media-band__top { top: 24px; }
  /* application tiles: stacked 4:5 */
  .mgrid { grid-template-columns: 1fr; }
  .mcard { aspect-ratio: 4 / 5; }
  .mcard__body { padding: 24px 20px; }
  .spec-shot { margin-top: 56px; }
  .spectable-plans { grid-template-columns: 1fr; margin-bottom: 20px; }
  .spectable-wrap { --spectable-peek: 24rem; }
  .spectable-fold { margin-top: 0; }
  .js .spectable-fold::after { height: 11rem; }
  .js .spectable-fold:not(.is-open) .spectable-fold__s { height: 11rem; }
  /* Spec pattern: one variant at a time — never a horizontal scroller. */
  .vswitch { display: flex; }
  .specs .spectable-plans [data-v],
  .specs .spectable [data-v] { display: none; }
  .specs[data-variant="e"]  .spectable-plans [data-v="e"],
  .specs[data-variant="ex"] .spectable-plans [data-v="ex"],
  .specs[data-variant="x"]  .spectable-plans [data-v="x"] { display: block; }
  .specs[data-variant="e"]  .spectable [data-v="e"],
  .specs[data-variant="ex"] .spectable [data-v="ex"],
  .specs[data-variant="x"]  .spectable [data-v="x"] { display: table-cell; }
  .spectable th, .spectable td { padding-left: 12px; padding-right: 12px; }
  .spec-crops { grid-template-columns: 1fr; }
  .spec-shot img { height: 300px; }
  .spec-crops img { height: 220px; }
  .panel--quote { padding: 28px; }
  .gate__r { padding: 28px 20px; }
  .cred-split__panel { padding: 48px var(--pad); }
  .cred-entries { margin-top: 44px; gap: 36px; }
  .appintro { padding: 72px var(--pad); }
  .apphero { min-height: 560px; }
  .footer { padding-bottom: 0; }
  .footer__bot { flex-direction: column; align-items: flex-start; }
}

/* ============================================================
   ANCHOR TARGETS — the header is fixed, so a jump must clear it
   ============================================================ */
/* Without this the header (--nav-h) sits over the section top and cuts the
   heading. The extra space keeps the eyebrow visible above the title too. */
:where(section, footer, div, h1, h2, h3)[id] { scroll-margin-top: calc(var(--nav-h) + 32px); }
#top, #main { scroll-margin-top: 0; }
@media (max-width: 720px) {
  :where(section, footer, div, h1, h2, h3)[id] { scroll-margin-top: calc(var(--nav-h) + 16px); }
}

/* ============================================================
   UTILITIES / A11Y
   ============================================================ */
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; top: 8px; left: 8px; z-index: 999; transform: translateY(-150%);
  background: var(--acc); color: var(--btn-fg); padding: 10px 16px; border-radius: var(--r-sharp);
  font-family: var(--font-display); font-weight: var(--fw-semibold); font-size: var(--fs-14);
  transition: transform var(--dur-2) var(--ease-out); }
.skip-link:focus { transform: none; outline: none; box-shadow: var(--shadow-focus); }
@media print { .skip-link, .fab { display: none; } }

/* Kills the UA <figure> margin only. Wrapped in :where() so it carries zero
   specificity: author rules always beat the UA default anyway, and this way a
   component that needs its own margin (.variant__plan, .spec-shot, .sec-media)
   is not silently overridden by a utility sitting at the end of the file. */
:where(.media) { margin: 0; }
.media img, .media video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* --- Button arrow nudge (micro-interaction) --- */
.btn svg, .link-arrow svg { transition: transform var(--dur-2) var(--ease-out); }
.btn:hover svg { transform: translateX(3px); }

/* --- Reveal-on-scroll: opt-in only when JS is present, so no-JS shows everything --- */
.reveal { opacity: 1; transform: none; transition: none; }
.js .reveal { transition: opacity var(--dur-4) var(--ease-out), transform var(--dur-4) var(--ease-out); }
.js .reveal:not(.in) { opacity: 0; transform: translateY(16px); }

/* --- Hero entrance (2026-07 bolder pass) ---
   One choreographed sequence instead of an identical fade-up on every child:
   the media settles from a slow push-in while the two headline lines rise out
   of their clipped blocks in turn, then the CTA row arrives. Three beats with
   distinct roles. CSS animations (not class-gated transitions), so a hidden tab
   simply plays them on first paint; no-JS and reduced motion render the final
   frame. */
@media (prefers-reduced-motion: no-preference) {
  .js .hero__media .media { animation: jbHeroSettle 1600ms var(--ease-out) both; }
  .js .hero__li { transform: translateY(115%); animation: jbHeroLine 760ms var(--ease-out) forwards; }
  .js .hero__line:nth-of-type(1) .hero__li { animation-delay: 80ms; }
  .js .hero__line:nth-of-type(2) .hero__li { animation-delay: 220ms; }
  .js .hero:not(.is-ready) .hero__line { overflow: hidden; }
  .js .hero__foot { opacity: 0; transform: translateY(12px); animation: jbHeroIn var(--dur-4) var(--ease-out) 520ms forwards; }
}
@keyframes jbHeroIn { to { opacity: 1; transform: none; } }
@keyframes jbHeroLine { to { transform: none; } }
@keyframes jbHeroSettle { from { transform: scale(1.045); } to { transform: none; } }

/* --- Hero poster fallback: still image under reduced motion ---
   Needs .hero to out-specify `.media img` (0,1,1), which would otherwise force
   the poster to display:block alongside the video. */
.hero .hero__poster { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero .hero__video { display: none; }
  .hero .hero__poster { display: block; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
}

/* --- Honour reduced motion everywhere --- */
@media (prefers-reduced-motion: reduce) {
  .js .reveal, .js .hero__body > *, .js .hero__li, .js .hero__media .media { opacity: 1 !important; transform: none !important; animation: none !important; }
  .dot { animation: none !important; }
  .mcard:hover .mcard__media img { transform: none !important; }
  .faq__a, .faq__q .qi, .spectable-fold__chev, .spectable-fold__disc, .spectable-wrap,
  .mail-tip, .mail-tip__card,
  .gate, .gate__slot, .gate__open-slot, .gate__r,
  .spectable tbody td { transition: none !important; }
  .mail-tip.is-on .mail-tip__card { opacity: 1; transform: none; }
  * { scroll-behavior: auto !important; }
}

/* --- Consent banner: a dismissible card on small screens --- */
@media (max-width: 720px) {
  .consent { left: 12px; right: 12px; bottom: 12px;
    border: 1px solid var(--cc-line-strong); border-radius: var(--r-sharp); }
}
.mobile-menu[hidden] { display: none !important; }
@media (max-width: 1100px) {
  .mobile-menu:not(.open) { visibility: hidden; pointer-events: none; }
  .lang a { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
}
