/* ============================================================
   Brilliance RGB — design system (tokens + reusable components)
   Ported from the design handoff: Designs/Open Design/prototypes/_shared/brilliance.css
   (source of truth: tokens.json + design-system/*.md).

   This is hand-authored design-system CSS for bespoke components that are
   impractical as pure Tailwind utilities (notched cards, RGB spectrum strips,
   the thin display type scale). Layout/spacing/colour for everything else uses
   Tailwind utilities in the block templates.

   Loaded from base.html AFTER mysite.css (Tailwind) so these win where they
   intentionally override. Brand tokens here are design CONSTANTS (not editor
   re-themeable); the editor-controlled palette still lives on BrandingSettings.
   ============================================================ */

/* Design fonts. Google Sans Flex/Code (the Figma originals) are not on the
   public Google Fonts API, so we use their documented fallbacks: Inter for
   sans (incl. weight 200 for the thin display headings) and Roboto Mono for
   the mono eyebrows/captions. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;500;600;700&family=Roboto+Mono:wght@300;400;500;600;700&display=swap');

:root {
  /* ── colour ──
     Brand colours are fallback defaults here; base.html overrides them from
     BrillianceBrandSettings (Settings → Brand Colours) — the single editable source. */
  --navy: #1C2F76;
  --navy-90: color-mix(in srgb, var(--navy) 90%, transparent);
  --cyan: #00B1EB;
  --sky: #74C0FC;
  --green: #95C11F;
  --red: #E50046;
  --white: #FFFFFF;
  --snow: #FFFAFA;
  --black: #000000;
  --stroke-black: #313131;
  --deep-navy: #050416;

  /* ── gradients (derived from the brand colours above) ── */
  --rgb-spectrum: linear-gradient(90deg, var(--navy-90) 0%, color-mix(in srgb, var(--cyan) 90%, transparent) 39.842%, color-mix(in srgb, var(--green) 90%, transparent) 73.981%, color-mix(in srgb, var(--red) 90%, transparent) 99.621%);
  --footer-grad: linear-gradient(to bottom, var(--navy) 35.455%, #000000 100%);
  --card-overlay: linear-gradient(to bottom, rgba(255,250,250,0) 30%, rgba(0,0,0,.78) 92%);
  --hero-scrim: linear-gradient(102deg, rgba(5,4,22,.90) 0%, rgba(5,4,22,.72) 34%, rgba(5,4,22,.30) 64%, rgba(5,4,22,0) 90%);
  --hero-scrim-light: linear-gradient(102deg, rgba(255,255,255,.82) 0%, rgba(255,255,255,.55) 38%, rgba(255,255,255,.12) 70%, rgba(255,255,255,0) 92%);

  /* ── type ── */
  /* Headings (.b-h1/.b-h2/.b-h3) use --sans; point it at the editor-controlled
     Main Font so headings, subheading and text all default to the same family.
     Falls back to Inter if the Main Font is unset (e.g. isolated previews). */
  --sans: var(--main-font-family, "Inter"), "Helvetica Neue", system-ui, sans-serif;
  /* The page wrapper carries Tailwind's `font-sans` utility, which sets font-family
     to var(--font-sans) on all descendants — overriding the body's Main Font for
     anything that doesn't set its own family (subheading, text). Re-point that
     variable at the Main Font so EVERY block matches the headings. */
  --font-sans: var(--main-font-family, "Inter"), "Helvetica Neue", ui-sans-serif, system-ui, sans-serif;
  --mono: "Roboto Mono", ui-monospace, monospace;

  /* ── radius ── */
  --r-xs: 4px;  --r-sm: 10px; --r-md: 20px;
  --r-pill: 16px; --r-pill-sm: 15px; --r-input: 25px;
  --r-cta: 30px; --r-learn: 32px;
  --notch: 20px 20px 100px 20px;
  --header-notch: 20px 20px 390px 20px;
  --footer-notch: 20px 20px 200px 20px;

  /* ── shadow ── */
  --shadow-nav: 0px 4px 12px 0px rgba(0,0,0,.25);

  /* ── layout framing ── */
  --page-gap: 20px;      /* gap from the page's left/right edges to the hero card */
  --page-gap-top: 20px;  /* gap from the page's TOP edge to the hero card (equal to side gap) */
  --nav-inset: 20px;     /* nav bar's equal inset from the hero's top/left/right edges */
  --nav-h: 66px;         /* nav bar height */
}

/* ---------- page frame (the design wraps everything in .page, max 1440px centred) ----------
   No overflow:hidden here — our nav is a global element OUTSIDE this wrapper, and the hero's
   -mt-[86px] overhang must stay visible (clipping would cut the top of the hero). */
/* The page (and therefore every Section) spans the full site width. The 1440px
   content frame is applied per-container (Container width) / per-content
   (.b-content), NOT here — so a Section's background reaches the window edges and
   a container can never extend beyond its Section. */
.b-page { width: 100%; position: relative; overflow-x: clip; }
/* Global guard: any stray horizontal overflow (anywhere, incl. nav/footer which
   sit outside .b-page) makes phones zoom the whole page out to fit — which makes
   everything look big and defeats the responsive breakpoints. `clip` is
   sticky-safe (unlike `hidden`, it won't break the sticky nav). */
html, body { overflow-x: clip; max-width: 100%; }

/* ---------- layout wrapper (responsive: fixed 1400px on desktop, fluid below) ---------- */
.b-content { width: 100%; max-width: 1400px; margin: 0 auto; padding: 0 clamp(20px, 5vw, 60px); }
.b-section { padding: clamp(56px, 8vw, 110px) 0; }
.b-section--tight { padding: clamp(40px, 5vw, 60px) 0; }
/* No top padding (e.g. Products, which sits right under its own heading). The
   editor's Advanced → Spacing → Padding top can still add space if wanted. */
.b-section--flush-top { padding-top: 0; }
.b-section--flush-bottom { padding-bottom: 0; }

/* ---------- type ---------- */
/* font-size: var(--fs, <default>) so the Advanced styling → Text "Text size"
   override (emitted as --fs on the block wrapper) reaches the text; unset → the
   original default. */
/* Card "Text size" control (feature/solutions/stat/info cards set this on their
   root): a multiplier applied to text below. Default 1 → no change anywhere. */
.b-tscale--sm { --tscale: .86; }
.b-tscale--lg { --tscale: 1.16; }
.b-tscale--xl { --tscale: 1.32; }
.b-h1 { font-family: var(--sans); font-weight: 200; font-size: calc(var(--fs, clamp(48px, 7vw, 96px)) * var(--tscale, 1)); line-height: 1.0; letter-spacing: -1px; }
.b-h1 .em { font-weight: 500; }
.b-h2 { font-family: var(--sans); font-weight: 200; font-size: calc(var(--fs, clamp(32px, 4vw, 48px)) * var(--tscale, 1)); line-height: 1.3; }
.b-h2 .em { font-weight: 500; }
.b-h3 { font-family: var(--sans); font-weight: 200; font-size: calc(var(--fs, clamp(24px, 3vw, 32px)) * var(--tscale, 1)); line-height: 1.3; }
/* The prototypes' `.product-name` display size (72px at 1440), used for a
   product / variant name rather than an ordinary section heading. This rule
   already carried the right values but was wired to nothing: HeadingBlock has
   no custom-class field, so the only way to reach it without adding one is to
   name the sections where the design uses it — the illuminator showcase bands,
   whose anchors the seed derives from the platform name. */
.b-product-name,
#neptune-showcase .b-h2,
#luna-showcase .b-h2 { font-family: var(--sans); font-weight: 200; font-size: var(--fs, clamp(44px, 6vw, 72px)); line-height: 1.3; }
/* font-family: inherit so a per-block Font-family override (Advanced styling →
   Text) actually reaches the paragraph text; defaults to the body's --sans. */
/* The prototypes' shared lead atom is a flat 20px at weight 400, faded to
   --ink-70 when it is a section lead (_shared `.lead{font-weight:400;
   font-size:20px; line-height:1.5}`, `.sec-lead{… color:var(--ink-70)}`).
   Ours was 300 weight, clamp(18-22px) and full ink. GLOBAL on purpose: every
   prototype uses that one atom, so the same values are right on every page.
   Fading currentColor rather than hard-coding a black keeps a lead on a dark
   band light (the design does the same thing there with a white color-mix),
   and a per-block Text colour / size still wins through --fs and the wrapper. */
.b-lead {
    font-family: inherit; font-weight: 400;
    font-size: calc(var(--fs, 20px) * var(--tscale, 1)); line-height: 1.5;
    color: color-mix(in srgb, currentColor 70%, transparent);
}
/* On a dark band the prototypes lift the lead to 82% white over the deep navy,
   rather than the 70% fade they use on light sections. */
.dark-section .b-lead { color: color-mix(in srgb, var(--white) 82%, var(--deep-navy)); }
.b-body { font-family: inherit; font-weight: 300; font-size: calc(var(--fs, clamp(15px, 1.7vw, 18px)) * var(--tscale, 1)); line-height: 1.6; }
.b-eyebrow { font-family: var(--mono); font-weight: 500; font-size: 14px; color: var(--navy); text-transform: uppercase; letter-spacing: .5px; }
.b-caption { font-family: var(--mono); font-weight: 300; font-size: 14px; opacity: .5; }
/* Inline code in rich text — monospace chip (the design's mono technical labels). */
code { font-family: var(--mono); font-size: .9em; background: color-mix(in srgb, var(--navy) 8%, transparent); padding: .1em .4em; border-radius: 5px; }
/* Blockquote in rich text — accent bar + softened text. */
blockquote { margin: 1.2em 0; padding: .2em 0 .2em 1.1em; border-left: 3px solid color-mix(in srgb, var(--cyan) 70%, transparent); font-style: italic; opacity: .85; }

/* ---------- pill / chip ---------- */
.b-pill { display: inline-flex; align-items: center; height: 40px; padding: 0 21px; background: var(--navy); color: var(--white); border-radius: var(--r-md); font-family: var(--mono); font-weight: 500; font-size: 16px; letter-spacing: .2px; }
/* Pill / Eyebrow → Alignment (PillBlock.align). The pill is inline, so text-align
   on its wrapper positions it; default (no modifier) is left. */
.b-pill-align--center { text-align: center; }
.b-pill-align--right { text-align: right; }
.b-chip { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 14px; background: var(--navy); color: var(--white); border-radius: var(--r-pill-sm); font-weight: 600; font-size: 12px; }
.b-chip .b-ar { width: 11px; height: 11px; }

/* ---------- rgb strip + inline arrow ---------- */
.b-rgb-strip { height: 10px; border-radius: 5px; background: var(--rgb-spectrum); }

/* ── Timeline (TimelineBlock) — milestone grid for the "Milestones" band ─────
   A row of nodes on a faint connector line: dot, mono year, light title, muted
   caption. Colours are theme-tokenised so the
   block works on light OR dark — the .dark-section override (below) flips them
   to white for the deep-navy band. */
.b-timeline {
    --tl-dot: var(--navy);
    --tl-line: linear-gradient(90deg, rgba(28,47,118,.35), rgba(28,47,118,.12));
    --tl-year: var(--navy);
    --tl-title: #000;
    --tl-cap: rgba(0,0,0,.6);
}
.b-timeline__track {
    position: relative;
    display: grid;
    grid-template-columns: repeat(var(--tl-n, 5), minmax(0, 1fr));
    gap: 28px;
}
/* Faint connector line across the row of dots (desktop only). */
@media (min-width: 1024px) {
    .b-timeline__track::before {
        content: "";
        position: absolute;
        top: 7px;
        left: 6px;
        right: 6px;
        height: 2px;
        background: var(--tl-line);
    }
}
.b-timeline__node { position: relative; padding-top: 40px; }
.b-timeline__dot {
    position: absolute;
    top: 0;
    left: 0;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--tl-dot);
}
.b-timeline__year {
    font-family: var(--mono);
    font-weight: 500;
    font-size: 15px;
    letter-spacing: .5px;
    color: var(--tl-year);
    margin-bottom: 10px;
}
.b-timeline__title {
    font-weight: 300;
    font-size: 21px;
    line-height: 1.25;
    color: var(--tl-title);
    margin-bottom: 8px;
}
.b-timeline__cap {
    font-weight: 400;
    font-size: 14px;
    line-height: 1.5;
    color: var(--tl-cap);
}
@media (max-width: 1023px) {
    .b-timeline__track { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 36px 28px; }
}
@media (max-width: 600px) {
    .b-timeline__track { grid-template-columns: 1fr; }
}
/* ── Dark section (Advanced → Background → Colour scheme = Dark) ──────────────
   Light text on a dark band. When a background image is also set, a vertical
   scrim keeps text legible over it (the wrapper carries the image; the scrim is
   a -1 layer above it, below content). Used by the About "Milestones" band. */
/* Broadened from .block-styled.dark-section so it also matches when the class is
   scoped to a Container's contained card (container.html) rather than the
   full-bleed wrapper — a container's colour scheme stays inside its own card. */
.dark-section { color: #fff; }
/* Legibility scrim only when the dark section carries a background IMAGE (a
   solid-colour dark card needs no overlay). */
.block-styled.dark-section--scrim { position: relative; isolation: isolate; }
.block-styled.dark-section--scrim::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: linear-gradient(180deg, rgba(5,4,22,.55), rgba(5,4,22,.82));
}
.dark-section .b-text-navy { color: #fff; }
.dark-section .b-lead,
.dark-section .b-body { color: rgba(255,255,255,.72); }
/* Container styled as a card: its background colour paints the width-constrained
   grid (see container.html), with comfortable interior padding; "rounded corners"
   adds the radius and clips the columns (e.g. an image) to it. */
.b-container-card { padding: clamp(28px, 4vw, 56px); }
.b-container-card--rounded { border-radius: clamp(18px, 2vw, 28px); overflow: hidden; }
/* Tablet/phone: non-fluid containers keep a side gutter so cards/borders never
   touch the screen edge.
   NOTE: this used to claim "desktop is unaffected — there the viewport exceeds the
   container's max-width". That only holds ABOVE the container width, and the
   container defaults to 72rem/1152px (pages also use 84rem/1344px) — both well over
   1024. A container self-centres via max-width + mx-auto, so its gutter is only the
   leftover space; between 1025px and its own max-width there IS no leftover and
   content ran flush to the viewport edge. The min-width:1025px rule below covers
   that band; this block stays phone/tablet-only so its tuned values don't change. */
@media (max-width: 1024px) {
    /* A small, even side gutter so cards/borders don't touch the screen edge,
       while still using most of the phone/tablet width. */
    .fedit-grid:not(.is-fluid) { width: calc(100% - 12px); }
    /* The form's 780px cap leaves big side gaps on larger phones/tablets — let it
       fill its container like the map does. */
    .b-formsec { max-width: none; }
    /* Inside a tabs panel: don't double-inset. Drop the .b-content side padding
       (the container gutter already handles edges) and let the inner container
       fill + stay centred. */
    [data-b-tabs] .b-content { padding-left: 0; padding-right: 0; }
    .b-tabpanel .fedit-grid:not(.is-fluid) { width: 100%; margin-inline: auto; }
}
/* Desktop widths NARROWER than the container's own max-width (1025px up to
   72rem/84rem — i.e. most laptops) get no gutter from mx-auto centring, because
   there's no leftover space to centre with. Constrain the width instead of adding
   padding-inline: max-width still wins once the viewport clears it, so the 48px cap
   is chosen so 1440px lands exactly on an 84rem container (1440 - 96 = 1344) and
   wide desktop stays pixel-identical. is-fluid (Container width = none) opts out. */
@media (min-width: 1025px) {
    .fedit-grid:not(.is-fluid) { width: calc(100% - 2 * clamp(24px, 4vw, 48px)); }
}
/* Timeline flips to white-on-dark inside a dark section. */
.dark-section .b-timeline {
    --tl-dot: #fff;
    --tl-line: linear-gradient(90deg, rgba(255,255,255,.30), rgba(255,255,255,.10));
    --tl-year: rgba(255,255,255,.9);
    --tl-title: #fff;
    --tl-cap: rgba(255,255,255,.6);
}
.b-ar { width: 1em; height: 1em; display: inline-block; flex: none; } /* inline ↗ via currentColor */

/* ---------- buttons ---------- */
.b-cta { display: inline-flex; align-items: center; justify-content: center; gap: 10px; height: 60px; padding: 0 32px; border-radius: var(--r-cta); font-family: var(--sans); font-weight: 400; font-size: 20px; cursor: pointer; border: none; text-align: center; transition: background-color .18s ease, border-color .18s ease, color .18s ease, transform .18s ease, box-shadow .18s ease; }
.b-cta--dark { background: var(--black); color: var(--white); }
.b-cta--light { background: var(--white); color: var(--black); }
.b-cta--outline { background: transparent; color: var(--navy); border: 1px solid var(--stroke-black); border-radius: var(--r-learn); }
/* Hover affordance for button CTAs (issue #17 — "Read more" had none): a subtle
   lift + per-variant tint, and the arrow nudges along its diagonal. */
.b-cta--dark:hover, .b-cta--light:hover, .b-cta--outline:hover { transform: translateY(-2px); box-shadow: 0 12px 26px -14px rgba(28, 47, 118, .38); }
.b-cta--dark:hover { background: color-mix(in srgb, var(--black) 82%, var(--navy)); }
.b-cta--light:hover { background: var(--snow); }
.b-cta--outline:hover { background: color-mix(in srgb, var(--navy) 7%, transparent); border-color: var(--navy); }
.b-cta--dark:hover .b-ar, .b-cta--light:hover .b-ar, .b-cta--outline:hover .b-ar { transform: translate(3px, -3px); }
/* Text-link variant: no button chrome — a mono uppercase link (matches .dl-more). */
.b-cta--link { height: auto; padding: 0; background: transparent; border: none; border-radius: 0; color: var(--navy); font-family: var(--mono); font-weight: 500; font-size: 14px; text-transform: uppercase; letter-spacing: .5px; }
.b-cta--link:hover { text-decoration: underline; }
.b-cta .b-ar { width: 18px; height: 18px; transition: transform .18s ease; }
/* Size variants (md = the base above). */
.b-cta--sm { height: 46px; padding: 0 22px; font-size: 15px; gap: 8px; }
.b-cta--sm .b-ar, .b-cta--sm .b-cta__ico { width: 14px; height: 14px; font-size: 14px; }
.b-cta--lg { height: 70px; padding: 0 40px; font-size: 22px; gap: 12px; }
.b-cta--lg .b-ar, .b-cta--lg .b-cta__ico { width: 22px; height: 22px; font-size: 22px; }
/* Download card (DownloadBlock) — file-type icon tile, title + type/status, download glyph. */
.b-dl { display: flex; align-items: center; gap: 18px; padding: 24px 26px; border: 2px solid var(--navy); border-radius: 20px; background: #fff; transition: background .15s ease; text-decoration: none; }
.b-dl:hover { background: #f2f4f8; }
/* .dl__icon in the prototypes is a NAVY tile pinned to the TOP of the row, not a
   black one centred against it. (The doc glyphs hard-code a white stroke rather
   than currentColor: caonyx_icon renders svg: icons as an <img>, and an
   img-loaded SVG cannot inherit colour from the page — same convention as the
   existing kf-* white line glyphs.) */
/* `color` is the icon colour for BOTH an <i> and a masked .cx-icon--mono — the
   navy tile needs a white glyph. */
.b-dl__icon { flex: none; align-self: flex-start; width: 48px; height: 48px; border-radius: 10px; background: var(--navy); color: var(--white); display: flex; align-items: center; justify-content: center; }
.b-dl__icon .cx-icon { width: 22px; height: 22px; }
.b-dl__meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.b-dl__title { display: block; font-weight: 400; font-size: 20px; line-height: 1.25; color: #000; }
.b-dl__type { display: block; font-family: var(--mono); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: var(--navy); }
.b-dl__dl { flex: none; width: 24px; height: 24px; color: var(--navy); }
@media (max-width: 640px) {
    .b-dl { gap: 11px; padding: 12px 14px; border-radius: 12px; }
    .b-dl__meta { gap: 4px; }
    .b-dl__icon { width: 32px; height: 32px; border-radius: 7px; }
    .b-dl__icon .cx-icon { width: 16px; height: 16px; }
    .b-dl__title { font-size: 14px; }
    .b-dl__type { font-size: 10px; }
    .b-dl__dl { width: 18px; height: 18px; }
}
/* Tablet only: no tablet rule existed, so download cards stayed desktop-sized
   (48px icon, 20px title) and read a bit large. Sit them between desktop (above)
   and mobile (≤640, above) — both already sized, leave as is. */
@media (min-width: 641px) and (max-width: 1024px) {
    .b-dl { gap: 14px; padding: 16px 18px; border-radius: 16px; }
    .b-dl__meta { gap: 5px; }
    .b-dl__icon { width: 40px; height: 40px; border-radius: 9px; }
    .b-dl__icon .cx-icon { width: 18px; height: 18px; }
    .b-dl__title { font-size: 16px; }
    .b-dl__type { font-size: 11px; }
    .b-dl__dl { width: 20px; height: 20px; }
}
.b-cta__ico { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; }
.b-cta__ico i { font-size: inherit; line-height: 1; }

/* ---------- Solutions card (big floating card, RGB gradient border) ---------- */
/* No max-width — the card fills its column so the layout (column proportion /
   container width) controls its size, and it can sit flush to the column's edge. */
/* border-radius order: top-left top-right bottom-right bottom-left — the big
   notch sits on the bottom-RIGHT (matches the design's rounded-br-[100px]). */
.b-sol-card-wrap { position: relative; width: 100%; padding: 1.5px; border-radius: 22px 22px 102px 22px; background: linear-gradient(135deg, var(--navy) 0%, var(--cyan) 38%, var(--green) 70%, var(--red) 100%); box-shadow: 0 40px 100px rgba(5, 4, 22, .45); }
/* When flares are added, the card hosts them: clip to its own (notched) shape and
   isolate so each flare stays inside the card, at whichever layer it chose. */
.b-sol-card--flares { position: relative; isolation: isolate; overflow: hidden; }
.b-sol-card { display: flex; flex-direction: column; background: var(--snow); border-radius: 20px 20px 100px 20px; padding: clamp(30px, 3.6vw, 56px); }
.b-sol-card .b-sol-list { display: flex; flex-direction: column; gap: 22px; margin-top: 14px; list-style: none; padding: 0; color: color-mix(in srgb, var(--navy) 82%, transparent); }
.b-sol-cta { margin-top: 26px; }
.b-sol-item { display: flex; align-items: center; gap: 16px; }
.b-sol-ic { flex: none; width: 42px; height: 42px; border-radius: 11px; background: var(--theme-color-5); color: var(--white); display: flex; align-items: center; justify-content: center; }
.b-sol-ic i { font-size: 18px; line-height: 1; }
/* SVG icons (CaonyxIconBlock "svg:" and "doc:" values), sized by their tile. */
.cx-icon { display: block; width: 24px; height: 24px; object-fit: contain; }
/* An icon mark can never outgrow the tile that frames it.
   Tile sizes shrink at the tablet/phone breakpoints, but several mark sizes are
   pinned by UNCONDITIONAL variant rules — .kfcard's 38px mark below is a
   5-class selector, the breakpoint override is `.b-card__glyph .cx-icon` with 2.
   A media query adds no specificity, so the variant kept winning on phones and
   a 38px glyph sat in a 32px tile, spilling over its rounded border.
   Capping against the tile fixes every such pair at once (and any future one)
   instead of restating each variant size at each breakpoint. 66% is just above
   the largest ratio any tile authors today (38/60 ≈ 63%), so nothing that fits
   at desktop is touched — it only engages once the tile has shrunk past it.
   The global cap is 100% (pure containment, no visual change anywhere — some
   marks legitimately fill their box edge-to-edge, e.g. the borderless
   .b-tabpanel .b-usp__ico); the 66% inset is scoped to the framed card glyph,
   where every authored ratio is already below it. */
.cx-icon { max-width: 100%; max-height: 100%; }
.b-card__glyph .cx-icon { max-width: 66%; max-height: 66%; }
/* Two flavours, decided per file by caonyx_icon (see cv/templatetags/caonyx_icons.py):
   - COLOURED (rgb-*, custom-*, tech-*, the RGB card glyphs…) stay an <img> and
     keep the brand colours they were authored in.
   - MONOCHROME (doc-*, kf-*, bullet-*, and editor-uploaded icons, which export
     black by default) come through as a <span> that paints currentColor through
     a mask of the artwork. That makes them inherit the tile's `color` exactly
     like a FontAwesome <i> does, instead of being stuck at whatever the file
     baked in — an <img> can't be recoloured by CSS at all.
   So every icon tile must set a `color`; that one declaration now drives both
   the <i> and the SVG path. */
.cx-icon--mono {
    background: currentColor;
    -webkit-mask: var(--cx-mask) center / contain no-repeat;
    mask: var(--cx-mask) center / contain no-repeat;
}
.b-sol-ic .cx-icon { width: 22px; height: 22px; }
/* Item text is a Text/Paragraph atom; inherit the list colour unless the item's
   own Advanced → Text colour overrides it. Reset the paragraph margins so it
   lines up with the icon chip. */
.b-sol-item__text { font-weight: 400; font-size: 18px; line-height: 1.35; color: inherit; }
.b-sol-item__text p { margin: 0; }
@media (max-width: 560px) { .b-sol-card-wrap { border-radius: 18px 18px 64px 18px; } .b-sol-card { border-radius: 16px 16px 62px 16px; } }

/* ---------- notched feature/USP/value card ---------- */
/* aspect-ratio keeps the card's proportion; overflow is VISIBLE so the text is
   never clipped — the card grows past the ratio when the text is longer. The
   image + overlay clip themselves to the card shape via border-radius: inherit,
   so only they are rounded, not the (grow-able) text. */
.b-card { position: relative; width: 100%; max-width: 380px; min-width: 0; aspect-ratio: 38 / 50; min-height: max-content; padding: 30px; border-radius: var(--notch); border: 2px solid var(--white); overflow: visible; background: var(--snow); display: flex; flex-direction: column; color: var(--white); }
.b-card--img { color: var(--white); }
.b-card--img .b-card__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; z-index: 0; }
.b-card--img .b-card__overlay { position: absolute; inset: 0; background: var(--card-overlay); border-radius: inherit; z-index: 1; }
/* Hairline border, not a solid navy rule. No prototype draws a heavy navy
   outline on a card: .ctbox uses --hair (rgba(28,47,118,.14)), .usp has no
   border at all. The 2px navy was ours and read as a much harder box. */
.b-card--outline { background: var(--white); color: var(--black); border-color: color-mix(in srgb, var(--navy) 14%, transparent); }
/* Card rows keep every card the same size. A centre-aligned row sets the grid's
   justify-items:center, which shrink-wraps each cell to its content — so a card
   with less text (e.g. the 3rd, alone on tablet) ends up narrower, and via the
   38/50 aspect-ratio, shorter. Force each cell to fill its column and centre the
   card within it (capped at its max-width) so all cards share the same width, and
   therefore the same aspect-ratio height. */
.b-cardgrid > .min-w-0 { justify-self: stretch; width: 100%; }
.b-cardgrid .b-card { margin-inline: auto; }
/* Row → Layout → "Equal size". Grid tracks already give equal WIDTH; grid cells
   already stretch to the tallest, so equal HEIGHT only needs the child to fill
   its cell. Make each cell a flex box whose single child stretches both axes, and
   pin any nested style wrapper + card to full height so the stretch reaches the
   card through its wrappers. General over any child block, not just cards. */
.b-row-equal > .min-w-0 { display: flex; }
.b-row-equal > .min-w-0 > * { flex: 1 1 auto; min-width: 0; height: 100%; }
.b-row-equal > .min-w-0 .block-styled,
.b-row-equal > .min-w-0 .b-card { height: 100%; }
/* Cards next to each other line up: equal height AND a shared glyph/title/body
   baseline, so every card's body starts on the same line even when titles wrap to
   a different number of lines. A subgrid makes the title row auto-size to the
   tallest title across the row; the cell is display:contents so the card itself is
   the grid item that spans the three shared tracks. Only from 640px (where cards
   sit side-by-side; below that they stack and each is independent), only where
   subgrid is supported (else the cards keep the default flex flow), and NOT on
   cards carrying a kicker — those (USP / image cards) reorder their own parts and
   must keep their flex `order`. */
@media (min-width: 640px) {
    @supports (grid-template-rows: subgrid) {
        .b-cardgrid:not(:has(.b-card__kicker)) { grid-template-rows: auto auto 1fr; }
        .b-cardgrid:not(:has(.b-card__kicker)) > .min-w-0 { display: contents; }
        .b-cardgrid:not(:has(.b-card__kicker)) > .min-w-0 > .b-card {
            grid-row: span 3;
            display: grid;
            grid-template-rows: subgrid;
            grid-template-columns: minmax(0, 1fr);
        }
    }
}
/* GENERAL — centre a lone item that wraps alone into the last row of a 2-column
   layout, for EVERY such grid (not a per-section patch): the item spans the row
   but keeps one-column width and centres, instead of being stuck left. Each grid
   is listed at ITS OWN 2-col breakpoint. Add new grids here rather than writing a
   bespoke rule. (Strips whose items fill — .b-statstrip etc. — use flex-wrap +
   justify-content:center for the same effect.)
     · card grid: cards carry their own max-width + margin-inline:auto, so a full
       span already centres them (2-col range = sm..lg, 640-1023).
     · plain grid: cells have no intrinsic width, so cap the spanned cell to one
       column and centre it (2-col range = 601-1024). */
@media (min-width: 640px) and (max-width: 1023px) {
    .b-cardgrid > .min-w-0:last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 601px) and (max-width: 1024px) {
    .b-grid:not(.b-grid--auto):not(.b-grid--members) > .b-grid__cell:last-child:nth-child(odd) {
        grid-column: 1 / -1; justify-self: center; width: calc((100% - 20px) / 2);
    }
}
/* The "Who to talk to" routes compress to a 2-column grid wherever .b-grid goes
   2-up (max-width:1024), so the fixed 5rem (pb-20) below them read as an outsized
   gap before the form. Trim it across that whole range — matching the .b-grid
   breakpoint so iPad-landscape (exactly 1024px) is covered too. */
@media (min-width: 601px) and (max-width: 1024px) {
    .block-styled.pb-20:has(.b-route) { padding-bottom: 2.5rem; }
}
/* Card height options (editor-controlled). Default keeps the 38/50 ratio. Compact
   is a moderate reduction with a smaller corner notch so the outline reads cleanly
   at small sizes. */
.b-card--h-compact { aspect-ratio: 1 / 1.08; border-radius: 16px 16px 52px 16px; }
/* Notch matches the prototypes: .ctbox 20/20/60/20, .igcard (the rgb-outlined
   slider card) has a deeper 100px sweep. */
.b-card--h-auto { aspect-ratio: auto; min-height: 0; border-radius: 20px 20px 60px 20px; }
.b-card--rgb.b-card--h-auto { border-radius: 20px 20px 100px 20px; }
/* The products "why Brilliance" card (.usp). It is the ONLY card in any of the
   twelve prototypes that carries a drop shadow, and the only one with a flat
   20px radius and no notch — so this is deliberately NOT a global .b-card
   rule. The plain-outline + auto-height combination matches exactly these
   three cards site-wide and nothing else (the visually similar illuminator
   and technology cards all set rgb_outline or accent_bar). Borderlessness
   already comes from the seed writing #FFFFFF into background_color, which
   the template also applies to border-color. */
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) {
    border-radius: 20px;
    box-shadow: 0 24px 48px -24px rgba(28, 47, 118, .22);
}
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__title {
    font-size: calc(clamp(22px, 2.2vw, 28px) * var(--tscale, 1));
}
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__body {
    font-size: calc(16px * var(--tscale, 1)); line-height: 1.5;
}
/* .usp__glyph: 56px, 14px radius, black, and no white ring. */
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__glyph {
    width: 56px; height: 56px; border-radius: 14px; border: 0;
}
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__glyph .cx-icon {
    width: 27px; height: 27px;
}
/* USP cards only: drop the kicker BELOW the glyph (icon -> BRIGHTER -> title).
   The template emits kicker before glyph for every feature card, so we re-sequence
   with flex `order` here rather than in the shared HTML — image cards keep their
   "01" kicker on top. The glyph's own 18px margin-bottom (h-auto) sets the
   icon->label gap; the kicker just needs a tight gap down to the title. */
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__glyph  { order: 0; }
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__kicker { order: 1; margin-bottom: 6px; }
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__title  { order: 2; }
.b-card--outline.b-card--h-auto:not(.b-card--rgb):not(.b-card--bar) .b-card__body   { order: 3; }
/* In a Grid CELL an auto-height card stretches to the row, so a trio of cards
   with different copy lengths still ends up the same height — the prototype's
   `.usp` cards do this because grid items stretch by default. Without it the
   Products USP row rendered 330px / 422px / 330px. */
/* `.b-grid` sets `align-items: start`, so a cell is only as tall as its content
   and `height: 100%` on the card resolves against that — the card cannot reach
   the row height on its own. Stretch the CELL first, scoped with :has() to cells
   that actually hold an auto-height card so every other grid (route cards,
   downloads, accordions) keeps the existing top-aligned behaviour. */
.b-grid__cell:has(.b-card--h-auto) { align-self: stretch; }
.b-grid__cell .b-card--h-auto { height: 100%; }
/* Same problem, the OTHER two containers an auto-height card can land in.
   The prototypes get equal heights for free (.coretech is a grid, .igtrack a
   flex row — both stretch their children by default); ours has the card
   several content-height wrappers deep, so the row height never reaches it.
   Every rule is :has()-scoped to wrappers that actually hold such a card, so
   ordinary rows and slides keep their content height.

   1. Card grid inside a layout column (technology "core technology" trio). */
.fedit-grid > .block-styled:has(.b-cardgrid .b-card--h-auto) { height: 100%; }
.fedit-grid > .block-styled:has(.b-cardgrid .b-card--h-auto) > .min-w-0 { height: 100%; }
.min-w-0 > .block-styled:has(.b-cardgrid .b-card--h-auto) { flex: 1 1 auto; }
.b-cardgrid:has(.b-card--h-auto) { height: 100%; }
.b-cardgrid > .min-w-0:has(.b-card--h-auto) { align-self: stretch; height: 100%; }
.b-cardgrid .b-card--h-auto { height: 100%; }
/* 2. Slider slides (technology "integration gallery"). */
.b-slide:has(.b-card--h-auto) { display: flex; }
.b-slide > .b-card--h-auto { height: 100%; }
/* Compact/auto cards have no free space for the glyph's margin-bottom:auto to push
   content down, so it collapses and the glyph touches the title — pin a fixed gap. */
/* (--h-auto / --h-compact used to need their own glyph margin to escape the
   base rule's `margin-bottom: auto`; the base now carries the same fixed value,
   so every card height shares it and this override is no longer needed.) */
/* TWO different prototype cards share the rgb-outline + auto-height combination,
   so neither can be styled on that pair alone:
     .igcard  (technology "integration") — 240-300px slides, 52px deep-navy glyph
     .kfcard  (illuminator key features) — 300-452px slides, 60px black glyph
   The design's own distinction is the slide width, which we already model as the
   slider's `slide_width` → .b-slider__track--narrow. So: the general slider case
   is .kfcard, and the narrow track overrides it to .igcard. The narrow selector
   carries an extra class so it wins on specificity, not on source order. */

/* .kfcard — glyph is the 60px black default, minus the white ring, with a
   larger 38px mark. */
.b-slider__track .b-card--rgb.b-card--h-auto .b-card__glyph { border: 0; }
.b-slider__track .b-card--rgb.b-card--h-auto .b-card__glyph .cx-icon { width: 38px; height: 38px; }
.b-slider__track .b-card--rgb.b-card--h-auto { box-shadow: 8px 8px 32px rgba(0, 0, 0, .18); }

/* .igcard — 52px, 12px radius, deep-navy fill, no ring, and no shadow. */
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto { box-shadow: none; }
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto .b-card__glyph {
    width: 52px; height: 52px; border-radius: 12px;
    background: var(--deep-navy); border: 0;
}
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto .b-card__glyph .cx-icon { width: 26px; height: 26px; }
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto .b-card__glyph i { font-size: 22px; }
/* Card body: honour line breaks so a multi-line body reads as a bullet list. */
.b-card__body { white-space: pre-line; }
/* Text must ALWAYS wrap to the card and never spill past its edge, in any layout
   (grid cell, flex rail, or a shrink-wrapping ancestor). min-width:0 lets a flex
   item shrink below its content's intrinsic width instead of flooring there and
   forcing the whole card wider than its column; overflow-wrap breaks the rare
   token too long for the resulting width. Paired with .b-card{min-width:0} above. */
.b-card__title, .b-card__body { min-width: 0; max-width: 100%; overflow-wrap: break-word; }
/* Body copy sits at 70% ink in EVERY prototype (.usp__body, .ctbox__d and
   .igcard__text all use --ink-70: rgba(0,0,0,.7)); ours was rendering pure
   black. Fading currentColor rather than hard-coding a black keeps this
   correct on image/dark cards, where the body must fade from white instead. */
.b-card__body { color: color-mix(in srgb, currentColor 70%, transparent); }
/* …except the photo cards, whose `.card__body` in the prototypes declares no
   colour and so stays the card's full white. Fading those was a regression
   introduced with the rule above. */
.b-card--img .b-card__body { color: var(--white); }
/* Type scale for the two compact card types on the technology page. Scoped to
   the variant rather than to --h3, so the larger feature cards elsewhere keep
   the 30px/20px base. Sizes are the prototypes' own:
     accent-bar card  = .ctbox  (21px / 15px, line-height 1.55)
     rgb-outline card = .igcard (20px / 14px, line-height 1.5) */
.b-card--bar.b-card--h-auto .b-card__title { font-size: calc(21px * var(--tscale, 1)); }
.b-card--bar.b-card--h-auto .b-card__body { font-size: calc(15px * var(--tscale, 1)); line-height: 1.55; }
/* .kfcard (illuminator key features): 300-weight clamp(24,2.4vw,30) title over a
   16px bullet list at --ink-80. */
.b-slider__track .b-card--rgb.b-card--h-auto .b-card__title {
    font-size: calc(clamp(24px, 2.4vw, 30px) * var(--tscale, 1)); font-weight: 300;
}
.b-slider__track .b-card--rgb.b-card--h-auto .b-card__body {
    font-size: calc(16px * var(--tscale, 1)); line-height: 1.5;
    color: rgba(0, 0, 0, .82);
}
/* .igcard (technology integration) overrides the above on the narrow track. */
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto .b-card__title {
    font-size: calc(20px * var(--tscale, 1));
}
.b-slider__track.b-slider__track--narrow .b-card--rgb.b-card--h-auto .b-card__body {
    font-size: calc(14px * var(--tscale, 1)); line-height: 1.5;
    color: color-mix(in srgb, currentColor 70%, transparent);
}
/* RGB gradient OUTLINE only (editor-controlled): a masked ring draws the gradient
   in the 2px border, not behind the card body — so the fill (var(--card-fill),
   coverflow-alpha-aware) stays clean. */
.b-card--rgb { border: 0; background: var(--card-fill, var(--white)); }
.b-card--rgb::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 2px; pointer-events: none; z-index: 1;
    background: linear-gradient(90deg, var(--navy) 0%, var(--cyan) 40%, var(--green) 74%, var(--red) 100%);
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor; mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude; }
/* The glyph used to carry `margin-bottom: auto`, which on a fixed-aspect-ratio
   card swallowed all the free space below it and pushed the title + body to the
   card's bottom edge. That made a title's position a function of how much body
   text sat underneath it, so across a row of cards no two titles lined up — a
   card with no body sat lowest, one with a long body sat highest.
   A fixed margin instead: glyph and title land in the same place in every card
   and the body grows downward, with the slack at the bottom. This is the value
   --h-auto and --h-compact already used, so all card heights now agree.
   Complements the .b-cardgrid subgrid above: that shares row tracks between
   side-by-side cards, this stops the text floating inside each card. Card grids
   are --h-auto, which already used 18px, so they are unaffected. */
.b-card__glyph { position: relative; z-index: 2; width: 60px; height: 60px; border-radius: var(--r-sm); background: var(--black); color: var(--white); border: 2px solid var(--white); display: flex; align-items: center; justify-content: center; margin-bottom: 18px; }
/* Brand glyphs keep their authored RGB colours on the black glyph box (no invert,
   which mangled the colours and merged the white detail lines). */
.b-card__glyph .cx-icon { width: 28px; height: 28px; }
.b-card__title { position: relative; z-index: 2; font-weight: 300; font-size: calc(30px * var(--tscale, 1)); line-height: 1.2; margin-bottom: 10px; }
/* Title scales with its heading level (editor-chosen): H1 largest → H3 smallest.
   H3 keeps the base size above, so existing cards render unchanged. */
.b-card__title--h1 { font-size: calc(clamp(30px, 3.4vw, 40px) * var(--tscale, 1)); }
.b-card__title--h2 { font-size: calc(clamp(28px, 3vw, 34px) * var(--tscale, 1)); }
/* NB: do NOT give --h3 a size here. `card()` defaults every seeded card to
   title_level h3, so an --h3 rule is really a site-wide base override and it
   shrinks every card on Home/Neptune/Luna too. Per-card-type sizing belongs
   on the variant classes below. */
/* Clickable feature card (a link set on the block) — no underline, whole-card
   pointer, subtle lift on hover. */
.b-card--link { text-decoration: none; cursor: pointer; transition: transform .2s ease, box-shadow .2s ease; }
.b-card--link:hover { transform: translateY(-4px); box-shadow: 0 22px 40px -24px rgba(28, 47, 118, .4); }
.b-card__body { position: relative; z-index: 2; font-weight: 400; font-size: calc(20px * var(--tscale, 1)); line-height: 1.4; }
/* Inline layout: icon + title on one row, text fills the rest of the card. */
.b-card__head { position: relative; z-index: 2; display: flex; align-items: center; gap: 18px; margin-bottom: 18px; }
.b-card--inline .b-card__glyph { margin-bottom: 0; flex: none; }
.b-card--inline .b-card__head .b-card__title { margin-bottom: 0; }
.b-card--inline .b-card__body { flex: 1 1 auto; }

/* ---------- stat card ---------- */
.b-stat { display: flex; flex-direction: column; gap: 12px; }
.b-stat__num { font-weight: 400; font-size: clamp(48px, 6vw, 64px); line-height: 1.1; color: var(--navy); }
.b-stat__num span { font-size: .56em; }
.b-stat__label { font-weight: 400; font-size: 20px; color: #333; }
.b-stat__bar { width: 160px; max-width: 100%; height: 8px; border-radius: 4px; background: var(--rgb-spectrum); }

/* ---------- illuminator card (Products point/area CTA duo) ----------
   Transcribed from prototypes/products/index.html .illum: white card, 2px
   accent border, the deep bottom-right notch, black glyph tile, button inside.
   Colours reuse the same brand vars as .b-route--{cyan,green,red}. */
.b-illum { display: flex; flex-direction: column; gap: 18px; padding: 44px 40px;
           border-radius: 20px 20px 100px 20px; background: var(--white);
           border: 2px solid var(--navy); height: 100%; }
.b-illum--navy  { border-color: var(--navy); }
.b-illum--cyan  { border-color: var(--cyan); }
.b-illum--green { border-color: var(--green); }
.b-illum--red   { border-color: var(--red); }
.b-illum__glyph { width: 56px; height: 56px; border-radius: 14px; background: var(--black);
                  color: var(--white);
                  display: flex; align-items: center; justify-content: center; flex: none; }
.b-illum__glyph svg, .b-illum__glyph .cx-icon { width: 28px; height: 28px; }
.b-illum__glyph i { font-size: 24px; line-height: 1; }
.b-illum__title { font-weight: 200; font-size: clamp(26px, 2.6vw, 32px); line-height: 1.15; color: var(--black); }
.b-illum__body  { font-weight: 400; font-size: 17px; line-height: 1.5; color: rgba(0, 0, 0, .7); }
/* margin-top:auto pins the button to the card foot so a pair of cards with
   different copy lengths still line their buttons up. */
.b-illum__cta { margin-top: auto; }
@media (max-width: 1024px) { .b-illum { padding: 34px 30px; } }
@media (max-width: 640px)  { .b-illum { padding: 26px 22px; gap: 14px; border-radius: 16px 16px 64px 16px; }
                             .b-illum__glyph { width: 46px; height: 46px; border-radius: 12px; }
                             .b-illum__glyph svg, .b-illum__glyph .cx-icon { width: 23px; height: 23px; }
                             .b-illum__body { font-size: 15px; } }

/* ---------- laserchip toggle ---------- */
.b-toggle-wrap { display: inline-flex; padding: 1.5px; border-radius: 32px; background: linear-gradient(135deg, var(--navy) 0%, var(--cyan) 38%, var(--green) 70%, var(--red) 100%); }
.b-toggle { display: inline-flex; align-items: center; height: 60px; padding: 8px; border-radius: 30px; gap: 4px; background: var(--white); }
.b-toggle__seg { display: inline-flex; align-items: center; justify-content: center; height: 40px; padding: 0 24px; border-radius: var(--r-md); font-weight: 500; font-size: 16px; text-transform: uppercase; color: var(--navy); cursor: pointer; background: transparent; border: none; white-space: nowrap; }
.b-toggle__seg--active { background: var(--navy); color: var(--white); }
/* Tabs / Switcher panels: only the active one shows (initTabs toggles .is-active). */
.b-tabpanel { display: none; }
.b-tabpanel.is-active { display: block; }
.b-selector__hint { font-size: 16px; color: color-mix(in srgb, var(--navy) 65%, transparent); }

/* ---------- products switcher ---------- */
.b-prod-panel { display: none; }
/* Gallery a touch narrower so heading / description / stats get more room. */
.b-prod-panel.is-active { display: grid; grid-template-columns: 1fr 1.2fr; gap: clamp(32px, 4vw, 60px); align-items: center; }
/* Specs variant (image + tables): align the two columns to the top, not centre. */
.b-prod-panel--spec.is-active { align-items: start; }
/* Spec / Feature tables (Wagtail contrib TableBlock) — caption + key/value rows. */
.b-spectable { display: flex; flex-direction: column; }
.b-spectable__cap { font-family: var(--mono); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: var(--navy); margin-bottom: 8px; }
.b-spectable table { width: 100%; border-collapse: collapse; }
.b-spectable td, .b-spectable th { padding: 12px 6px; border-bottom: 1px solid color-mix(in srgb, var(--navy) 14%, transparent); font-size: clamp(14px, 1.6vw, 16px); line-height: 1.4; text-align: left; vertical-align: top; }
.b-spectable th { font-weight: 500; color: var(--navy); width: 45%; }
.b-spectable td { font-weight: 400; color: inherit; }
.b-spectable tr:last-child td, .b-spectable tr:last-child th { border-bottom: none; }
/* Design: Gray cards — each row a rounded grey card, all text black, small
   vertical gaps between rows. A divider line separates the caption from the rows. */
.b-spectable--cards .b-spectable__cap { border-bottom: 1px solid color-mix(in srgb, var(--navy) 18%, transparent); padding-bottom: 10px; margin-bottom: 12px; }
.b-spectable--cards table { border-collapse: separate; border-spacing: 0 8px; }
.b-spectable--cards td, .b-spectable--cards th { background: color-mix(in srgb, var(--navy) 6%, #f3f4f6); border: none; color: #000; padding: 13px 16px; }
.b-spectable--cards th { font-weight: 500; }
/* Design: Striped — alternating row tint, no divider lines. */
.b-spectable--striped td, .b-spectable--striped th { border-bottom: none; }
.b-spectable--striped tbody tr:nth-child(odd) > * { background: color-mix(in srgb, var(--navy) 5%, transparent); }

/* The illuminator showcase spec sheets are the prototypes' `.dtbl`, which the
   generic "lines" design does not match: rows are tinted on the odd row with
   --navy-tint rgba(28,47,118,.10) and carry NO divider, the caption is a 16px
   semibold sentence-case label over a full-width black rule (not a mono
   uppercase eyebrow), keys are black at 600 and values --ink-80.
   Scoped to the two showcase sections rather than to .b-spectable, because the
   same "lines" design is used by Neptune and the Products switcher, whose own
   prototypes were not part of this audit. */
#neptune-showcase .b-spectable td, #neptune-showcase .b-spectable th,
#luna-showcase .b-spectable td, #luna-showcase .b-spectable th {
    border-bottom: none; padding: 9px 16px;
}
#neptune-showcase .b-spectable tbody tr:nth-child(odd) > *,
#luna-showcase .b-spectable tbody tr:nth-child(odd) > * {
    background: color-mix(in srgb, var(--navy) 10%, transparent);
}
#neptune-showcase .b-spectable__cap,
#luna-showcase .b-spectable__cap {
    font-family: var(--sans); font-weight: 600; font-size: 16px;
    text-transform: none; letter-spacing: 0; color: #000;
    padding-bottom: 10px; margin-bottom: 0; border-bottom: 1px solid #000;
}
#neptune-showcase .b-spectable th, #luna-showcase .b-spectable th { font-weight: 600; color: #000; }
#neptune-showcase .b-spectable td, #luna-showcase .b-spectable td { color: rgba(0, 0, 0, .82); }

/* ---------- product comparison (TableBlock, design = Comparison cards) ----------
   Row-major CSS grid. Floating coloured cards per column (column-gap), with a
   full-width .b-cmp__rule (grid-column 1/-1) between each row drawing ONE
   continuous divider line that runs across the gaps between the cards. */
/* When a column centres its content (align-items:center), flex items shrink to
   their content width. Wide content (comparison / table / grid) should still fill
   the column — stretch the styled wrappers that contain them. */
.block-styled:has(.b-cmp-scroll),
.block-styled:has(.b-table-wrap),
.block-styled:has(.b-row-scroll-wrap),
.block-styled:has(.b-grid),
.block-styled:has([data-b-tabs]) { align-self: stretch; width: 100%; }
/* A horizontal-scroll Row nests inside Column → grid track. Grid/flex items
   default to min-width:auto, so the track grows to the row's full content width
   (1116px) and the section clips it instead of the row scrolling. min-width:0 on
   every ancestor lets the track shrink to the container, so overflow-x:auto on
   .b-row-scroll actually engages. */
.block-styled:has(.b-row-scroll-wrap),
.fedit-grid:has(.b-row-scroll-wrap) > .block-styled { min-width: 0; }

/* Container → Layout → "Stacking order: Right to left". Once the columns collapse
   into one track, reverse their reading order so the rightmost column comes first
   — for the common case of a heading living at the top of the right-hand column
   (spec table left, heading + features right), which otherwise lands in the
   middle of the phone view. `order` is used rather than `direction: rtl`, which
   flips the inline axis (and text/padding alignment) instead of the stack order.
   The container caps at 4 columns, so four explicit rules cover every case; the
   selector is scoped to `.block-styled` children so any edit-mode affordance the
   fedit JS injects into the grid is left alone. The two bands are emitted
   independently by container.html: the -md class only appears when the resolved
   tablet layout is genuinely a single track. */
@media (max-width: 639px) {
    .fedit-grid.b-stack-rtl > .block-styled:nth-child(1) { order: 4; }
    .fedit-grid.b-stack-rtl > .block-styled:nth-child(2) { order: 3; }
    .fedit-grid.b-stack-rtl > .block-styled:nth-child(3) { order: 2; }
    .fedit-grid.b-stack-rtl > .block-styled:nth-child(4) { order: 1; }
}
@media (min-width: 640px) and (max-width: 1023px) {
    .fedit-grid.b-stack-rtl-md > .block-styled:nth-child(1) { order: 4; }
    .fedit-grid.b-stack-rtl-md > .block-styled:nth-child(2) { order: 3; }
    .fedit-grid.b-stack-rtl-md > .block-styled:nth-child(3) { order: 2; }
    .fedit-grid.b-stack-rtl-md > .block-styled:nth-child(4) { order: 1; }
}

/* Native scrollbar hidden everywhere — on phones we draw our own always-visible
   draggable bar UNDER the table (.b-cmp-bar), synced in brilliance.js, because
   mobile overlay scrollbars auto-hide and can't be forced on. */
.b-cmp-scroll { overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none; }
.b-cmp-scroll::-webkit-scrollbar { display: none; }
.b-cmp-wrap { position: relative; }
.b-cmp-bar { display: none; }
@media (max-width: 768px) {
    .b-cmp-bar {
        display: block; height: 6px; margin: 12px 2px 0; padding: 0;
        background: color-mix(in srgb, var(--navy) 12%, transparent);
        border-radius: 999px; touch-action: none; cursor: pointer;
    }
    .b-cmp-bar.is-hidden { display: none; }
    .b-cmp-bar__thumb {
        display: block; height: 100%; width: 40%; min-width: 32px;
        background: color-mix(in srgb, var(--navy) 55%, transparent);
        border-radius: 999px; will-change: transform;
    }
    .dark-section .b-cmp-bar { background: rgba(255, 255, 255, .16); }
    .dark-section .b-cmp-bar__thumb { background: rgba(255, 255, 255, .6); }
}
/* Fill the container width; the label (1fr) column absorbs the extra space while
   the cards stay capped, so widening the table widens the left column. */
.b-cmp { display: grid; align-items: stretch; grid-template-columns: minmax(230px, 1fr) repeat(var(--cmp-n, 2), minmax(180px, 360px)); column-gap: 24px; row-gap: 0; min-width: 740px; width: 100%; max-width: 1120px; margin-inline: auto; }
/* The continuous divider — spans every column AND the gaps between them. */
.b-cmp__rule { grid-column: 1 / -1; height: 0; border-top: 1px solid color-mix(in srgb, var(--navy) 16%, transparent); background: none; }
/* Section rows: bold + larger label, no values. The split adds space + a divider
   line ABOVE the row, kept INSIDE the cells so the cards' side borders run
   through it (no cut-off). The thin inter-row rule is hidden there. */
/* Higher specificity (.b-cmp …) so these win over the base .b-cmp__lab /
   .b-ccard__cell rules (which are defined later in the file). */
.b-cmp .b-cmp__lab--strong { font-weight: 800; font-size: clamp(18px, 2.2vw, 22px); color: #000; }
.b-cmp .b-cmp__rule--hide { display: none; }
/* Section gap = space only (a normal continuous rule still draws the line above);
   no per-cell border, which would break at the column gaps. */
.b-cmp .b-cmp__lab--split, .b-cmp .b-ccard__cell--split { padding-top: 40px; }
.b-cmp .b-cmp__lab--split { align-items: flex-start; }
.b-cmp__corner { min-height: 0; }
.b-cmp__lab--corner { border: 0; min-height: 0; }
.b-cmp__lab { display: flex; align-items: center; min-height: 56px; padding: 8px 16px 8px 0; font-weight: 600; font-size: 16px; color: #000; }
/* Card pieces — accent border forms the floating card outline around a column;
   head rounds the top, foot rounds the bottom. */
/* Cards are white inside; the coloured flair is a corner glow on the head only,
   positioned via --flair-pos (editor: Card flair position). */
.b-ccard__head { min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; text-align: center; background-color: var(--white); border: 1px solid var(--cyan); border-bottom: 0; border-radius: 18px 18px 0 0; }
.b-ccard__cell { min-height: 56px; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; text-align: center; font-weight: 400; font-size: 16px; color: #000; background-color: var(--white); border-left: 1px solid var(--cyan); border-right: 1px solid var(--cyan); }
.b-ccard__foot { min-height: 64px; display: flex; align-items: center; justify-content: center; padding: 0 12px; text-align: center; font-weight: 500; font-size: 15px; letter-spacing: .5px; text-transform: uppercase; background-color: var(--white); border: 1px solid var(--cyan); border-top: 0; border-radius: 0 0 18px 18px; }
/* accent colours (border + head flair glow + foot text) */
.b-ccard__head--green, .b-ccard__cell--green, .b-ccard__foot--green { border-color: var(--green); }
.b-ccard__head--navy, .b-ccard__cell--navy, .b-ccard__foot--navy { border-color: var(--navy); }
.b-ccard__head--red, .b-ccard__cell--red, .b-ccard__foot--red { border-color: var(--red); }
.b-ccard__head--cyan { background-image: radial-gradient(135% 130% at var(--flair-pos, top left), color-mix(in srgb, var(--cyan) 46%, transparent), transparent 58%); }
.b-ccard__head--green { background-image: radial-gradient(135% 130% at var(--flair-pos, top left), color-mix(in srgb, var(--green) 46%, transparent), transparent 58%); }
.b-ccard__head--navy { background-image: radial-gradient(135% 130% at var(--flair-pos, top left), color-mix(in srgb, var(--navy) 34%, transparent), transparent 58%); }
.b-ccard__head--red { background-image: radial-gradient(135% 130% at var(--flair-pos, top left), color-mix(in srgb, var(--red) 46%, transparent), transparent 58%); }
.b-cmp--no-flair .b-ccard__head { background-image: none; }
.b-ccard__head--sky, .b-ccard__cell--sky, .b-ccard__foot--sky { border-color: var(--sky); }
.b-ccard__head--sky { background-image: radial-gradient(135% 130% at var(--flair-pos, top left), color-mix(in srgb, var(--sky) 46%, transparent), transparent 58%); }
.b-ccard__foot--sky { color: var(--sky); }
.b-ccard__foot--cyan { color: var(--cyan); }
.b-ccard__foot--green { color: var(--green); }
.b-ccard__foot--navy { color: var(--navy); }
.b-ccard__foot--red { color: var(--red); }
.b-ccard__name { font-family: var(--sans); font-weight: 200; font-size: clamp(22px, 2.6vw, 36px); line-height: 1.1; color: #000; }
.b-ccard__series { font-weight: 500; font-size: 13px; letter-spacing: .5px; text-transform: uppercase; color: rgba(0, 0, 0, .6); }
.b-cmp-ico { width: 22px; height: 22px; flex: none; }
.b-cmp-ico--yes { color: var(--green); }
.b-cmp-ico--no { color: var(--red); }
.b-cmp-dash { color: color-mix(in srgb, #000 45%, transparent); font-weight: 600; }
@media (max-width: 1023px) { .b-prod-panel.is-active { grid-template-columns: 1fr; } }
/* stat card (bordered, coloured numeral + RGB bar) */
/* Stats row: equal columns sized to however many stats there are (--stat-count). */
.b-stats { display: grid; gap: 20px; grid-template-columns: repeat(var(--stat-count, 3), minmax(0, 1fr)); }
/* Below tablet, let the stat cards get narrow and wrap so several fit per row
   instead of one full-width card per row. */
@media (max-width: 1024px) { .b-stats { gap: 12px; grid-template-columns: repeat(auto-fit, minmax(105px, 1fr)); } }
/* A row of stat cards (b-row--stats, tagged in row.html) stays on ONE line at
   EVERY width — flex no-wrap with equal, shrinkable cells — instead of the row
   grid's columns that wrapped them in the narrow switcher column. They live in a
   ~half-width container column that does not collapse on phones, so wrapping
   there put one card per line; we keep no-wrap and shrink padding/type instead. */
.b-row--stats { display: flex !important; flex-wrap: nowrap; align-items: stretch; gap: 16px; }
.b-row--stats > .min-w-0 { flex: 1 1 0; min-width: 0; display: flex; }
/* Stretch the intermediate style wrapper too, so the card fills the full cell
   height and all cards match even when a caption wraps to two lines. */
.b-row--stats .min-w-0 > .block-styled { flex: 1; display: flex; min-width: 0; }
/* Give the cards real presence on desktop; they still scale down (vw) for the
   narrower tablet column. Number + label group at the top, caption + bar drop
   to the bottom (margin-top:auto) so there's a clear gap under the label. */
.b-row--stats .b-pstat { min-height: clamp(172px, 15vw, 210px); padding: clamp(18px, 1.8vw, 26px); }
.b-row--stats .b-pstat__num { font-size: clamp(26px, 4vw, 60px); }
.b-row--stats .b-pstat__lead { font-size: clamp(15px, 2vw, 30px); }
/* Caption: fluid, always a step below the label; bottom-aligned with a minimum
   gap under the label. (Without an explicit size it fell back to the 16px base
   and grew larger than the label in the 641-1024 range, and wrapped.) */
.b-row--stats .b-pstat__sub { font-size: clamp(12px, 1.3vw, 16px); line-height: 1.3; margin-top: auto; padding-top: 10px; }
/* Phone: three cramped cards can't fit a caption on one line, so let the row
   wrap to 2-up (the lone third card grows to full width) — each card is now
   wide enough for the caption to sit on one line at a readable size. */
@media (max-width: 640px) {
    .b-row--stats { gap: 10px; flex-wrap: wrap; }
    .b-row--stats > .min-w-0 { flex: 1 1 calc(50% - 5px); }
    .b-row--stats .b-pstat { padding: 16px 14px; border-width: 1.5px; min-height: 168px; }
    .b-row--stats .b-pstat__num { font-size: clamp(32px, 9.5vw, 48px); }
    .b-row--stats .b-pstat__suffix { font-size: .52em; }
    .b-row--stats .b-pstat__lead { font-size: clamp(17px, 4.8vw, 22px); line-height: 1.15; }
    .b-row--stats .b-pstat__sub { font-size: clamp(13px, 3.6vw, 15px); line-height: 1.25; margin-top: 5px; }
}
/* Small phones: stack one per row so even the longest caption never wraps. */
@media (max-width: 430px) {
    .b-row--stats > .min-w-0 { flex-basis: 100%; }
    .b-row--stats .b-pstat { min-height: 0; }
}
/* Sizing per Figma stat card: number 64 / unit 36 / label / caption 16 / bar 8. */
.b-pstat { display: flex; flex-direction: column; width: 100%; min-height: 240px; padding: 24px; border: 2px solid var(--navy); border-radius: var(--r-md); background: var(--white); }
.b-pstat__num { font-weight: 400; font-size: calc(clamp(56px, 5.2vw, 76px) * var(--tscale, 1)); line-height: 1; }
.b-pstat__suffix { font-size: .58em; vertical-align: -0.05em; }
.b-pstat__lead { font-weight: 300; font-size: calc(clamp(30px, 3vw, 40px) * var(--tscale, 1)); line-height: 1.1; color: var(--navy); margin-top: 2px; }
.b-pstat__sub { font-weight: 400; font-size: calc(16px * var(--tscale, 1)); color: #555; margin-top: auto; margin-bottom: 8px; }
.b-pstat__bar { width: 100%; height: 8px; border-radius: 4px; background: var(--rgb-spectrum); }
/* Stat Strip (StatStripBlock) — the About "proof" row: figures framed by a navy
   rule top and bottom. As many figures as fit per line (~150px each), collapsing
   to fewer as the width shrinks.
   Flex-wrap + justify-content:center (not an auto-fit grid) so an under-filled
   LAST row centres instead of left-aligning — the general "centre the wrapped
   remainder" behaviour shared by every wrapping strip (see also .b-wrap-center).
   Items grow to fill, so full rows are unchanged and a lone wrapped item spans
   the row with its content centred. */
/* Matches the prototypes' `.stat-grid`: a LEFT-aligned 4-up grid with no rules.
   It used to be a centred flex band framed by 2px navy hairlines — a treatment
   that appears in NO prototype (checked all 12; five use .stat-grid, none has a
   ruled band) and whose figures ran to 52px against the design's ~30px. Neptune,
   Luna and the Evaluation Kit were rendering that same wrong treatment. */
.b-statstrip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px 28px; padding: 50px 0; }
.b-statstrip__item { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; text-align: left; min-width: 0; height: 100%; }
.b-statstrip__num { font-weight: 400; font-size: clamp(24px, 2.1vw, 32px); line-height: 1.05; letter-spacing: -.5px;
                    white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--navy); }
.b-statstrip__suffix { font-size: .5em; letter-spacing: 0; margin-left: 3px; font-variant-numeric: normal; }
.b-statstrip__label { font-weight: 400; font-size: 15px; line-height: 1.4; color: #333; }
/* margin-top:auto keeps the RGB bars on one baseline when labels wrap to
   different heights — `.stat-grid .stat__bar` does exactly this. */
.b-statstrip__bar { width: 160px; max-width: 100%; height: 8px; border-radius: 4px; background: var(--rgb-spectrum); margin-top: auto; }
@media (max-width: 1100px) { .b-statstrip { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) {
  .b-statstrip { grid-template-columns: 1fr; gap: 22px; padding: 34px 0; }
}
/* Icon point (IconPointBlock) — rounded icon tile + bold label + description.
   The About "Vision & values" USP item. */
.b-usp { display: flex; gap: 18px; align-items: flex-start; }
.b-usp__ico { flex: none; width: 48px; height: 48px; margin-top: 2px; display: flex;
              align-items: center; justify-content: center; font-size: 22px;
              border-radius: 12px; background: #050416; color: #fff; }
.b-usp__ico svg { width: 24px; height: 24px; }
.b-usp__ico .cx-icon { width: 24px; height: 24px; }
.b-usp__label { font-weight: 400; font-size: var(--fs, clamp(20px, 2vw, 24px)); line-height: 1.25; color: #000; }
.b-usp__body { font-weight: 400; font-size: var(--fs, 16px); line-height: 1.5; margin-top: 4px;
               color: color-mix(in srgb, #000 70%, transparent); }
/* Dark section: the label/body carry explicit dark colours, so flip them to
   white; give the icon tile a light backing so it isn't invisible on #050416. */
.dark-section .b-usp__label { color: #fff; }
.dark-section .b-usp__body { color: rgba(255,255,255,.72); }
/* The prototypes' .trust__ico is a SOLID black tile with a faint white
   hairline, not a translucent wash — on the deep-navy band the wash left the
   glyph floating with no edge. */
.dark-section .b-usp__ico { background: #000; border: 1px solid rgba(255, 255, 255, .12); border-radius: 10px; }
/* News card (NewsCardBlock) — slide inside the News slider: thumb, tag + date
   meta, headline. */
.b-ncard { display: flex; flex-direction: column; text-decoration: none; }
a.b-ncard { transition: transform .2s; }
a.b-ncard:hover { transform: translateY(-2px); }
.b-ncard__thumb { display: block; width: 100%; aspect-ratio: 400 / 240; object-fit: cover;
                  border-radius: var(--r-md); border: 2px solid var(--white); margin-bottom: 18px;
                  background: color-mix(in srgb, var(--navy) 6%, transparent); }
.b-ncard__meta { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.b-ncard__tag { display: inline-flex; align-items: center; height: 28px; padding: 0 13px;
                border: 1.5px solid var(--navy); border-radius: 15px; font-family: var(--mono);
                font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--navy); }
.b-ncard__date { font-family: var(--mono); font-weight: 300; font-size: 13px;
                 color: color-mix(in srgb, var(--navy) 55%, transparent); }
.b-ncard__title { font-weight: 300; font-size: 24px; line-height: 1.25; color: #000; }
/* News card on a dark band. Needed since the card became placeable in any Row, not
   only inside a Slider — dropped into a dark section its navy tag and near-black
   headline were all but invisible. */
.dark-section .b-ncard__title { color: #fff; }
.dark-section .b-ncard__tag { border-color: rgba(255,255,255,.5); color: rgba(255,255,255,.9); }
.dark-section .b-ncard__date { color: rgba(255,255,255,.6); }
/* Divider (DividerBlock) — thin horizontal rule; light variant on dark sections. */
.b-divider { width: 100%; height: 0; border: 0; border-top: 2px solid color-mix(in srgb, var(--navy) 14%, transparent); margin: 0; }
.dark-section .b-divider { border-top-color: rgba(255,255,255,.18); }
/* Role card (RoleCardBlock) — dark textured vacancy card for the Careers slider:
   tag chip · role title · teaser · "View role →" link, over the brand dark
   texture + a vertical scrim. */
.b-rcard { position: relative; display: flex; flex-direction: column; height: 100%; min-height: 300px;
           padding: 32px; border-radius: var(--notch); overflow: hidden; text-decoration: none; transition: transform .2s;
           background: #050416 url("../img/brilliance/images/role-card-bg.d4d24141ffac.jpg") center / cover no-repeat; }
a.b-rcard:hover { transform: translateY(-2px); }
.b-rcard::before { content: ""; position: absolute; inset: 0;
                   background: linear-gradient(to bottom, rgba(5,4,22,.62), rgba(5,4,22,.88)); }
.b-rcard > * { position: relative; z-index: 1; }
.b-rcard__tag { align-self: flex-start; display: inline-flex; align-items: center; height: 28px; padding: 0 13px;
                border: 1.5px solid rgba(255,255,255,.45); border-radius: 15px; font-family: var(--mono);
                font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
                color: rgba(255,255,255,.8); margin-bottom: 22px; }
.b-rcard__title { font-weight: 300; font-size: 28px; line-height: 1.2; color: #fff; margin-bottom: 10px; }
.b-rcard__teaser { font-weight: 400; font-size: 16px; line-height: 1.5; color: rgba(255,255,255,.7); margin-bottom: 24px; }
.b-rcard__link { margin-top: auto; display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; color: #fff; }
/* Member card (MemberCardBlock) — portrait + name (large) + role (small, mono).
   A cell in the About team grid. */
.b-member__photo { display: block; width: 100%; aspect-ratio: 3 / 3.2; object-fit: cover;
                   border-radius: 14px; border: 2px solid var(--white); margin-bottom: 14px;
                   background: color-mix(in srgb, var(--navy) 10%, transparent); }
.b-member__name { font-weight: 300; font-size: 19px; line-height: 1.2; color: #000; margin-bottom: 2px; }
.b-member__role { font-family: var(--mono); font-weight: 500; font-size: 12px; text-transform: uppercase;
                  letter-spacing: .4px; color: color-mix(in srgb, var(--navy) 60%, transparent); margin-bottom: 10px; }
.b-member__expertise { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin: 0 0 10px; padding: 0; }
.b-member__expertise li { padding: 4px 10px; border-radius: 99px; font-family: var(--mono); font-size: 11px;
                          letter-spacing: .04em; color: var(--navy);
                          background: color-mix(in srgb, var(--cyan) 12%, var(--snow)); }
.b-member__li { display: inline-flex; color: var(--navy); font-size: 22px; line-height: 1; transition: color .2s; }
.b-member__li:hover { color: var(--cyan); }
/* Team member profile page (team_member_page.html) — photo + bio, own layout
   (distinct from the .b-member grid card above). Responsive: 2-col → stacked. */
.b-profile { display: grid; grid-template-columns: 320px 1fr; gap: clamp(28px, 5vw, 64px);
             align-items: start; max-width: 1000px; margin: 0 auto;
             padding: calc(var(--nav-h, 66px) + 72px) 0 72px; }
.b-profile__photo { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 18px;
                    border: 2px solid var(--white); background: color-mix(in srgb, var(--navy) 10%, transparent); }
.b-profile__eyebrow { font-family: var(--mono); font-weight: 500; font-size: 12px; text-transform: uppercase;
                      letter-spacing: .5px; color: var(--cyan); margin-bottom: 12px; }
.b-profile__name { font-weight: 300; font-size: clamp(34px, 5vw, 52px); line-height: 1.05; margin-bottom: 8px; }
.b-profile__dept { font-size: 17px; color: color-mix(in srgb, var(--navy) 65%, transparent); margin-bottom: 24px; }
.b-profile__bio { font-size: 16px; line-height: 1.65; color: #1a1a1a; max-width: 60ch; }
.b-profile__bio p { margin-bottom: 14px; }
.b-profile__links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.b-profile__link { display: inline-flex; align-items: center; height: 44px; padding: 0 22px; border-radius: 24px;
                   border: 1.5px solid color-mix(in srgb, var(--navy) 25%, transparent); font-weight: 500; font-size: 14px;
                   color: var(--navy); transition: border-color .2s, color .2s; }
.b-profile__link:hover { border-color: var(--cyan); color: var(--cyan); }
@media (max-width: 720px) {
    .b-profile { grid-template-columns: 1fr; gap: 22px; max-width: 440px;
                 padding-top: calc(var(--nav-h, 66px) + 40px); }
    .b-profile__photo { max-width: 300px; }
    .b-profile__dept { margin-bottom: 18px; }
}
/* Grid row limit → hidden cells + "Load more" button (GridBlock). */
.b-grid__cell--hidden { display: none; }
.b-grid.is-expanded .b-grid__cell--hidden { display: block; }
.b-grid__more-wrap { display: flex; justify-content: center; margin-top: 32px; }
.b-grid__more { display: inline-flex; align-items: center; gap: 10px; padding: 13px 26px; cursor: pointer;
                font-family: var(--mono); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: .6px;
                color: color-mix(in srgb, var(--navy) 70%, transparent); background: transparent;
                border: 1.5px solid color-mix(in srgb, var(--navy) 22%, transparent); border-radius: 15px;
                transition: color .2s, border-color .2s, background .2s; }
.b-grid__more:hover { color: var(--navy); border-color: var(--navy); background: color-mix(in srgb, var(--navy) 6%, transparent); }
.b-grid__more-ic { transition: transform .2s; }
.b-grid__more.is-open .b-grid__more-ic { transform: rotate(180deg); }
.dark-section .b-grid__more { color: rgba(255,255,255,.75); border-color: rgba(255,255,255,.28); }
.dark-section .b-grid__more:hover { color: #fff; border-color: #fff; background: rgba(255,255,255,.08); }
/* Logo marquee (LogoMarqueeBlock) — auto-scrolling logo row. Track holds the set
   twice; a -50% slide loops it seamlessly. Edge fades + pause-on-hover. */
@keyframes b-marquee-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.b-marquee { position: relative; overflow: hidden; }
/* No flex gap — each tile carries its own trailing margin so the track width is
   exactly tiles × 204px and the -50% wrap lands on an identical tile (seamless).
   A flex gap would add an extra space between the two halves and break the loop. */
.b-marquee__track { display: flex; width: max-content;
                    animation: b-marquee-scroll var(--marquee-dur, 28s) linear infinite; }
.b-marquee:hover .b-marquee__track { animation-play-state: paused; }
.b-logo { flex: 0 0 auto; margin-right: 24px; display: flex; align-items: center; justify-content: center;
          width: 180px; height: 96px; padding: 0 12px; border-radius: var(--r-md);
          border: 2px solid color-mix(in srgb, var(--navy) 16%, transparent); background: var(--snow, #f7f8fb);
          font-family: var(--mono); font-size: 11px; letter-spacing: .5px; line-height: 1.4; text-align: center;
          color: color-mix(in srgb, var(--navy) 45%, transparent); }
.b-logo__img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.b-marquee::before, .b-marquee::after { content: ""; position: absolute; top: 0; bottom: 0; width: 100px; z-index: 1; pointer-events: none; }
.b-marquee::before { left: 0; background: linear-gradient(to right, var(--marquee-fade, #fff) 40%, transparent); }
.b-marquee::after { right: 0; background: linear-gradient(to left, var(--marquee-fade, #fff) 40%, transparent); }
@media (prefers-reduced-motion: reduce) { .b-marquee__track { animation: none; } }
/* Media CTA (MediaCtaBlock) — split promo card: image + dark panel (heading,
   text, button), rounded + bordered, clipped. Image side switchable. */
.b-mediacta { display: flex; align-items: stretch; border-radius: var(--notch);
              overflow: hidden; border: 2px solid var(--white); }
.b-mediacta--img-right { flex-direction: row-reverse; }
.b-mediacta__media { flex: 0 0 600px; max-width: 50%; }
.b-mediacta__img { display: block; width: 100%; height: 100%; min-height: 440px; object-fit: cover; }
/* Media side holding a block (e.g. a Location Map) — the block fills the pane
   edge-to-edge (override the block's own inline height + rounded corners). */
.b-mediacta__media--block { display: flex; }
.b-mediacta__media--block > * { flex: 1; min-width: 0; }
.b-mediacta__media--block .location-map-wrapper { margin: 0 !important; height: 100%; min-height: 440px; }
.b-mediacta__media--block .location-map { height: 100% !important; min-height: 440px; border-radius: 0 !important; }
.b-mediacta__panel { position: relative; overflow: hidden; flex: 1; min-width: 0; background: #050416; color: #fff;
                     padding: clamp(40px, 5vw, 70px) clamp(26px, 5vw, 60px);
                     display: flex; flex-direction: column; justify-content: center; }
.b-mediacta__panel--bottom { justify-content: flex-end; }
/* Photo-backed panel (opt-in): building/location photo under a navy scrim + faint grid. */
.b-mediacta__panel--photo { background: linear-gradient(135deg, var(--navy), color-mix(in srgb, var(--navy) 55%, #000)); }
.b-mediacta__panel-photo { position: absolute; inset: 0; z-index: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%; }
.b-mediacta__panel-scrim { position: absolute; inset: 0; z-index: 0; background: linear-gradient(180deg, rgba(5,4,22,.30) 0%, rgba(5,4,22,.20) 38%, rgba(20,28,66,.78) 78%, rgba(5,4,22,.92) 100%); }
.b-mediacta__panel-grid { position: absolute; inset: 0; z-index: 0; opacity: .10; mix-blend-mode: overlay;
    background-image: linear-gradient(rgba(255,255,255,.4) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.4) 1px, transparent 1px);
    background-size: 80px 80px; }
.b-mediacta__panel-body { position: relative; z-index: 1; display: flex; flex-direction: column; }
/* Eyebrow + pulsing location pin. */
/* Location layout: pin beside a stacked eyebrow + heading label (prototype .mapwrap). */
.b-mediacta__loc { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; }
.b-mediacta__loc-label { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.b-mediacta__loc .b-mediacta__title { font-size: clamp(20px, 2.4vw, 26px); font-weight: 300; line-height: 1.2; margin: 0; }
.b-mediacta__eyebrow { font-family: var(--mono); font-weight: 500; font-size: 14px; text-transform: uppercase; letter-spacing: .5px; color: rgba(255,255,255,.7); }
.b-mediacta__pin { position: relative; flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--cyan);
    box-shadow: 0 0 0 6px rgba(0,177,235,.25), 0 0 0 14px rgba(0,177,235,.12); }
.b-mediacta__pin::after { content: ""; position: absolute; left: 0; top: 0; width: 18px; height: 18px; border-radius: 50%; background: var(--cyan); animation: b-pinPulse 2.6s ease-out infinite; }
@keyframes b-pinPulse { 0% { transform: scale(1); opacity: .5; } 70% { transform: scale(3.4); opacity: 0; } 100% { opacity: 0; } }
.b-mediacta__title { font-weight: 300; font-size: clamp(30px, 4vw, 46px); line-height: 1.1; color: #fff; margin-bottom: 18px; }
.b-mediacta__text { font-weight: 300; font-size: clamp(18px, 2vw, 22px); line-height: 1.5;
                    color: rgba(255,255,255,.78); max-width: 460px; margin-bottom: 38px; }
@media (prefers-reduced-motion: reduce) { .b-mediacta__pin::after { animation: none; } }
@media (max-width: 1024px) {
    .b-mediacta__loc { gap: 12px; margin-bottom: 18px; }
    .b-mediacta__loc .b-mediacta__title { font-size: clamp(15px, 2.4vw, 18px); }
    .b-mediacta__eyebrow { font-size: 10px; }
    .b-mediacta__pin, .b-mediacta__pin::after { width: 15px; height: 15px; }
}
@media (max-width: 640px) {
    .b-mediacta__loc { gap: 10px; margin-bottom: 14px; }
    .b-mediacta__loc .b-mediacta__title { font-size: 14px; }
    .b-mediacta__eyebrow { font-size: 10px; }
    .b-mediacta__pin, .b-mediacta__pin::after { width: 13px; height: 13px; }
}
@media (max-width: 1023px) {
  .b-mediacta, .b-mediacta--img-right { flex-direction: column; }
  .b-mediacta__media { flex: none; max-width: none; }
  .b-mediacta__img { min-height: 240px; }
  .b-mediacta__media--block .location-map-wrapper,
  .b-mediacta__media--block .location-map { min-height: 300px; }
}
/* crossfade image gallery */
.b-gallery { position: relative; height: clamp(340px, 38vw, 535px); background: var(--snow); overflow: hidden; }
.b-gallery__slide { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .55s cubic-bezier(.16,1,.3,1); pointer-events: none; }
.b-gallery__slide.is-active { opacity: 1; }
.b-gallery__nav { position: absolute; right: 30px; bottom: 30px; display: flex; gap: 14px; z-index: 2; }
/* Image switcher = crossfade gallery + dot navigation; swipe/drag/wheel to switch. */
.b-imgsw { display: flex; flex-direction: column; gap: 18px; margin-bottom: 18px; }
.b-imgsw .b-gallery { touch-action: pan-y; cursor: pointer; }
.b-dots { display: flex; gap: 10px; justify-content: center; }
.b-dot { width: 11px; height: 11px; flex: none; border-radius: 99px; border: none; padding: 0; cursor: pointer; background: color-mix(in srgb, var(--navy) 22%, transparent); transition: width .25s, background .25s; }
.b-dot:hover { background: color-mix(in srgb, var(--navy) 45%, transparent); }
/* Active dot stretches into a pill (the common style). */
.b-dot.is-on { width: 60px; background: var(--navy); }
.b-pcarousel__btn { width: 45px; height: 45px; flex: none; border-radius: 50%; border: none; background: var(--white); color: var(--navy); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 6px 20px rgba(5,4,22,.20); transition: transform .2s, background .2s, color .2s; }
.b-pcarousel__btn:hover { background: var(--navy); color: var(--white); transform: translateY(-2px); }

/* ---------- nav (sticky brand bar) ---------- */
/* Nav sits INSIDE the hero card: inset by (page-gap + nav-inset) from the page
   edges, i.e. nav-inset from the hero's top/left/right edges (equal on all three). */
.b-nav { position: sticky; top: 0; z-index: 50; padding-top: calc(var(--page-gap-top) + var(--nav-inset)); transition: transform .35s ease; }
/* Hide-on-scroll-down / show-on-scroll-up (see mysite/static/js/brilliance.js) */
.b-nav--hidden { transform: translateY(-130%); }
.b-nav__bar { width: calc(100% - 2 * (var(--page-gap) + var(--nav-inset))); min-height: var(--nav-h); margin: 0 auto; padding: 10px clamp(16px, 3vw, 24px) 10px clamp(18px, 3vw, 28px); display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; background: var(--navy); border-radius: var(--r-md); box-shadow: var(--shadow-nav); }
.b-nav__logo { width: clamp(180px, 22vw, 270px); height: auto; }
.b-nav__links { display: flex; align-items: center; gap: clamp(16px, 2.5vw, 36px); flex-wrap: wrap; }
.b-nav__links a { font-family: var(--sans); font-weight: 600; font-size: 14px; text-transform: uppercase; color: var(--white); letter-spacing: .3px; }
.b-nav__links a:hover { opacity: .8; }
/* Dropdown nav item (a page with in-menu children, e.g. Products → Luna). */
.b-nav__item { position: relative; }
.b-nav__toprow { display: inline-flex; align-items: center; gap: 3px; }
.b-nav__toplink { font-family: var(--sans); font-weight: 600; font-size: 14px; text-transform: uppercase; color: var(--white); letter-spacing: .3px; }
.b-nav__toplink:hover { opacity: .8; }
/* Static (non-link) dropdown header — an unpublished grouping page's label. */
.b-nav__toplink--static { cursor: default; }
.b-nav__toplink--static:hover { opacity: 1; }
.b-nav__caret { display: inline-flex; align-items: center; justify-content: center; padding: 2px; background: none; border: 0; color: var(--white); cursor: pointer; touch-action: manipulation; }
.b-nav__caret svg { transition: transform .2s ease; }
/* Dropdown opens left-aligned by default; JS (positionNavDropdowns in
   brilliance.js) adds .b-nav__sub--flip to right-anchor it ONLY when it would
   otherwise overflow the right of the screen (e.g. "Open roles" near the end).
   max-width keeps it inside the viewport if a parent sits very close to the edge. */
.b-nav__sub { position: absolute; top: 100%; left: -10px; min-width: 190px; max-width: calc(100vw - 32px); margin-top: 10px; padding: 8px; background: var(--navy); border-radius: 0; box-shadow: var(--shadow-nav); display: flex; flex-direction: column; gap: 2px; opacity: 0; visibility: hidden; transform: translateY(6px); transition: opacity .18s ease, transform .18s ease, visibility .18s; z-index: 60; }
.b-nav__sub--flip { left: auto; right: -10px; }
.b-nav__sub::before { content: ""; position: absolute; top: -12px; left: 0; right: 0; height: 12px; }
/* Open state is authoritative from JS (.is-open) — the single source of truth on
   touch, where :hover is sticky and button :focus is platform-dependent (iOS
   doesn't focus buttons on tap). Keeping :hover / :focus-within inside
   (hover: hover) means touch never relies on either, so tapping the caret can't
   flash, stick, or leave the arrow pointing the wrong way. */
.b-nav__item.is-open .b-nav__sub { opacity: 1; visibility: visible; transform: translateY(0); }
.b-nav__item.is-open .b-nav__caret svg { transform: rotate(180deg); }
@media (hover: hover) {
    .b-nav__item:hover .b-nav__sub,
    .b-nav__item:focus-within .b-nav__sub { opacity: 1; visibility: visible; transform: translateY(0); }
    .b-nav__item:hover .b-nav__caret svg,
    .b-nav__item:focus-within .b-nav__caret svg { transform: rotate(180deg); }
}
.b-nav__sub a { display: block; padding: 9px 14px; border-radius: 0; font-family: var(--sans); font-weight: 600; font-size: 12.5px; text-transform: uppercase; letter-spacing: .3px; color: var(--white); white-space: nowrap; }
.b-nav__sub a:hover { background: rgba(255, 255, 255, .12); opacity: 1; }
.b-nav__contact { display: inline-flex; align-items: center; gap: 8px; height: 32px; padding: 0 16px; background: var(--white); color: var(--navy) !important; border-radius: var(--r-pill); font-weight: 600; font-size: 14px; text-transform: uppercase; }
.b-nav__contact:hover { opacity: 1 !important; background: var(--snow); }
.b-nav__contact .b-ar { width: 14px; height: 14px; }
/* Hamburger toggle — desktop hides it (links sit inline). */
.b-nav__toggle { display: none; }
/* Tablet + phone: collapse the links into a dropdown so the bar stays a single
   predictable-height row (the hero pull-up math relies on a fixed --nav-h). */
@media (max-width: 1023px) {
    .b-nav__bar { position: relative; flex-wrap: nowrap; }
    .b-nav__toggle { display: inline-flex; flex-direction: column; justify-content: center; gap: 5px; width: 42px; height: 42px; padding: 9px; background: transparent; border: none; cursor: pointer; flex: none; }
    .b-nav__toggle span { display: block; width: 100%; height: 2px; background: var(--white); border-radius: 2px; transition: transform .25s ease, opacity .2s ease; }
    .b-nav--open .b-nav__toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
    .b-nav--open .b-nav__toggle span:nth-child(2) { opacity: 0; }
    .b-nav--open .b-nav__toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
    .b-nav__links {
        position: absolute; top: calc(100% + 8px); left: 0; right: 0;
        flex-direction: column; align-items: flex-start; gap: 2px;
        background: var(--navy); border-radius: var(--r-md);
        padding: 14px clamp(18px, 4vw, 28px); box-shadow: var(--shadow-nav);
        max-height: calc(100vh - 140px); overflow-y: auto; display: none;
    }
    .b-nav--open .b-nav__links { display: flex; }
    /* Left-align items; the 18px left padding matches the Contact pill's inner
       padding so every item's TEXT starts on the same vertical line. */
    .b-nav__links a { width: 100%; padding: 11px 0 11px 18px; font-size: 15px; text-align: left; }
    /* Higher specificity than `.b-nav__links a` so the white pill keeps its own
       horizontal padding; left-align its text so it starts on the same line as
       the other items (its 18px padding == the others' left indent). */
    .b-nav__links a.b-nav__contact { margin-top: 8px; height: 40px; padding: 0 18px; justify-content: flex-start; }
    /* Dropdown items collapse inline: caret beside the parent, submenu below,
       tap the caret to expand (data-nav-caret in brilliance.js). */
    .b-nav__item { width: 100%; }
    /* Left-align the label on the same line as the other items (18px indent); the
       caret sits inline right after the text. */
    .b-nav__toprow { display: flex; align-items: center; gap: 6px; width: 100%; padding: 11px 0 11px 18px; }
    .b-nav__toprow .b-nav__toplink { width: auto; padding: 0; font-size: 15px; }
    .b-nav__caret { padding: 6px; }
    .b-nav__sub { position: static; opacity: 1; visibility: visible; transform: none; display: none; width: 100%; min-width: 0; margin: 0; padding: 0 0 6px; background: transparent; box-shadow: none; }
    .b-nav__sub::before { display: none; }
    .b-nav__item.is-open .b-nav__sub { display: flex; }
    .b-nav__item.is-open .b-nav__caret svg { transform: rotate(180deg); }
    .b-nav__sub a { color: var(--white); text-align: left; font-size: 13px; padding: 9px 0 9px 30px; }
}

/* Tablet: cap the collapsed nav menu width + right-anchor it (under the hamburger)
   so short left-aligned items aren't stranded in a sparse full-width panel.
   Phones (< 640px) keep the full-width panel. */
@media (min-width: 640px) and (max-width: 1023px) {
    .b-nav__links { left: auto; right: 0; width: min(340px, calc(100vw - 32px)); }
}

/* ---------- footer ---------- */
/* extra bottom space so the half-outside RGB graphic (-68px) clears the page end */
/* Bottom gap to the window matches the side gap (--page-gap). With a corner mark
   (protrudes 68px below the frame) the gap is measured from the mark's bottom, so
   reserve that protrusion + --page-gap. Without a mark it's just --page-gap. */
.b-footer { padding: clamp(48px, 7vw, 90px) 0 calc(68px + var(--page-gap)); }
.b-footer--no-mark { padding-bottom: var(--page-gap); }
/* Footer mirrors the hero frame: a constant --page-gap (20px) inset on the
   left/right/bottom to the window edges, so the page is framed evenly top and
   bottom regardless of zoom. */
.b-footer__frame { position: relative; width: calc(100% - 2 * var(--page-gap)); margin: 0 auto; padding: clamp(28px, 5vw, 60px); background: var(--footer-grad); color: var(--white); border-radius: var(--footer-notch); }
/* Frame stays full-bleed; the inner content centres at a max-width so it doesn't
   spread to the edges on wide screens / when zoomed out. */
.b-footer__inner { width: 100%; max-width: 1300px; margin-inline: auto; }
.b-footer__frame .b-rgb-strip { width: 100%; max-width: 1300px; margin-bottom: clamp(28px, 4vw, 48px); }
.b-footer__logo { width: clamp(220px, 26vw, 329px); height: auto; margin-bottom: clamp(28px, 4vw, 48px); }
.b-footer__cols { position: relative; z-index: 2; display: flex; flex-wrap: wrap; gap: clamp(28px, 4vw, 60px); }
.b-footer__col { flex: 1 1 200px; min-width: 180px; }
.b-footer__col-title { font-weight: 600; font-size: 16px; text-transform: uppercase; letter-spacing: .8px; margin-bottom: 18px; color: var(--white); }
.b-footer__col a, .b-footer__col p { display: block; font-weight: 400; font-size: 20px; line-height: 2; color: #e6e8f2; }
.b-footer__col a:hover { color: #fff; }
/* Scoped under .b-footer__col so this 16px caption beats the more-specific
   `.b-footer__col p { font-size: 20px }` link rule (else it renders full size). */
.b-footer__col p.b-footer__updates { font-weight: 400; font-size: 16px; line-height: 1.5; color: #e6e8f2; margin: 18px 0 6px; }
.b-footer__email { display: flex; gap: 10px; margin-top: 14px; }
.b-footer__email input { width: 100%; max-width: 280px; height: 50px; border-radius: var(--r-input); border: none; padding: 0 22px; font-family: var(--sans); font-size: 18px; color: var(--black); background: var(--white); }
.b-footer__email input::placeholder { color: #8890a8; }
.b-footer__send { width: 42px; height: 42px; flex: none; border-radius: 50%; background: var(--navy); color: var(--white); border: 1px solid rgba(255,255,255,.4); display: flex; align-items: center; justify-content: center; cursor: pointer; align-self: center; }
.b-footer__send .b-ar { width: 16px; height: 16px; }
.b-footer__social { display: flex; gap: 16px; margin-top: 22px; }
.b-footer__social a { color: var(--white); display: inline-flex; transition: opacity .2s; }
.b-footer__social a:hover { opacity: .75; }
.b-footer__social i { font-size: 30px; line-height: 1; }
/* RGB graphic: bottom-right corner, ~half outside the frame (Figma: 440px-tall
   frame, 167px graphic at top 341 → overflows the bottom by ~68px). */
.b-footer__rgb { position: absolute; right: 0; bottom: -68px; width: 220px; height: auto; z-index: 1; pointer-events: none; }
.b-footer__legal { position: relative; z-index: 2; display: flex; align-items: center; gap: 8px 26px; flex-wrap: wrap; margin-top: 44px; padding-top: 24px; border-top: 1px solid rgba(255,255,255,.18); font-weight: 400; font-size: 14px; color: #e6e8f2; }
.b-footer__legal a { color: #e6e8f2; }
.b-footer__legal a:hover { color: #fff; }
@media (max-width: 1024px) { .b-footer__rgb { width: 160px; bottom: -50px; } .b-footer { padding-bottom: calc(50px + var(--page-gap)); } .b-footer--no-mark { padding-bottom: var(--page-gap); } }
@media (max-width: 640px) { .b-footer__rgb { display: none; } .b-footer { padding-bottom: var(--page-gap); } }

/* ---------- shared helpers ---------- */
.b-mono { font-family: var(--mono); }
.b-text-navy { color: var(--navy); }
.b-text-cyan { color: var(--cyan); }
.b-text-green { color: var(--green); }
.b-text-red { color: var(--red); }
.b-text-black { color: var(--black); }
.b-text-white { color: var(--white); }
.b-border-navy { border-color: var(--navy); }
.b-bg-navy { background: var(--navy); }
/* rich-text inside a display heading: drop the wrapping <p>'s margin */
.b-h1 p, .b-h2 p, .b-h3 p { margin: 0; }
/* image atom */
.b-figure { margin: 0; }
.b-img { display: block; width: 100%; height: auto; }
/* Fixed aspect ratio (Image block → Aspect ratio); --ar set on the figure. */
.b-img--ar { aspect-ratio: var(--ar); object-fit: cover; height: auto; }
/* Image block → Size (cap width) + Alignment (only when not full width). */
.b-figure--lg { max-width: 720px; }
.b-figure--md { max-width: 480px; }
.b-figure--sm { max-width: 320px; }
.b-figure--center { margin-left: auto; margin-right: auto; }
.b-figure--left { margin-right: auto; }
.b-figure--right { margin-left: auto; }

/* ---------- Team cluster (centre image + scattered avatars / story chips) ---------- */
.b-cluster { position: relative; display: grid; place-items: center; min-height: 640px; }
.b-cluster__center { position: relative; z-index: 2; width: min(560px, 100%); margin-inline: auto; }

/* ---------- video lightbox (native <dialog>, see base.html #video-modal) ----------
   A modal <dialog> is centred ONLY by the UA stylesheet's `dialog:modal { margin: auto }`.
   Tailwind's Preflight sets `margin: 0` on `*` (mysite.css, in @layer base), which
   matches <dialog> too — so without this the lightbox opens pinned to the top-left
   corner instead of the middle of the viewport. Restored here rather than as a
   utility class on the element because it is a reset repair, and this file is
   unlayered so it beats @layer base regardless of specificity. */
dialog:modal { margin: auto; }

/* ---------- story modal (opened by team-cluster chips) ---------- */
.b-story-modal { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; padding: 24px; opacity: 0; pointer-events: none; transition: opacity .3s ease; }
.b-story-modal.is-open { opacity: 1; pointer-events: auto; }
.b-story-modal__scrim { position: absolute; inset: 0; background: rgba(5, 4, 22, .62); backdrop-filter: blur(3px); }
.b-story-modal__wrap { position: relative; width: min(720px, 100%); max-height: 88vh; padding: 1.5px; border-radius: 22px 22px 22px 102px; background: linear-gradient(135deg, var(--navy) 0%, var(--cyan) 38%, var(--green) 70%, var(--red) 100%); box-shadow: 0 50px 120px rgba(5, 4, 22, .55); transform: translateY(18px) scale(.985); transition: transform .35s cubic-bezier(.16, 1, .3, 1); }
.b-story-modal.is-open .b-story-modal__wrap { transform: none; }
.b-story-modal__card { position: relative; display: flex; flex-direction: column; max-height: calc(88vh - 3px); background: var(--snow); border-radius: 20px 20px 20px 100px; overflow: hidden; }
.b-story-modal__close { position: absolute; top: 18px; right: 18px; z-index: 4; width: 42px; height: 42px; border: none; cursor: pointer; border-radius: 50%; background: var(--white); color: var(--navy); display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 18px rgba(5, 4, 22, .18); transition: transform .2s, box-shadow .2s; }
.b-story-modal__close:hover { transform: scale(1.07); box-shadow: 0 10px 24px rgba(5, 4, 22, .26); }
.b-story-modal__head { display: flex; align-items: center; gap: 20px; padding: clamp(28px, 3.4vw, 44px) clamp(28px, 3.6vw, 52px) 0; }
.b-story-modal__avatar { flex: none; width: 84px; height: 84px; border-radius: 50%; object-fit: cover; border: 2px solid var(--white); box-shadow: 0 8px 24px rgba(5, 4, 22, .18); }
.b-story-modal__role { font-family: var(--mono); font-weight: 500; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--cyan); margin-bottom: 6px; }
.b-story-modal__name { font-weight: 200; font-size: clamp(27px, 3.6vw, 37px); line-height: 1.04; color: var(--navy); }
.b-story-modal__eyebrow { font-size: 14px; color: color-mix(in srgb, #000 60%, var(--snow)); margin-top: 4px; }
.b-story-modal__body { overflow-y: auto; padding: clamp(22px, 2.6vw, 30px) clamp(28px, 3.6vw, 52px) clamp(30px, 3.6vw, 48px); margin-top: 8px; }
.b-story-modal__body p { font-size: 15px; line-height: 1.6; color: color-mix(in srgb, #000 80%, var(--snow)); margin-bottom: 16px; }
.b-story-modal__body p:last-child { margin-bottom: 0; }
.b-story-modal__body strong { color: var(--navy); font-weight: 600; }
/* Pulled-out highlight line, and the expertise tags, inside the story modal. */
.b-story-modal__body .b-story-highlight { font-size: clamp(16px, 1.9vw, 19px); font-weight: 500; line-height: 1.45; color: var(--navy); margin-bottom: 20px; padding-left: 16px; border-left: 3px solid var(--cyan); }
.b-story-expertise { display: flex; flex-wrap: wrap; gap: 8px; list-style: none; margin: 22px 0 0; padding: 0; }
.b-story-expertise li { padding: 5px 12px; border-radius: 99px; background: color-mix(in srgb, var(--cyan) 12%, var(--snow)); color: var(--navy); font-family: var(--mono); font-size: 12px; letter-spacing: .06em; }
.b-story-modal__rgb { height: 6px; border-radius: 99px; margin-top: 26px; background: linear-gradient(90deg, var(--navy), var(--cyan) 39%, var(--green) 74%, var(--red)); }
@media (max-width: 560px) {
    .b-story-modal { padding: 14px; }
    .b-story-modal__wrap { border-radius: 18px 18px 18px 64px; }
    .b-story-modal__card { border-radius: 16px 16px 16px 62px; }
    .b-story-modal__head { flex-direction: column; align-items: flex-start; gap: 14px; }
    .b-story-modal__avatar { width: 72px; height: 72px; }
}
.b-avatar { display: block; box-sizing: border-box; border-radius: 50%; overflow: hidden; width: var(--av-size, 104px); height: var(--av-size, 104px); box-shadow: 0 8px 24px rgba(5, 4, 22, .18); }
.b-avatar--outline { border: 2px solid var(--white); }
.b-avatar__img { display: block; width: 100%; height: 100%; object-fit: cover; transform-origin: center; }
.b-story-chip { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 16px; background: var(--navy); color: var(--white); border-radius: 15px; font-weight: 600; font-size: 13px; box-shadow: 0 6px 18px rgba(28, 47, 118, .30); text-decoration: none; white-space: nowrap; }
.b-story-chip .b-ar { width: 14px; height: 14px; }
/* member = avatar centred on its (left,top) point; the chip is anchored BELOW it
   (absolute) so it never shifts the avatar. */
.b-cluster__a { position: absolute; z-index: 3; width: var(--av-size, 104px); transform: translate(-50%, -50%); }
.b-cluster__a .b-story-chip { position: absolute; top: calc(100% + 10px); left: 50%; transform: translateX(-50%); }
/* Default scatter — exact figma centres (% of the 1440×714 cluster frame).
   Per-avatar diameter comes from each member's Avatar size (figma presets). */
.b-cluster__slot-1  { left: 15.2%; top: 8.1%; }
.b-cluster__slot-2  { left: 28.6%; top: 25.0%; }
.b-cluster__slot-3  { left: 4.7%;  top: 35.4%; }
.b-cluster__slot-4  { left: 21.1%; top: 52.7%; }
.b-cluster__slot-5  { left: 10.3%; top: 74.8%; }
.b-cluster__slot-6  { left: 81.6%; top: 8.1%; }
.b-cluster__slot-7  { left: 72.3%; top: 27.5%; }
.b-cluster__slot-8  { left: 90.0%; top: 29.8%; }
.b-cluster__slot-9  { left: 80.1%; top: 64.4%; }
.b-cluster__slot-10 { left: 93.1%; top: 82.1%; }
@media (min-width: 1024px) {
    .b-cluster { aspect-ratio: 1440 / 714; }
    .b-cluster__scatter { position: absolute; inset: 0; }
}
@media (max-width: 1023px) {
    .b-cluster { display: block; min-height: 0; aspect-ratio: auto; }
    .b-cluster__a { position: static !important; inset: auto !important; transform: none !important; width: auto; display: flex; flex-direction: column; align-items: center; gap: 10px; }
    .b-cluster__a .b-story-chip { position: static; transform: none;
        height: clamp(24px, 6.2vw, 28px); padding: 0 clamp(10px, 3vw, 13px); font-size: clamp(10px, 2.7vw, 12px); }
    .b-cluster__a .b-story-chip .b-ar { width: clamp(12px, 3vw, 14px); height: clamp(12px, 3vw, 14px); }
    .b-cluster__scatter { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; gap: 20px 24px; margin-top: 34px; }
    /* Avatars + link adapt slightly to the viewport (capped at the desktop-stack
       size, so tablet/large phones are unchanged; small phones shrink a little). */
    .b-cluster__scatter .b-avatar { width: clamp(70px, 19vw, 88px); height: clamp(70px, 19vw, 88px); }
}

/* Ambient decorative flares (Advanced → Background → Decorative flares). Pure-CSS
   radial-gradient glows anchored to the styled wrapper's edges. overflow is
   VISIBLE so a glow can bleed past the section boundary into the neighbouring
   section (the page's overflow-x:clip still prevents any horizontal scroll). They
   never affect layout (absolute). Whether a flare paints in front of or behind the
   block's content is chosen per flare — see .b-flares--front / .b-flares--back
   below. Any colour via --flare-color; softened on mobile. */
.b-styled--flares { position: relative; isolation: isolate; }
/* Layer is per-flare (Flare → Layer), so the two containers below split by it.
   pointer-events:none keeps both non-interactive so clicks pass through.

   --back is z-index:-1, which is well-defined inside the isolate above: the
   painting order within a stacking context puts negative-z children AFTER the
   context element's own background/border but BEFORE its in-flow content. So a
   back flare is still visible over the block's background colour or image, and
   still sits under every heading and button. It cannot escape the block either,
   because `isolation: isolate` bounds it.
   --front is the z-index:2 overlay; it washes over whatever it covers, which is
   why it is opt-in per flare rather than the global default it used to be. */
.b-flares { position: absolute; inset: 0; overflow: visible; pointer-events: none; }
.b-flares--back { z-index: -1; }
/* 4, not 2: several content elements declare z-index 2 or 3 of their own
   (.b-card__title, .b-ctaband__inner, .b-footer__cols, .b-cluster__center at 2;
   .b-cluster__a at 3). At 2 the flare TIED with them and lost on tree order —
   the container is emitted before the content — so "In front of the content"
   silently did nothing on exactly the blocks an editor would pick it for. */
.b-flares--front { z-index: 4; }
/* Contained flares: clipped to the block (no spill past the edges). */
.b-flares--clip { overflow: hidden; border-radius: inherit; }
.b-flare { position: absolute; width: clamp(240px, 60vw, 600px); height: clamp(240px, 60vw, 600px); border-radius: 50%; opacity: .32;
           background: radial-gradient(closest-side, var(--flare-color, #1C2F76), transparent 72%); }
/* sizes — fluid: scale with the viewport width, floored so they don't vanish and
   capped at the desktop size (reached ~1000px+), so desktop is unchanged. */
.b-flare--sm { width: clamp(200px, 38vw, 380px); height: clamp(200px, 38vw, 380px); }
.b-flare--md { width: clamp(240px, 60vw, 600px); height: clamp(240px, 60vw, 600px); }
.b-flare--lg { width: clamp(300px, 82vw, 820px); height: clamp(300px, 82vw, 820px); }
.b-flare--xl { width: clamp(360px, 106vw, 1060px); height: clamp(360px, 106vw, 1060px); }
.b-flare--wide { width: clamp(320px, 110vw, 1100px); height: clamp(240px, 46vw, 460px); }
.b-flare--tall { width: clamp(240px, 46vw, 460px); height: clamp(320px, 110vw, 1100px); }
/* intensity */
.b-flare--faint { opacity: .16; }
.b-flare--soft { opacity: .24; }
.b-flare--strong { opacity: .5; }
/* positions — anchor to an edge/corner, then translate so the glow bleeds off it */
.b-flare--tl { top: 0; left: 0; transform: translate(-40%, -40%); }
.b-flare--tc { top: 0; left: 50%; transform: translate(-50%, -45%); }
.b-flare--tr { top: 0; right: 0; transform: translate(40%, -40%); }
.b-flare--lc { top: 50%; left: 0; transform: translate(-45%, -50%); }
.b-flare--c  { top: 50%; left: 50%; transform: translate(-50%, -50%); }
.b-flare--rc { top: 50%; right: 0; transform: translate(45%, -50%); }
.b-flare--bl { bottom: 0; left: 0; transform: translate(-40%, 40%); }
.b-flare--bc { bottom: 0; left: 50%; transform: translate(-50%, 45%); }
.b-flare--br { bottom: 0; right: 0; transform: translate(40%, 40%); }
/* Sizes are fluid (clamp above), so no per-breakpoint size override is needed —
   just soften the glow a touch on phones. */
@media (max-width: 767px) {
  .b-flare { opacity: .2; }
}
.b-rounded-md { border-radius: var(--r-md); }
.b-rounded-notch { border-radius: var(--notch); }
.b-rounded-header { border-radius: var(--header-notch); }
/* horizontal slider: hide scrollbar + nav buttons */
.b-no-bar { -ms-overflow-style: none; scrollbar-width: none; }
.b-no-bar::-webkit-scrollbar { display: none; }
/* Row → Layout → Horizontal scroll: one non-wrapping row that scrolls sideways
   instead of wrapping into a grid. Native scrollbar is hidden; like the card
   table (.b-cmp-bar) we draw our OWN always-visible draggable bar under the row
   (.b-row-scroll-bar, synced in brilliance.js) so it stays usable at every
   breakpoint — desktop mouse and mobile alike (mobile overlay bars auto-hide).
   The bar shows only when the items actually overflow (JS toggles .is-hidden). */
/* No scroll-snap: free, continuous scrolling like the card-comparison table
   (.b-cmp-scroll). Snap made the track settle onto card edges, so dragging the
   bar felt like it jumped between fixed stops instead of moving smoothly. */
.b-row-scroll { display: flex; flex-wrap: nowrap; align-items: stretch; gap: 24px; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scrollbar-width: none; -ms-overflow-style: none; }
.b-row-scroll::-webkit-scrollbar { display: none; }
/* flex-grow:1 makes the items fill the row into equal columns EXACTLY like the
   off-state grid when the cards fit (so toggling scroll doesn't change desktop
   spacing); the capped card centres in each column via margin-inline:auto. But
   flex-shrink:0 means when the columns can't fit they keep their width and the
   row overflows → scrolls. The per-breakpoint width is that no-shrink scroll
   width, tracking .b-card's max-width so the card fills its item (no dead gap). */
.b-row-scroll__item { flex: 1 0 auto; width: min(84vw, 360px); }
.b-row-scroll__item .b-card { margin-inline: auto; }
@media (max-width: 1024px) { .b-row-scroll__item { width: min(84vw, 320px); } }
@media (max-width: 640px)  { .b-row-scroll__item { width: min(84vw, 210px); } }
@media (max-width: 420px)  { .b-row-scroll__item { width: min(84vw, 190px); } }
.b-row-scroll-wrap { position: relative; }
/* Same look as the card-comparison table bar (.b-cmp-bar): navy on light
   sections, white on dark (.dark-section). Inset by --page-gap on BOTH sides
   (the same edge gap the hero/footer frames use) so it sits centred with an
   equal gap left and right, instead of bleeding to the full-width row's edges. */
.b-row-scroll-bar { display: block; height: 6px; width: calc(100% - 2 * var(--page-gap)); margin: 14px auto 0; padding: 0; background: color-mix(in srgb, var(--navy) 12%, transparent); border-radius: 999px; touch-action: none; cursor: pointer; }
.b-row-scroll-bar.is-hidden { display: none; }
.b-row-scroll-bar__thumb { display: block; height: 100%; width: 40%; min-width: 32px; background: color-mix(in srgb, var(--navy) 55%, transparent); border-radius: 999px; will-change: transform; }
.dark-section .b-row-scroll-bar { background: rgba(255, 255, 255, .16); }
.dark-section .b-row-scroll-bar__thumb { background: rgba(255, 255, 255, .6); }
/* Slider track fills its CONTAINER, not the viewport. The track is a direct
   child of the section, so its width follows the section → the container the
   editor chose (full-width container = full-width carousel; narrower container =
   narrower carousel). The gutter padding matches .b-content so the first card
   lines up under the heading; scroll-padding keeps snapping aligned. No vw-based
   bleed — that hard-coded it to the window width. */
/* Feature Slider header (heading + subheading + arrows) is capped and centred at
   1400 like .b-content / the Product Switcher, so it stays centred on the page at
   any zoom instead of spreading to the container edges. The track/cards keep the
   full-width gutter so the carousel still fills its container. */
.b-slider__head {
    width: 100%;
    /* max-width comes inline from the block's "Heading / buttons width" option;
       centred so the header sits inside that width like a layout container. */
    margin-inline: auto;
}
/* Match the fedit container gutter so a constrained header lines up with a Wide
   container's content edge at every breakpoint. Two rules, mirroring
   .fedit-grid:not(.is-fluid) exactly — a slider header lives in a FLUID container
   (the track needs to bleed), so it can't inherit the container's own gutter and has
   to reproduce it. Keep these in lockstep with the .fedit-grid rules above: the
   header used to pad only below 1024px, which left it flush to the screen edge
   between 1025px and its max-width (0px at 1280 — same bug as the containers had). */
@media (max-width: 1024px) {
    .b-slider__head--contained { padding-inline: clamp(20px, 5vw, 48px); }
}
@media (min-width: 1025px) {
    .b-slider__head--contained { width: calc(100% - 2 * clamp(24px, 4vw, 48px)); }
}
.b-slider__track {
    /* Align the first card to the same centred 1400 box as the header (so it lines
       up under it), then add ~30px so the heading clears it on the left. Cards still
       bleed to the container's right edge. */
    padding-left: max(clamp(20px, 3vw, 32px), calc((100% - 1400px) / 2 + 30px));
    padding-right: clamp(20px, 5vw, 60px);
    scroll-padding-left: max(clamp(20px, 3vw, 32px), calc((100% - 1400px) / 2 + 30px));
    cursor: grab;
}
/* Between 1025px and 1400px the calc() above goes negative, so the floor (a
   phone-tuned 32px) wins and the first card sat left of the header's 48px gutter.
   Raise the floor to the header/container gutter in that band only, so the card
   lines up under the heading as intended. Above 1400px the calc still wins, and
   phone/tablet keep the 32px floor. scroll-padding must track padding or snapping
   lands mid-card. */
@media (min-width: 1025px) {
    .b-slider__track {
        padding-left: max(clamp(24px, 4vw, 48px), calc((100% - 1400px) / 2 + 30px));
        scroll-padding-left: max(clamp(24px, 4vw, 48px), calc((100% - 1400px) / 2 + 30px));
    }
}
/* Slide width. Lives here (not as a Tailwind class in the template) so the
   block's "Slide width" option can override it: narrow = small icon chips,
   wide = media cards with figures. Per-breakpoint overrides for the modifiers
   sit with the other .b-slide media queries further down — the modifiers are
   two-class selectors, so they'd otherwise beat the plain .b-slide overrides. */
.b-slide { width: min(380px, 80vw); min-width: 0; }
.b-slider__track--narrow .b-slide { width: min(300px, 74vw); }
.b-slider__track--wide .b-slide { width: min(460px, 86vw); }
/* The track is the scroll region; the wrap only exists to host the drawn
   scrollbar underneath it. Same look + helper as the card table's .b-cmp-bar
   (wireDragScrollbar in brilliance.js), phone-gated because on desktop the
   prev/next arrows are the affordance and a second bar would be noise. */
.b-slider-wrap { position: relative; }
.b-slider-bar { display: none; }
@media (max-width: 640px) {
    .b-slider-bar {
        display: block; height: 6px; padding: 0;
        /* Line the bar up with the track's own inline padding so it sits under
           the first card, not under the bleed. */
        margin: 12px clamp(20px, 3vw, 32px) 0;
        background: color-mix(in srgb, var(--navy) 12%, transparent);
        border-radius: 999px; touch-action: none; cursor: pointer;
    }
    .b-slider-bar.is-hidden { display: none; }
    .b-slider-bar__thumb {
        display: block; height: 100%; width: 40%; min-width: 32px;
        background: color-mix(in srgb, var(--navy) 55%, transparent);
        border-radius: 999px; will-change: transform;
    }
    .dark-section .b-slider-bar { background: rgba(255, 255, 255, .16); }
    .dark-section .b-slider-bar__thumb { background: rgba(255, 255, 255, .6); }
}
/* While dragging: grabbing cursor + suppress text/image selection and snap so the
   track follows the pointer smoothly. */
/* Selectable / coverflow carousel: the centred card scales up; others sit at
   normal size, dimmed slightly. JS adds .is-active and centres it. */
.b-cv-track { scroll-snap-type: none; overflow-y: hidden; }
/* All cards stay full-size (so the gap between them is even); the selected scales
   up slightly. The track's vertical padding absorbs the scale so it isn't clipped. */
.b-cv-card { transition: transform .45s cubic-bezier(.2, .7, .2, 1); transform: scale(1); cursor: pointer; transform-origin: center center; }
.b-cv-card.is-active { transform: scale(1.06); }
/* Non-selected cards: fade only the card background (text stays fully opaque). */
.b-cv-card .b-card { transition: transform .45s cubic-bezier(.2, .7, .2, 1), background-color .4s ease; }
.b-cv-card:not(.is-active) .b-card--outline { background-color: color-mix(in srgb, var(--white) 85%, transparent); }
.b-cv-card.is-active .b-card--outline { background-color: color-mix(in srgb, var(--white) 97%, transparent); }
/* RGB cards fade via the fill variable (their background is a gradient, not a flat colour). */
.b-cv-card:not(.is-active) .b-card--rgb { --card-fill: color-mix(in srgb, var(--white) 85%, transparent); }
.b-cv-card.is-active .b-card--rgb { --card-fill: color-mix(in srgb, var(--white) 97%, transparent); }
.b-slider__track--grabbing { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.b-slider__track--grabbing * { pointer-events: none; }

/* A "Full width (fluid)" container (width: none) simply fills its Section, which
   is already full-site-width — no break-out trickery, so it never extends beyond
   its Section. Fixed widths (Default/Narrow/Wide) stay centred within the Section
   via their max-width + mx-auto. */
/* Arrows reconstruct the design's icons/arrows-2.svg: a faded "inactive" prev and
   a solid "active" next. Colours come from the theme (var(--navy)/var(--white)),
   so brand changes flow through. The arrow glyph itself uses currentColor. */
/* The optional CTA beside a slider's arrows (Slider → Link next to the arrows).
   The design draws it sans / sentence case / 16px; the global .b-cta--link token
   is mono / UPPERCASE / 14px and is in live use elsewhere ("View product" on the
   solutions cards), so this stays scoped rather than redefining the token.

   height/padding/justify/text-align have to be restated, not just typography:
   .b-cta--link sets them at specificity (0,1,0), but the unscoped .b-cta rules
   inside the max-width 1024/640/420 media queries later in this file match at the
   SAME specificity and therefore win — which rendered this "text link" as a 44px
   tall, 18px padded button on every viewport below 1025px. Restating them here
   also neutralises the --sm/--lg size modifiers, which otherwise let the Size
   dropdown turn the link into a 70px block. font-family stays `inherit` so a
   per-section font from _style_open.html is still honoured. */
/* Keep the CTA + arrows hard right even when the slider's own heading is empty
   (a section that needs pill + heading + lead builds that stack in the
   container above and leaves the block's heading blank). With the heading div
   gone the actions become the flex row's only child and would otherwise fall
   to the left. A no-op when a heading IS present, since that div is flex-1. */
.b-slider__head .b-slider__actions { margin-left: auto; }
.b-slider__actions .b-cta--link {
    font-family: inherit; font-size: 1rem; font-weight: 500; line-height: 1.5;
    text-transform: none; letter-spacing: normal;
    height: auto; padding: 0; gap: 8px;
    justify-content: flex-start; text-align: left;
}
.b-slider__actions .b-cta--link .b-ar { width: 15px; height: 15px; }
/* The design has no underline on hover; keep the arrow nudge the button CTAs use
   as the affordance instead. */
.b-slider__actions .b-cta--link:hover { text-decoration: none; }
.b-slider__actions .b-cta--link:hover .b-ar { transform: translate(3px, -3px); }
/* .b-cta--link carries no focus ring of its own — the button variants rely on
   their chrome, which this one does not have. */
.b-slider__actions .b-cta--link:focus-visible { outline: none; border-radius: 4px; box-shadow: 0 0 0 4px rgba(28, 47, 118, .18); }
/* A slider can sit in a dark section, and .b-cta--link hard-codes navy. */
.dark-section .b-slider__actions .b-cta--link { color: var(--white); }
.b-slider__btn { width: 60px; height: 60px; flex: none; border-radius: 50%; border: none; background: var(--white); color: var(--navy); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background .2s, color .2s, opacity .2s; }
/* prev = the design's "inactive" arrow: plain white circle, faded navy arrow, no outline. */
.b-slider__btn[data-dir="prev"] { color: color-mix(in srgb, var(--navy) 45%, transparent); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--navy) 15%, transparent); }
.b-slider__btn[data-dir="prev"]:hover { color: var(--navy); }
/* next = "active" arrow: solid navy circle, white arrow. */
.b-slider__btn[data-dir="next"] { background: var(--navy); color: var(--white); }
.b-slider__btn[data-dir="next"]:hover { opacity: .85; }
/* glyph icon (FontAwesome) sits in the black glyph box, always white */
.b-card__glyph i { color: var(--white); font-size: 26px; line-height: 1; }
/* Editor bold inside a thin display heading renders as the design's .em (weight 500). */
.b-h1 strong, .b-h2 strong, .b-h3 strong, .b-h1 b, .b-h2 b, .b-h3 b { font-weight: 500; }
/* Body/lead paragraphs are weight 300, so the browser's `bolder` (Tailwind reset)
   only steps bold up to 400 — barely visible. Pin an absolute semibold instead. */
.b-body b, .b-body strong, .b-lead b, .b-lead strong { font-weight: 600; }
.b-notch { border-radius: var(--notch); }
.b-header-notch { border-radius: var(--header-notch); }

/* ---------- subheading ---------- */
.b-subheading { font-weight: 200; font-size: clamp(20px, 2.4vw, 30px); line-height: 1.3; margin: 0; }
/* Subheading → Text size (SubheadingBlock.size). Default is the rule above. */
.b-subheading--sm { font-size: clamp(15px, 1.6vw, 18px); }
.b-subheading--lg { font-size: clamp(24px, 3vw, 38px); }
.b-subheading--xl { font-size: clamp(28px, 3.6vw, 46px); }

/* ---------- hero ---------- */
/* Hero sits on a dark scrim, so its heading/subheading text is always white,
   overriding HeadingBlock's default navy. */
/* Default hero text is white (dark scrim). Headings only force white when they
   carry the default-navy class; an editor-set Text colour (no b-text-navy, colour
   on the wrapper) then wins. Subheading inherits — a custom wrapper colour wins. */
.b-hero-frame, .b-hero-frame .b-content { color: var(--hero-fg, var(--white)); }
.b-hero-frame .b-h1.b-text-navy, .b-hero-frame .b-h2.b-text-navy, .b-hero-frame .b-h3.b-text-navy { color: var(--hero-fg, var(--white)); }
/* Image overlay variants (Hero block → Image overlay). Dark = white text over a
   dark scrim (home); Light/None = dark text over a light image (product). */
.b-hero-frame--dark  { --hero-fg: var(--white); --hero-scrim-bg: var(--hero-scrim); }
.b-hero-frame--light { --hero-fg: var(--navy);  --hero-scrim-bg: var(--hero-scrim-light); }
.b-hero-frame--none  { --hero-fg: var(--navy); }
/* The hero sub-line is NOT the heading colour. Every prototype's `.hero__sub`
   fades it: --ink-70 on a light hero, ~88% white on a dark one. Ours inherited
   --hero-fg, so a light hero's sub-line came out navy. It is also a step
   smaller than our --lg default: clamp(20px,2.6vw,32px)/1.5, not
   clamp(24px,3vw,38px)/1.3. */
.b-hero-frame--light .b-subheading,
.b-hero-frame--none .b-subheading { color: rgba(0, 0, 0, .7); }
.b-hero-frame--dark .b-subheading { color: color-mix(in srgb, var(--white) 88%, var(--deep-navy)); }
.b-hero-frame .b-subheading--lg { font-size: clamp(20px, 2.6vw, 32px); line-height: 1.5; }
/* Imageless light hero (e.g. Contact "Let's talk"): a soft light gradient fills
   the notched box so it reads as a header band. The cyan/green/red glows are
   baked in here (part of the design, matching the prototype) rather than exposed
   as editor flares. An editor-set image sits on top (absolute) and covers it. */
.b-hero-frame--light .b-hero__box,
.b-hero-frame--none .b-hero__box {
    background:
        radial-gradient(circle clamp(360px, 46vw, 880px) at 4% 2%, rgba(0, 177, 235, .30), transparent 66%),
        radial-gradient(circle clamp(300px, 40vw, 740px) at 74% 46%, rgba(149, 193, 31, .22), transparent 68%),
        radial-gradient(circle clamp(280px, 36vw, 660px) at 103% 104%, rgba(229, 0, 70, .16), transparent 68%),
        linear-gradient(158deg, #eef1f8 0%, #e4e9f4 52%, #dfe5f1 100%);
}
/* Dark hero without an editor image: a dark RGB-glow band so the white text is
   visible (mirrors the light/none boxes). An editor-set image sits on top
   (absolute) and covers it. */
.b-hero-frame--dark .b-hero__box {
    background:
        radial-gradient(circle clamp(360px, 46vw, 880px) at 4% 2%, rgba(0, 177, 235, .24), transparent 66%),
        radial-gradient(circle clamp(300px, 40vw, 740px) at 74% 46%, rgba(149, 193, 31, .16), transparent 68%),
        radial-gradient(circle clamp(280px, 36vw, 660px) at 103% 104%, rgba(229, 0, 70, .16), transparent 68%),
        linear-gradient(158deg, #0b1435 0%, #0a1230 52%, #060b1e 100%);
}
/* Inset card: small --page-gap from the page's top/left/right. The negative top
   margin (= nav inset + nav height) tucks the card up so its top sits exactly
   --page-gap below the page top, with the nav bar floating inside it. */
.b-hero-frame { margin: calc(-1 * (var(--nav-inset) + var(--nav-h))) var(--page-gap) 0; }
/* Video hero: spans the full page width AND the full top — drop the side gutter,
   the rounded header notch, and pull up the extra --page-gap-top so it's flush to
   the viewport top (the nav floats over it). The framed card keeps the top gap;
   the full-bleed hero must not. The <video> renders over the poster image; on
   reduced-motion it hides so the poster shows instead. */
.b-hero-frame--full {
    margin-left: 0;
    margin-right: 0;
    margin-top: calc(-1 * (var(--page-gap-top) + var(--nav-inset) + var(--nav-h)));
}
.b-hero-frame--full .b-header-notch { border-radius: 0; }
.b-hero__video { pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .b-hero__video { display: none; } }
/* Hero height fills the viewport EXACTLY — one screenful on first load, never
   more. It was a fixed 780px (560px without buttons), which overflowed the fold
   on any short display: a 1366x768 laptop has ~650px of viewport, so the hero ran
   ~120% of the screen. Pixels can't track the display, so this is viewport-relative.

   svh (SMALL viewport height) is the unit that means "what is visible on first
   load": on mobile the URL bar is expanded at that moment, and svh is measured
   with it expanded. 100dvh would resize as the bar retracts (a layout jump mid-
   scroll) and 100lvh/100vh are measured with it RETRACTED, i.e. taller than the
   screen on load — which is the exact bug being fixed here. The plain-vh line
   before each svh line is the fallback for browsers without svh (pre-2022).

   Two variants, because the two hero frames start at different offsets:
   the framed card is tucked to --page-gap-top below the viewport top, so it must
   be that much shorter to end at the fold; the full-bleed hero starts at y=0. */
.b-hero__box { height: var(--hero-h, calc(100vh - var(--page-gap-top))); }
.b-hero-frame--full .b-hero__box { height: var(--hero-h, 100vh); }
/* The svh upgrade has to sit behind @supports, not in a second declaration.
   The usual "declare vh then svh" fallback works only for literal values: here
   the value goes through var(), so it is resolved at computed-value time, and an
   engine that cannot parse svh does not fall back to the previous declaration —
   the property becomes invalid at computed-value time and the hero collapses.
   @supports keeps the vh rule intact on those engines instead. */
@supports (height: 100svh) {
    .b-hero__box { height: var(--hero-h, calc(100svh - var(--page-gap-top))); }
    .b-hero-frame--full .b-hero__box { height: var(--hero-h, 100svh); }
}
/* Below 1024px the hero content sits in normal flow rather than absolutely (see
   .b-hero__inner's max-md: classes), so a FIXED height would clip a long heading
   on a short screen — e.g. a phone held in landscape. min-height still fills the
   viewport; the box grows past it only when the content genuinely needs it. */
@media (max-width: 1024px) {
    /* Both selectors must appear in this reset. `.b-hero-frame--full .b-hero__box`
       is (0,2,0) and outranks a bare `.b-hero__box { height: auto }` at (0,1,0),
       so the full-bleed heroes — 18 of the 23 on the site — would otherwise keep
       a hard height here and clip their own content on a short screen. */
    .b-hero__box,
    .b-hero-frame--full .b-hero__box { height: auto; }
    .b-hero__box { min-height: calc(100vh - var(--page-gap-top)); }
    .b-hero-frame--full .b-hero__box { min-height: 100vh; }
}
@supports (height: 100svh) {
    @media (max-width: 1024px) {
        .b-hero__box { min-height: calc(100svh - var(--page-gap-top)); }
        .b-hero-frame--full .b-hero__box { min-height: 100svh; }
    }
}
.b-hero-scrim { position: absolute; inset: 0; background: var(--hero-scrim-bg, var(--hero-scrim)); }
@media (max-width: 1024px) { .b-header-notch { border-radius: var(--notch); } }

/* Containers (.fedit-grid) fill their section and centre within their max-width,
   which yields side gutters on desktop. Below that max-width (tablet/phone) the
   container is 100% wide with no padding, so content runs to the screen edges —
   add a gutter there. The hero and other .b-content blocks already have their own
   gutter. Desktop NARROWER than the container hits the same problem — handled by
   the min-width:1025px width calc next to the .b-container-card rules above. */
@media (max-width: 1024px) {
    .fedit-grid:not(.is-fluid) { padding-inline: clamp(20px, 5vw, 48px); }
}

/* ============================================================================
   Small-screen scale-down. Desktop (>1024px) keeps its full scale; tablet and
   phone shrink type, components and spacing so more fits on screen. Appended
   last so these override the base sizes when the breakpoints match.
   ========================================================================== */
/* Tablet (<=1024) */
@media (max-width: 1024px) {
    .b-h1 { font-size: var(--fs, clamp(30px, 5vw, 46px)); line-height: 1.12; }
    .b-h2 { font-size: var(--fs, clamp(23px, 3.4vw, 32px)); }
    .b-h3 { font-size: var(--fs, clamp(18px, 2.4vw, 22px)); }
    .b-product-name { font-size: clamp(24px, 4vw, 38px); }
    .b-subheading { font-size: clamp(14px, 1.7vw, 16px); }
    .b-lead { font-size: var(--fs, clamp(13px, 1.5vw, 15px)); }
    .b-body { font-size: var(--fs, clamp(12px, 1.4vw, 14px)); }
    .b-eyebrow { font-size: 11px; }
    .b-cv-track { gap: 16px; }
    .b-cv-card { width: min(320px, 46vw); }
    .b-section { padding: clamp(26px, 4vw, 48px) 0; }
    .b-pill { height: 30px; padding: 0 13px; font-size: 12px; }
    .b-cta { height: 44px; padding: 0 18px; font-size: 14px; }
    .b-cta .b-ar { width: 15px; height: 15px; }
    .b-card { max-width: 320px; padding: 18px; }
    .b-card__title { font-size: clamp(17px, 2.4vw, 21px); }
    .b-card__body { font-size: clamp(13px, 1.8vw, 15px); }
    .b-card__glyph { width: 44px; height: 44px; }
    .b-card__glyph .cx-icon { width: 21px; height: 21px; }
    .b-card__glyph i { font-size: 19px; }
    .b-toggle { height: 48px; padding: 6px; border-radius: 26px; }
    .b-toggle-wrap { border-radius: 28px; }
    .b-toggle__seg { height: 34px; padding: 0 14px; font-size: 12px; }
    .b-sol-card { padding: clamp(18px, 2.6vw, 32px); }
    .b-sol-ic { width: 34px; height: 34px; }
    .b-sol-item__text { font-size: 15px; }
    .b-pcarousel__btn { width: 42px; height: 42px; }
    .b-slider__btn { width: 38px; height: 38px; }
    .b-slider__btn svg { width: 17px; height: 17px; }
    /* Oversized chrome / icons / images shrink on tablet (desktop unchanged) */
    :root { --notch: 16px 16px 64px 16px; }
    .b-statstrip__bar { width: 120px; height: 6px; }
    .b-usp__ico { width: 36px; height: 36px; font-size: 16px; border-radius: 10px; }
    .b-usp__ico svg, .b-usp__ico .cx-icon { width: 18px; height: 18px; }
    .b-hero__watch { height: 48px; font-size: 16px; gap: 10px; }
    .b-hero__watch-ic { width: 40px; height: 40px; }
    .b-hero__watch-ic svg { width: 13px; height: 13px; }
    .b-member__photo, .b-ncard__thumb, .b-mediacta { border-width: 1.5px; }
    /* stats — shrink the enormous numbers/cards so several fit per row */
    .b-pstat { min-height: 0; padding: 14px; }
    .b-pstat__num { font-size: clamp(30px, 5vw, 48px); }
    .b-pstat__lead { font-size: clamp(16px, 2.2vw, 22px); }
    .b-pstat__sub { font-size: 13px; }
    /* New blocks — scale typography in step with the core blocks above */
    .b-statstrip__num { font-size: clamp(22px, 3vw, 30px); }
    .b-statstrip__label { font-size: clamp(12px, 1.4vw, 14px); }
    .b-mediacta__title { font-size: clamp(22px, 3vw, 32px); }
    .b-mediacta__text { font-size: clamp(14px, 1.6vw, 16px); }
    .b-rcard__title { font-size: clamp(20px, 2.6vw, 24px); }
    .b-rcard__teaser { font-size: 14px; }
    .b-ncard__title { font-size: clamp(17px, 2.2vw, 20px); }
    .b-usp__label { font-size: var(--fs, clamp(15px, 1.8vw, 17px)); }
    .b-usp__body { font-size: var(--fs, 13px); }
    .b-timeline__title { font-size: clamp(16px, 2vw, 18px); }
    .b-timeline__cap { font-size: 13px; }
    .b-member__name { font-size: 17px; }
    /* footer text */
    .b-footer { padding-top: clamp(34px, 5vw, 60px); }
    .b-footer__col a, .b-footer__col p { font-size: 16px; line-height: 1.8; }
    .b-footer__col-title { font-size: 14px; }
    .b-footer__logo { width: clamp(170px, 24vw, 230px); }
    .b-footer__social i { font-size: 24px; }
    /* cluster centre image gets a gutter so it never touches the screen edges */
    .b-cluster__center { width: min(460px, 84%); }
    /* tighten the inter-block gaps (inline/Tailwind, so override) */
    .fedit-grid { gap: 22px !important; }
    [data-fedit-stack] { gap: 20px !important; }
    [data-fedit-content] { gap: 18px !important; }
}
/* Phone (<=640) */
@media (max-width: 640px) {
    .b-h1 { font-size: var(--fs, clamp(26px, 7vw, 37px)); line-height: 1.15; }
    .b-hero-frame .b-h1 { font-size: var(--fs, clamp(32px, 9vw, 44px)); }
    .b-h2 { font-size: var(--fs, clamp(22px, 5.6vw, 29px)); }
    .b-h3 { font-size: var(--fs, clamp(17px, 4.6vw, 21px)); }
    .b-product-name { font-size: clamp(14px, 4vw, 20px); }
    .b-subheading { font-size: 15px; }
    .b-lead { font-size: var(--fs, 13px); }
    .b-body { font-size: var(--fs, 12px); }
    .b-eyebrow { font-size: 10px; }
    .b-cv-track { gap: 12px; }
    .b-cv-card { width: min(260px, 54vw); }
    .b-section { padding: 18px 0; }
    .b-pill { height: 28px; padding: 0 12px; font-size: 12px; }
    .b-cta { height: 34px; padding: 0 12px; font-size: 11px; }
    .b-cta .b-ar { width: 12px; height: 12px; }
    .b-card { max-width: 210px; padding: 12px; }
    /* …but that cap exists to match .b-row-scroll__item in a horizontal scroll
       row, where a small card is the point. In a Grid CELL the cell already sets
       the width (one column on phone), so the cap just left ~133px of the 323px
       cell empty. Scoped to .b-grid__cell so carousels/scroll rows keep the cap. */
    .b-grid__cell .b-card { max-width: 100%; }
    .b-card__title { font-size: 13px; }
    .b-card__body { font-size: 11px; }
    .b-card__glyph { width: 36px; height: 36px; }
    .b-card__glyph .cx-icon { width: 17px; height: 17px; }
    .b-card__glyph i { font-size: 16px; }
    .b-toggle { height: 42px; padding: 5px; border-radius: 22px; }
    .b-toggle-wrap { border-radius: 24px; }
    .b-toggle__seg { height: 30px; padding: 0 11px; font-size: 11px; }
    .b-sol-card { padding: 14px; }
    .b-sol-ic { width: 30px; height: 30px; }
    .b-sol-item__text { font-size: 12px; }
    .b-slider__btn { width: 30px; height: 30px; }
    .b-slider__btn svg { width: 15px; height: 15px; }
    /* Oversized chrome / icons / images shrink further on phones */
    :root { --notch: 12px 12px 44px 12px; }
    .b-statstrip__bar { width: 90px; height: 5px; }
    .b-usp__ico { width: 30px; height: 30px; font-size: 14px; border-radius: 9px; }
    .b-usp__ico svg, .b-usp__ico .cx-icon { width: 15px; height: 15px; }
    .b-hero__watch { height: 36px; font-size: 12px; gap: 8px; }
    .b-hero__watch-ic { width: 30px; height: 30px; }
    .b-hero__watch-ic svg { width: 11px; height: 11px; }
    .b-member__photo, .b-ncard__thumb, .b-mediacta { border-width: 1px; }
    /* Standalone block images go full-width when columns stack here — cap + centre
       them so they don't dominate. */
    .b-figure { max-width: min(340px, 82vw); margin-left: auto; margin-right: auto; }
    .b-mediacta__img { min-height: 180px; }
    .b-pcarousel__btn { width: 36px; height: 36px; }
    .b-pstat { padding: 10px; }
    .b-pstat__num { font-size: clamp(22px, 7vw, 32px); }
    .b-pstat__lead { font-size: clamp(14px, 3.6vw, 17px); }
    .b-pstat__sub { font-size: 11px; }
    .b-pstat__bar { height: 5px; }
    /* New blocks */
    .b-statstrip__num { font-size: clamp(20px, 5.5vw, 26px); }
    .b-statstrip__label { font-size: 11px; }
    .b-mediacta__title { font-size: clamp(18px, 4.6vw, 22px); }
    .b-mediacta__text { font-size: 12px; }
    .b-rcard__title { font-size: 18px; }
    .b-rcard__teaser { font-size: 12px; }
    .b-ncard__title { font-size: 16px; }
    .b-ncard__tag, .b-ncard__date, .b-rcard__tag, .b-timeline__year, .b-member__role { font-size: 10px; }
    .b-member__expertise li { font-size: 10px; padding: 3px 8px; }
    .b-usp__label { font-size: var(--fs, 14px); }
    .b-usp__body { font-size: var(--fs, 12px); }
    .b-timeline__title { font-size: 15px; }
    .b-timeline__cap { font-size: 12px; }
    .b-member__name { font-size: 15px; }
    .b-logo { font-size: 10px; }
    .b-grid__more { font-size: 11px; }
    .b-spectable td, .b-spectable th { font-size: 12px; padding: 9px 5px; }
    .b-spectable__cap { font-size: 10px; }
    .b-table th, .b-table td { font-size: 12px; padding: 11px 12px; }
    .b-footer__col a, .b-footer__col p { font-size: 12px; line-height: 1.6; }
    .b-footer__col-title { font-size: 11px; margin-bottom: 10px; }
    .b-footer__logo { width: 140px; }
    .b-footer__social i { font-size: 20px; }
    .b-footer__legal { font-size: 11px; margin-top: 22px; }
    .b-footer__email input { height: 40px; font-size: 13px; }
    .b-cluster__center { width: min(340px, 84%); }
    /* Gaps — container gap + column row-gap are INLINE styles; the row gap is the
       Tailwind gap-6 utility; the slider has its own gap-[30px]. Override them all
       so cards (horizontal) and stacked items (vertical) sit closer together. */
    .fedit-grid { gap: 18px !important; }
    [data-fedit-stack] { gap: 16px !important; }
    [data-fedit-content] { gap: 16px !important; }
    .b-slider__track { gap: 14px !important; }
}
/* Small phone (<=420) */
@media (max-width: 420px) {
    .b-h1 { font-size: var(--fs, clamp(23px, 6.4vw, 30px)); }
    .b-hero-frame .b-h1 { font-size: var(--fs, clamp(28px, 8.5vw, 37px)); }
    .b-h2 { font-size: var(--fs, clamp(19px, 5.2vw, 24px)); }
    .b-h3 { font-size: var(--fs, clamp(16px, 4.2vw, 18px)); }
    .b-product-name { font-size: clamp(13px, 3.7vw, 16px); }
    .b-subheading { font-size: 14px; }
    .b-lead { font-size: var(--fs, 12px); }
    .b-body { font-size: var(--fs, 11px); }
    /* New blocks */
    .b-statstrip__num { font-size: clamp(18px, 4.5vw, 22px); }
    .b-statstrip__label { font-size: 10px; }
    .b-mediacta__title { font-size: clamp(16px, 4vw, 20px); }
    .b-mediacta__text { font-size: 11px; }
    .b-rcard__title { font-size: 16px; }
    .b-ncard__title { font-size: 14px; }
    .b-usp__label { font-size: var(--fs, 13px); }
    .b-usp__body { font-size: var(--fs, 11px); }
    .b-timeline__title { font-size: 14px; }
    .b-member__name { font-size: 14px; }
    .b-spectable td, .b-spectable th { font-size: 11px; padding: 8px 5px; }
    .b-table th, .b-table td { font-size: 11px; padding: 9px 10px; }
    .b-cv-track { gap: 10px; }
    .b-cv-card { width: min(210px, 58vw); }
    .b-section { padding: 14px 0; }
    .b-pill { height: 26px; padding: 0 11px; font-size: 11px; }
    .b-cta { height: 30px; padding: 0 11px; font-size: 10px; }
    .b-card { max-width: 190px; padding: 10px; }
    /* Same reasoning as the 640px block: let a grid card fill its cell. */
    .b-grid__cell .b-card { max-width: 100%; }
    .b-card__title { font-size: 12px; }
    .b-card__body { font-size: 10px; }
    .b-card__glyph { width: 32px; height: 32px; }
    .b-pstat__num { font-size: clamp(18px, 5.4vw, 24px); }
    .b-pstat__lead { font-size: 13px; }
    .b-footer__col a, .b-footer__col p { font-size: 11px; }
    .b-cluster__center { width: min(300px, 82%); }
    .fedit-grid { gap: 16px !important; }
    [data-fedit-stack] { gap: 14px !important; }
    [data-fedit-content] { gap: 14px !important; }
    .b-slider__track { gap: 12px !important; }
}
/* Slider slide widths track the card max-widths so cards shrink (and more peeks
   in) without leftover gap. The --narrow/--wide modifiers are repeated at every
   breakpoint because they are two-class selectors: they outrank the plain
   .b-slide rule regardless of source order, so omitting them here would leave a
   wide media rail at its desktop width on a phone. Wide slides stay generous
   (~86vw) so the card's image + figures stay legible, with an edge peeking to
   signal the rail scrolls. */
@media (max-width: 1024px) {
    .b-slide { width: min(320px, 76vw); }
    .b-slider__track--narrow .b-slide { width: min(280px, 70vw); }
    .b-slider__track--wide .b-slide { width: min(400px, 82vw); }
}
@media (max-width: 640px) {
    .b-slide { width: min(210px, 72vw); }
    .b-slider__track--narrow .b-slide { width: min(260px, 78vw); }
    .b-slider__track--wide .b-slide { width: min(340px, 86vw); }
}
@media (max-width: 420px) {
    .b-slide { width: min(190px, 72vw); }
    .b-slider__track--narrow .b-slide { width: min(230px, 80vw); }
    .b-slider__track--wide .b-slide { width: min(300px, 88vw); }
}

/* Advanced -> Spacing emits fixed Tailwind padding/margin utilities (pt-20 = 80px,
   pt-12 = 48px, ...) on .block-styled. These are the gaps BETWEEN sections /
   containers, and they never shrank on mobile. Scale the big ones down here. */
@media (max-width: 640px) {
    .block-styled.pt-24 { padding-top: 32px !important; }
    .block-styled.pt-20 { padding-top: 28px !important; }
    .block-styled.pt-16 { padding-top: 24px !important; }
    .block-styled.pt-12 { padding-top: 20px !important; }
    .block-styled.pt-10 { padding-top: 18px !important; }
    .block-styled.pt-8  { padding-top: 14px !important; }
    .block-styled.pb-24 { padding-bottom: 32px !important; }
    .block-styled.pb-20 { padding-bottom: 28px !important; }
    .block-styled.pb-16 { padding-bottom: 24px !important; }
    .block-styled.pb-12 { padding-bottom: 20px !important; }
    .block-styled.pb-10 { padding-bottom: 18px !important; }
    .block-styled.pb-8  { padding-bottom: 14px !important; }
    .block-styled.mt-24 { margin-top: 32px !important; }
    .block-styled.mt-20 { margin-top: 28px !important; }
    .block-styled.mt-16 { margin-top: 24px !important; }
    .block-styled.mt-12 { margin-top: 20px !important; }
    .block-styled.mt-8  { margin-top: 14px !important; }
    .block-styled.mb-24 { margin-bottom: 32px !important; }
    .block-styled.mb-20 { margin-bottom: 28px !important; }
    .block-styled.mb-16 { margin-bottom: 24px !important; }
    .block-styled.mb-12 { margin-bottom: 20px !important; }
    .block-styled.mb-8  { margin-bottom: 14px !important; }
}
@media (max-width: 420px) {
    .block-styled.pt-24, .block-styled.pt-20 { padding-top: 24px !important; }
    .block-styled.pt-16, .block-styled.pt-12 { padding-top: 18px !important; }
    .block-styled.pb-24, .block-styled.pb-20 { padding-bottom: 24px !important; }
    .block-styled.pb-16, .block-styled.pb-12 { padding-bottom: 18px !important; }
    .block-styled.mt-24, .block-styled.mt-20, .block-styled.mt-16, .block-styled.mt-12 { margin-top: 18px !important; }
    .block-styled.mb-24, .block-styled.mb-20, .block-styled.mb-16, .block-styled.mb-12 { margin-bottom: 18px !important; }
}

/* ── Table / Comparison block (TableBlock) ─────────────────────────────────
   Generic comparison/spec grid. Scrolls horizontally on narrow screens. */
.b-table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.b-table { width: 100%; border-collapse: collapse; min-width: 560px; color: var(--navy); }
.b-table th, .b-table td { padding: 16px 20px; text-align: left; vertical-align: middle; font-size: 15px; border-bottom: 1px solid color-mix(in srgb, var(--navy) 12%, transparent); }
.b-table thead th { border-bottom: 2px solid color-mix(in srgb, var(--navy) 22%, transparent); vertical-align: bottom; }
.b-table__corner { font-family: var(--mono); font-weight: 500; font-size: 14px; text-transform: uppercase; letter-spacing: .5px; color: color-mix(in srgb, var(--navy) 70%, transparent); }
.b-table__colname { display: block; font-weight: 500; font-size: 16px; }
.b-table__rowlabel { font-weight: 400; }
.b-table tbody tr:hover { background: color-mix(in srgb, var(--navy) 4%, transparent); }
.b-table__cell { white-space: nowrap; }
.b-table__celltext { color: color-mix(in srgb, var(--navy) 78%, transparent); }
.b-table__mark + .b-table__celltext { margin-left: 9px; }
.b-table__mark { font-size: 16px; }
.b-table__mark--yes { color: var(--green); }
.b-table__mark--no { color: color-mix(in srgb, var(--navy) 28%, transparent); }
.b-table__mark--partial { color: color-mix(in srgb, var(--navy) 40%, transparent); }
/* Availability / status badges under a column header */
.b-table__badge { display: inline-block; margin-top: 8px; padding: 3px 11px; border-radius: var(--r-pill-sm); font-family: var(--mono); font-weight: 500; font-size: 12px; letter-spacing: .2px; white-space: nowrap; }
.b-table__badge--positive { background: color-mix(in srgb, var(--green) 18%, transparent); color: color-mix(in srgb, var(--green) 72%, var(--navy)); }
.b-table__badge--upcoming { background: color-mix(in srgb, var(--red) 14%, transparent); color: color-mix(in srgb, var(--red) 78%, var(--navy)); }
.b-table__badge--neutral { background: color-mix(in srgb, var(--navy) 10%, transparent); color: color-mix(in srgb, var(--navy) 70%, transparent); }

/* ── Grid (GridBlock): N equal columns of child blocks ─────────────────────── */
/* align-items:start so a cell that grows (e.g. an open accordion) doesn't stretch
   its row-mates to match. */
.b-grid { display: grid; grid-template-columns: repeat(var(--grid-cols, 4), minmax(0, 1fr)); gap: 20px; align-items: start; }
.b-grid__cell { min-width: 0; }
@media (max-width: 1024px) { .b-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) { .b-grid { grid-template-columns: 1fr; } }
/* Auto columns — pack as many equal cells as fit (higher specificity beats the
   fixed-count responsive rules above). Denser min on phones. */
.b-grid.b-grid--auto { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
@media (max-width: 600px) { .b-grid.b-grid--auto { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); } }
/* Team-member grids keep small cards (several per line) on tablet/phone instead
   of the generic 1-col phone collapse that blows one photo up to full width. */
@media (max-width: 1024px) { .b-grid.b-grid--members { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 600px) { .b-grid.b-grid--members { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ── Route card (RouteCardBlock): a "who to talk to" contact route ──────────── */
.b-route { position: relative; display: flex; flex-direction: column; height: 100%; padding: 30px 28px 26px; background: var(--white); border: 2px solid color-mix(in srgb, var(--navy) 14%, #fff); border-radius: 20px; text-decoration: none; color: inherit; transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease; }
a.b-route:hover { transform: translateY(-4px); border-color: color-mix(in srgb, var(--navy) 34%, #fff); box-shadow: 0 22px 40px -22px rgba(28, 47, 118, .40); }
a.b-route:focus-visible { outline: none; box-shadow: 0 0 0 4px rgba(28, 47, 118, .18); }
.b-route__glyph { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; margin-bottom: 20px; color: #fff; background: var(--navy); }
.b-route__glyph i, .b-route__glyph svg { font-size: 22px; width: 24px; height: 24px; }
.b-route--cyan .b-route__glyph { background: var(--cyan); }
.b-route--green .b-route__glyph { background: var(--green); }
.b-route--red .b-route__glyph { background: var(--red); }
.b-route__title { font-weight: 500; font-size: 19px; line-height: 1.25; color: var(--navy); margin-bottom: 7px; }
.b-route__desc { font-weight: 400; font-size: 15px; line-height: 1.5; color: color-mix(in srgb, var(--navy) 70%, transparent); margin-bottom: 20px; }
.b-route__contact { margin-top: auto; }
.b-route__who { display: block; font-weight: 500; font-size: 15px; color: color-mix(in srgb, var(--navy) 80%, transparent); margin-bottom: 3px; }
.b-route__mail { display: inline-flex; align-items: center; gap: 7px; font-family: var(--mono); font-weight: 500; font-size: 14px; color: var(--navy); word-break: break-word; }
.b-route__ar { width: 13px; height: 13px; flex: none; transition: transform .2s ease; }
a.b-route:hover .b-route__ar { transform: translate(2px, -2px); }
/* Route grids stretch cells so every card's contact line sits at the bottom. */
.b-grid__cell:has(.b-route) { align-self: stretch; }
.b-grid__cell:has(.b-route) > .block-styled { height: 100%; }
@media (max-width: 1024px) {
    .b-route { padding: 22px 20px 20px; }
    .b-route__glyph { width: 42px; height: 42px; margin-bottom: 16px; }
    .b-route__glyph i, .b-route__glyph svg { font-size: 19px; width: 20px; height: 20px; }
    .b-route__title { font-size: 15px; }
    .b-route__desc { font-size: 12px; margin-bottom: 16px; }
    .b-route__who { font-size: 12px; }
    .b-route__mail { font-size: 11px; }
}
@media (max-width: 640px) {
    .b-route { padding: 18px 16px 16px; border-radius: 16px; }
    .b-route__glyph { width: 38px; height: 38px; margin-bottom: 12px; border-radius: 10px; }
    .b-route__glyph i, .b-route__glyph svg { font-size: 17px; width: 18px; height: 18px; }
    .b-route__title { font-size: 13px; }
    .b-route__desc { font-size: 11px; margin-bottom: 14px; }
    .b-route__who { font-size: 11px; }
    .b-route__mail { font-size: 10px; }
}

/* ── Contact form (ContactFormBlock): "Start the conversation" card ─────────── */
.b-formsec { max-width: 780px; margin: 0 auto; }
.b-formglow { position: relative; border-radius: 20px 20px 100px 20px; }
.b-formglow::before { content: ""; position: absolute; inset: -6px; border-radius: inherit; background: var(--rgb-spectrum); filter: blur(22px); opacity: .30; z-index: 0; }
/* RGB outline: a soft rainbow (spectrum) glow behind a card — editor toggle. */
.b-rgb-outline { position: relative; border-radius: var(--notch); }
.b-rgb-outline::before { content: ""; position: absolute; inset: -6px; border-radius: inherit; background: var(--rgb-spectrum); filter: blur(24px); opacity: .32; z-index: 0; }
.b-rgb-outline > .b-mediacta { position: relative; z-index: 1; }
.b-formcard { position: relative; z-index: 1; padding: clamp(28px, 3.4vw, 48px); border-radius: 20px 20px 100px 20px; border: 2px solid var(--navy); background: #fff; }
.b-formcard .b-eyebrow { display: block; margin-bottom: 6px; }
.b-formcard__title { font-weight: 300; font-size: clamp(26px, 2.6vw, 32px); line-height: 1.18; margin: 6px 0 30px; color: var(--navy); }
.b-field { margin-bottom: 20px; }
.b-field label:not(.b-cvdrop) { display: block; font-family: var(--mono); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: .4px; color: var(--navy); margin-bottom: 8px; }
.b-field input, .b-field textarea { width: 100%; font-family: var(--sans); font-size: 16px; color: var(--navy); background: #fff; border: 2px solid color-mix(in srgb, var(--navy) 16%, #fff); border-radius: 14px; padding: 13px 16px; transition: border-color .18s ease, box-shadow .18s ease; }
.b-field textarea { min-height: 140px; resize: vertical; }
.b-field input::placeholder, .b-field textarea::placeholder { color: color-mix(in srgb, var(--navy) 45%, #fff); }
.b-field input:focus, .b-field textarea:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 4px rgba(28, 47, 118, .12); }
/* Auto-filled, locked field (e.g. Role on the apply form): grayed out, not editable. */
.b-field input[readonly], .b-field input.b-field--readonly { background: color-mix(in srgb, var(--navy) 6%, #f4f5f8); color: color-mix(in srgb, var(--navy) 62%, #fff); border-color: color-mix(in srgb, var(--navy) 12%, #fff); cursor: not-allowed; box-shadow: none; }
.b-field input[readonly]:focus, .b-field input.b-field--readonly:focus { border-color: color-mix(in srgb, var(--navy) 12%, #fff); box-shadow: none; }
/* Phone field with country selector (PhoneNumberPrefixWidget): country <select> +
   national number in a row, styled to match .b-field inputs. */
.b-phone { display: flex; gap: 10px; align-items: stretch; }
.b-phone select, .b-phone input { font-family: var(--sans); font-size: 16px; color: var(--navy); background: #fff; border: 2px solid color-mix(in srgb, var(--navy) 16%, #fff); border-radius: 14px; padding: 13px 16px; transition: border-color .18s ease, box-shadow .18s ease; }
.b-phone select { flex: 0 0 auto; width: auto; max-width: 7.5rem; }
.b-phone input { flex: 1 1 auto; min-width: 0; }
.b-phone select:focus, .b-phone input:focus { outline: none; border-color: var(--navy); box-shadow: 0 0 0 4px rgba(28, 47, 118, .12); }
.b-formrow { display: flex; gap: 20px; }
.b-formrow .b-field { flex: 1; min-width: 0; }
.b-formcard .b-cta { margin-top: 6px; }
.b-formcard__status { margin-top: 18px; margin-bottom: 20px; font-family: var(--mono); font-weight: 500; font-size: 15px; line-height: 1.45; padding: 14px 18px; border-radius: 14px; }
.b-formcard__status--ok { color: var(--green); background: color-mix(in srgb, var(--green) 8%, #fff); border: 2px solid var(--green); }
.b-formcard__status--err { color: var(--red); background: color-mix(in srgb, var(--red) 8%, #fff); border: 2px solid var(--red); }
/* AJAX submit (initFormAjax): the status region is empty until JS injects a
   success/error banner, and the submit button shows a busy state while sending. */
.b-formstatus:empty { display: none; }
.b-cta[disabled], .b-cta:disabled { opacity: .6; cursor: progress; pointer-events: none; }
/* Required consent checkbox. */
.b-check { display: flex; align-items: flex-start; gap: 10px; margin: 4px 0 22px; cursor: pointer; }
.b-check input[type="checkbox"] { flex: none; width: 20px; height: 20px; margin-top: 1px; accent-color: var(--navy); cursor: pointer; }
.b-check__text { font-size: 14px; line-height: 1.5; color: color-mix(in srgb, var(--navy) 80%, transparent); }
.b-check__text p { display: inline; margin: 0; }
.b-check__text a { color: var(--navy); text-decoration: underline; }
/* Honeypot: present in the DOM for bots, moved off-screen for humans + AT. */
.b-hp { position: absolute !important; left: -9999px !important; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 540px) { .b-formrow { flex-direction: column; gap: 0; } }
@media (max-width: 1024px) {
    .b-formcard__title { font-size: clamp(18px, 2.8vw, 22px); margin-bottom: 24px; }
    .b-field { margin-bottom: 16px; }
    .b-field label:not(.b-cvdrop) { font-size: 10px; margin-bottom: 6px; }
    .b-field input, .b-field textarea { font-size: 13px; padding: 11px 14px; }
    .b-phone select, .b-phone input { font-size: 13px; padding: 11px 14px; }
    .b-field textarea { min-height: 120px; }
    .b-check__text { font-size: 12px; }
    .b-formcard__status { font-size: 12px; margin-bottom: 16px; }
}
@media (max-width: 640px) {
    .b-formcard { padding: 22px 18px; border-radius: 16px 16px 52px 16px; }
    .b-formcard__title { font-size: 16px; margin-bottom: 20px; }
    .b-field { margin-bottom: 14px; }
    .b-field label:not(.b-cvdrop) { font-size: 9.5px; margin-bottom: 5px; }
    .b-field input, .b-field textarea { font-size: 12px; padding: 8px 11px; border-radius: 11px; }
    .b-phone { gap: 8px; }
    .b-phone select, .b-phone input { font-size: 12px; padding: 8px 11px; border-radius: 11px; }
    .b-field textarea { min-height: 92px; }
    .b-check { gap: 8px; margin-bottom: 18px; }
    .b-check input[type="checkbox"] { width: 17px; height: 17px; }
    .b-check__text { font-size: 11px; }
    .b-formcard__status { font-size: 11px; padding: 12px 14px; margin-bottom: 14px; }
}

/* ── Accordion (AccordionBlock): one expand/collapse Q&A card ───────────────── */
/* Text colour inherits (editor-controlled via Advanced styling → Text). The answer
   reveals with a grid-rows 0fr→1fr transition — robust, never clips the content. */
/* No colour declared here, so an editor-set Text colour (inherited from the
   styling wrapper) wins; otherwise it inherits the page text colour. */
.b-acc { background: var(--white); box-shadow: 0 24px 33px -15px rgba(149, 149, 149, .25); padding: 24px 28px; }
.b-acc--rounded { border-radius: 12px; }
.b-acc--square { border-radius: 0; }
.b-acc__head { display: flex; align-items: flex-start; gap: 18px; width: 100%; padding: 0; background: none; border: 0; text-align: left; cursor: pointer; color: inherit; }
.b-acc__plus { flex: none; width: 20px; height: 20px; margin-top: 2px; color: var(--navy); transition: transform .25s ease; }
.b-acc__q { font-weight: 600; font-size: 16px; line-height: 1.4; color: inherit; }
.b-acc__a-wrap { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .3s ease; }
.b-acc.is-open .b-acc__a-wrap { grid-template-rows: 1fr; }
.b-acc__a { overflow: hidden; min-height: 0; padding-left: 38px; font-weight: 400; font-size: 15px; line-height: 1.55; color: inherit; opacity: .82; }
.b-acc__a p { font-size: inherit; }
.b-acc.is-open .b-acc__a { padding-top: 14px; border-top: 1px solid color-mix(in srgb, currentColor 15%, transparent); }
.b-acc.is-open .b-acc__plus { transform: rotate(45deg); }

/* ── Responsive: new blocks (Table / Comparison, Accordion, Grid, Selector) ──── */
@media (max-width: 1024px) {
    .b-table th, .b-table td { padding: 14px 16px; }
    .b-table__colname { font-size: 16px; }
    .b-table__corner, .b-table__rowlabel, .b-table__cell { font-size: 15px; }
    /* Comparison cards: narrower cards (capped) so the label column still grows
       to fill and sit as far left as possible. */
    .b-cmp { min-width: 600px; column-gap: 16px;
        grid-template-columns: minmax(180px, 1.3fr) repeat(var(--cmp-n, 2), minmax(130px, 1fr)); }
    .b-cmp__lab, .b-ccard__cell { font-size: 14px; min-height: 50px; }
    .b-ccard__head { min-height: 96px; }
    .b-ccard__name { font-size: clamp(20px, 3vw, 28px); }
    .b-acc { padding: 20px 22px; }
    .b-selector__hint { font-size: 14px; }
}
@media (max-width: 640px) {
    .b-table th, .b-table td { padding: 11px 12px; font-size: 14px; }
    .b-table__colname { font-size: 15px; }
    .b-table__corner, .b-table__rowlabel, .b-table__cell, .b-table__celltext { font-size: 13px; }
    .b-table__mark { font-size: 16px; }
    .b-cmp { min-width: 480px; column-gap: 12px; }
    .b-cmp__lab { font-size: 12px; min-height: 44px; padding-right: 8px; }
    .b-ccard__cell { font-size: 12px; min-height: 44px; padding: 6px 8px; }
    .b-ccard__head { min-height: 84px; }
    .b-ccard__foot { font-size: 12px; min-height: 50px; }
    .b-spectable td, .b-spectable th { padding: 10px 5px; }
    .b-acc { padding: 16px 18px; }
    .b-acc__head { gap: 12px; }
    .b-acc__q { font-size: 13px; }
    .b-acc__a { font-size: 12px; padding-left: 30px; }
    .b-acc.is-open .b-acc__a { margin-left: 0; }
    .b-grid { gap: 14px; }
    .b-selector__hint { font-size: 13px; }
}
/* Eval-kit Order tabs: drop the request card's shadow "halo", and render the
   "Configure your kit" checks as transparent green checks (no dark tile). */
.b-tabpanel .b-sol-card-wrap { box-shadow: none; }
/* Tick list: no tile, and the glyph itself is brand green — set it on the
   container so a masked SVG picks it up too, not just the <i>. */
.b-tabpanel .b-usp__ico { background: transparent; border: none; width: 26px; height: 26px; border-radius: 0; margin-top: 1px; color: var(--green); }
.b-tabpanel .b-usp__ico i { color: var(--green); font-size: 24px; }
/* Order checklist: a ruled list — Divider blocks sit between the icon-point rows
   (column row-gap is None); the item padding gives the rows breathing room. */
.b-tabpanel .b-usp { padding: 12px 0; align-items: center; }
.b-tabpanel .b-usp__ico .cx-icon { width: 26px; height: 26px; }
/* Tablet only: these checklist rows keep the desktop icon (26px) and any set
   --fs, which reads oversized in the narrower tab card. Compact them between
   desktop (above) and mobile (≤640, below) — both already sized, leave as is.
   min(--fs, cap) caps a large Text size the way the mobile rule does. */
@media (min-width: 641px) and (max-width: 1024px) {
    .b-tabpanel .b-usp { gap: 13px; padding: 10px 0; }
    .b-tabpanel .b-usp__ico,
    .b-tabpanel .b-usp__ico .cx-icon { width: 22px; height: 22px; }
    .b-tabpanel .b-usp__ico i { font-size: 20px; }
    .b-tabpanel .b-usp__label { font-size: min(var(--fs, clamp(15px, 1.8vw, 17px)), 15px); }
    .b-tabpanel .b-usp__body { font-size: min(var(--fs, 13px), 13px); }
}
/* Outline CTA on a dark band — white border + text (e.g. the closing "Talk to
   engineering" button on the black call-to-action band). */
.dark-section .b-cta--outline { color: #fff; border-color: rgba(255, 255, 255, .5); }
/* Solutions-card eyebrow pill — a descriptive label (e.g. "Pointer luminator ·
   LBS-Holo") can be long, so let it wrap with padding and auto height instead of
   clipping inside the fixed 40px pill. */
.b-sol-card .b-pill { height: auto; min-height: 34px; padding: 8px 18px; white-space: normal;
                      line-height: 1.25; text-align: center; font-size: 13px; margin-bottom: 18px; }
/* Slightly larger on desktop only — leave tablet/mobile at the values above. */
@media (min-width: 1024px) {
    .b-sol-card .b-pill { min-height: 38px; padding: 10px 22px; font-size: 15px; }
}
/* Mobile: match the smaller general-pill scale (this override had pinned it to
   a larger 13px). Keep min-height/white-space so long labels still wrap. */
@media (max-width: 640px) {
    .b-sol-card .b-pill { min-height: 28px; padding: 6px 12px; font-size: 12px; }
}
@media (max-width: 420px) {
    .b-sol-card .b-pill { min-height: 26px; padding: 6px 11px; font-size: 11px; }
}
/* Fit-to-width background image → cover ("fill") below an editor-chosen
   breakpoint (BackgroundSettings "Fill on small screens"). Full-width/natural-
   height reads as a thin sliver or an over-tall band on a narrow screen, so it
   fills the band instead. b-bg-fill-md fills up to tablet (≤1024), b-bg-fill-sm
   up to mobile (≤768); "Never" emits neither, keeping fit-to-width everywhere.
   !important overrides the inline size/position emitted by _style_open. */
@media (max-width: 1024px) {
    .b-bg-fit-width.b-bg-fill-md { background-size: cover !important; background-position: center !important; }
}
@media (max-width: 768px) {
    .b-bg-fit-width.b-bg-fill-sm { background-size: cover !important; background-position: center !important; }
}
/* Icon points on mobile: a per-block Text size (--fs) otherwise holds at every
   breakpoint, which is oversized on a phone — cap the label/note, and compact
   the Order checklist's icon tile + spacing. min() still lets a smaller setting
   (Extra small) through while capping large ones. */
@media (max-width: 640px) {
    .b-usp__label { font-size: min(var(--fs, 14px), 14px); }
    .b-usp__body { font-size: min(var(--fs, 12px), 12px); }
    .b-tabpanel .b-usp { gap: 11px; padding: 8px 0; }
    .b-tabpanel .b-usp__ico,
    .b-tabpanel .b-usp__ico .cx-icon { width: 20px; height: 20px; }
}
/* Quote (QuoteBlock) — pull-quote: big lead-weight text with a navy left rule.
   Fluid so it scales down on phones (per the responsive rule). */
.b-quote { margin: clamp(28px, 4vw, 44px) 0; padding: 6px 0 6px clamp(18px, 3vw, 34px); border-left: 3px solid var(--navy); }
.b-quote__text { font-weight: 200; font-size: clamp(20px, 3.2vw, 32px); line-height: 1.3; color: var(--black); margin: 0; }
.b-quote__cite { display: block; margin-top: 14px; font-family: var(--mono); font-weight: 400; font-size: 14px; font-style: normal; color: color-mix(in srgb, var(--navy) 70%, transparent); }
.dark-section .b-quote { border-left-color: rgba(255, 255, 255, .4); }
.dark-section .b-quote__text { color: #fff; }
.dark-section .b-quote__cite { color: rgba(255, 255, 255, .7); }
/* Rich-text body copy (e.g. Privacy policy, article prose) — the CSS reset strips
   list bullets and paragraph margins, so restore them for lists and stacked
   blocks inside .b-body / .b-lead. em-based, so it scales with the text. */
.b-body > * + *, .b-lead > * + * { margin-top: 1em; }
.b-body ul, .b-body ol, .b-lead ul, .b-lead ol { margin: 1em 0; padding-left: 1.4em; }
.b-body ul, .b-lead ul { list-style: disc; }
.b-body ol, .b-lead ol { list-style: decimal; }
.b-body li, .b-lead li { margin: .4em 0; }
.b-body li::marker { color: var(--navy); }
.dark-section .b-body li::marker { color: rgba(255, 255, 255, .6); }
/* Page index (PageIndexBlock) — "On this page" TOC in a left column. Sticky is
   applied to the grid COLUMN (a sticky grid item sticks within the grid, which is
   as tall as the body column beside it) — NOT to .b-toc, whose own wrapper is
   only its height. align-self:start keeps the item content-height so it can move. */
.fedit-grid > .block-styled:has(.b-toc) {
    position: sticky;
    top: calc(var(--nav-h, 66px) + 34px);
    align-self: start;
}
/* Desktop: the title is a plain label (the whole thing is an always-open sticky
   sidebar), so strip button chrome and hide the caret. */
.b-toc__title { display: block; width: 100%; text-align: left; background: none; border: 0; cursor: default;
    font-family: var(--mono); font-weight: 500; font-size: 13px; text-transform: uppercase; letter-spacing: .5px; color: color-mix(in srgb, var(--navy) 55%, transparent); margin: 0 0 14px; padding: 0; }
.b-toc__caret { display: none; }
.b-toc__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; border-left: 1px solid color-mix(in srgb, var(--navy) 14%, transparent); }
.b-toc__list a { display: block; padding: 7px 0 7px 16px; margin-left: -1px; border-left: 2px solid transparent; font-size: 15px; line-height: 1.35; color: color-mix(in srgb, var(--navy) 68%, transparent); text-decoration: none; transition: color .15s ease, border-color .15s ease; }
.b-toc__list a:hover { color: var(--navy); }
.b-toc__list a.is-active { color: var(--navy); border-left-color: var(--navy); font-weight: 500; }
/* headings clear the sticky nav when jumped to via a TOC link */
.b-page .b-h2 { scroll-margin-top: calc(var(--nav-h, 66px) + 30px); }
.dark-section .b-toc__list { border-left-color: rgba(255,255,255,.18); }
.dark-section .b-toc__list a { color: rgba(255,255,255,.7); }
.dark-section .b-toc__list a:hover, .dark-section .b-toc__list a.is-active { color: #fff; border-left-color: #fff; }
/* Mobile: the 2-col layout stacks, so the index becomes a compact collapsible bar
   above the body (closed by default) — never a tall block that shoves content down. */
@media (max-width: 900px) {
    .fedit-grid > .block-styled:has(.b-toc) { position: static; }
    .b-toc { border: 1px solid color-mix(in srgb, var(--navy) 14%, transparent); border-radius: 12px; overflow: hidden; }
    .b-toc__title { display: flex; align-items: center; justify-content: space-between; gap: 10px;
        margin: 0; padding: 11px 14px; cursor: pointer; font-size: 11px; }
    .b-toc__caret { display: block; flex: none; transition: transform .2s ease; color: color-mix(in srgb, var(--navy) 60%, transparent); }
    .b-toc.is-open .b-toc__caret { transform: rotate(180deg); }
    .b-toc__list { display: none; padding: 2px 14px 10px; border-left: 0; }
    .b-toc.is-open .b-toc__list { display: flex; border-left: 1px solid color-mix(in srgb, var(--navy) 14%, transparent); margin-left: 4px; }
    .b-toc__list a { padding: 6px 0 6px 12px; font-size: 12.5px; line-height: 1.3; }
    .dark-section .b-toc { border-color: rgba(255,255,255,.2); }
}
/* Secondary (outline) CTA inside a dark hero — white border + text so it reads on
   the dark scrim (e.g. the "All open roles" ghost button on a vacancy hero). */
.b-hero-frame--dark .b-cta--outline { color: #fff; border-color: rgba(255, 255, 255, .5); }
/* Column card — when a Column has a background (ColumnStyle.background), pad it so
   its content isn't flush to the edges; the bg + rounded come from the styled
   wrapper (_style_open). Turns a column into a contained card (e.g. a vacancy
   "At a glance" sidebar). */
.b-col-card { padding: clamp(22px, 2.4vw, 32px); box-shadow: 0 12px 34px rgba(5, 4, 22, .07); }
.b-col-card--rounded { border-radius: clamp(16px, 1.7vw, 22px); }
/* Numbered list (NumberedListBlock) — steps as circled numbers + label + text in
   a responsive grid (4 → 2 → 1). Flips white inside a Dark colour-scheme card. */
.b-numlist { list-style: none; margin: 0; padding: 0 0 clamp(18px, 2.6vw, 28px); display: grid; gap: clamp(22px, 2.6vw, 32px); grid-template-columns: repeat(var(--nl-cols, 4), minmax(0, 1fr)); }
.b-numlist__item { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.b-numlist__n { width: clamp(30px, 3.4vw, 38px); height: clamp(30px, 3.4vw, 38px); border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-family: var(--mono); font-weight: 500; font-size: clamp(12px, 1.6vw, 15px); color: var(--navy); border: 1.5px solid color-mix(in srgb, var(--navy) 42%, transparent); }
.b-numlist__label { font-family: var(--sans); font-weight: 400; font-size: clamp(13px, 1.7vw, 16px); line-height: 1.3; color: #000; margin: 0; }
.b-numlist__text { font-weight: 300; font-size: clamp(11px, 1.4vw, 13px); line-height: 1.5; color: color-mix(in srgb, #000 68%, transparent); margin: 0; }
.dark-section .b-numlist__n { border-color: rgba(255, 255, 255, .45); color: #fff; }
.dark-section .b-numlist__label { color: #fff; }
.dark-section .b-numlist__text { color: rgba(255, 255, 255, .72); }
@media (max-width: 900px) { .b-numlist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .b-numlist { grid-template-columns: 1fr; } }
/* Info card (InfoCardBlock) — a bordered "facts" card (vacancy "At a glance").
   Comfortable on desktop (where it's a narrow sidebar), compacted on phones (see
   the ≤560px block below). Fixed sizes, not vw — it must not scale with the wide
   viewport when it lives in a narrow column. */
.b-infocard { position: relative; padding: clamp(20px, 2.6vw, 28px); border-radius: 18px 18px 52px 18px;
    border: 2px solid color-mix(in srgb, var(--navy) 16%, transparent);
    background: color-mix(in srgb, var(--navy) 5%, var(--white)); overflow: hidden; }
.b-infocard__strip { height: 6px; width: min(200px, 58%); margin-bottom: clamp(16px, 2vw, 22px); }
.b-infocard__title { font-family: var(--sans); font-weight: 300; font-size: calc(clamp(16px, 2vw, 19px) * var(--tscale, 1)); line-height: 1.25; color: #000; margin: 0 0 clamp(12px, 1.6vw, 18px); }
.b-infocard__facts { display: flex; flex-direction: column; gap: clamp(12px, 1.4vw, 15px); margin: 0 0 20px; }
.b-infocard__row { display: flex; flex-direction: column; gap: 2px; margin: 0; }
.b-infocard__k { font-family: var(--mono); font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: color-mix(in srgb, var(--navy) 55%, transparent); margin: 0; }
.b-infocard__v { font-weight: 400; font-size: calc(clamp(13px, 1.6vw, 16px) * var(--tscale, 1)); color: var(--navy); margin: 0; }
.b-infocard__list { list-style: disc; padding-left: 1.15em; margin: 0 0 20px; display: flex; flex-direction: column; gap: 8px; }
.b-infocard__list li { font-weight: 300; font-size: calc(clamp(12px, 1.5vw, 14px) * var(--tscale, 1)); line-height: 1.5; color: color-mix(in srgb, var(--navy) 80%, transparent); }
.b-infocard__list li::marker { color: color-mix(in srgb, var(--navy) 45%, transparent); }
.b-infocard__cta { margin-top: 2px; }
.b-infocard__cta .b-cta { width: 100%; height: clamp(44px, 5vw, 52px); padding: 0 20px; font-size: clamp(13px, 1.6vw, 15px); }
@media (max-width: 560px) {
    /* Sizes/spacing scale via clamp() above; only the corner radius changes here. */
    .b-infocard { border-radius: 14px 14px 38px 14px; }
}
/* Form fields (dynamic) — required marker, help hint, error message. */
.b-field__req { color: var(--red); }
.b-field__hint { display: block; margin-top: 5px; font-size: 13px; color: color-mix(in srgb, var(--navy) 55%, transparent); }
.b-field__err { display: block; margin-top: 5px; font-size: 13px; color: var(--red); }
.b-field--err input, .b-field--err textarea, .b-field--err select { border-color: var(--red); }
/* Form section header — eyebrow · title · intro, ABOVE the form card. */
.b-formsec__head { margin-bottom: clamp(28px, 4vw, 44px); }
.b-formsec__title { font-family: var(--sans); font-weight: 200; font-size: clamp(30px, 4vw, 46px); line-height: 1.15; color: #000; margin: 14px 0 0; }
.b-formsec__intro { margin-top: 16px; font-weight: 300; font-size: clamp(15px, 1.7vw, 18px); line-height: 1.55; color: color-mix(in srgb, var(--navy) 72%, transparent); }
/* File upload — large size renders a drag & drop zone (data-cvdrop, wired in
   brilliance.js); small size is the compact native input (editor-controlled via
   the field's "Large field" toggle). Also: large multi-line field = more rows. */
.b-cvdrop { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; padding: clamp(24px, 3vw, 34px) 20px; border: 1.5px dashed color-mix(in srgb, var(--navy) 34%, transparent); border-radius: 14px; background: color-mix(in srgb, var(--navy) 3%, transparent); cursor: pointer; transition: border-color .15s ease, background .15s ease; }
.b-cvdrop.is-over { border-color: var(--cyan); background: color-mix(in srgb, var(--cyan) 9%, transparent); }
.b-cvdrop__ico { color: color-mix(in srgb, var(--navy) 55%, transparent); }
.b-cvdrop__title { font-weight: 500; font-size: 16px; color: var(--navy); }
.b-cvdrop__hint { font-size: 14px; color: color-mix(in srgb, var(--navy) 60%, transparent); }
.b-cvdrop__types { margin-top: 6px; font-family: var(--mono); font-size: 12px; color: color-mix(in srgb, var(--navy) 50%, transparent); }
.b-cvdrop__file { display: none; margin-top: 8px; font-size: 14px; font-weight: 500; color: var(--green); }
.b-cvdrop.has-file .b-cvdrop__file { display: block; }
.b-cvdrop input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; overflow: hidden; }
.b-field--lg textarea { min-height: 180px; }
/* 404 / not-found page — centered bordered panel with a big RGB-accented code. */
.b-nf { display: flex; align-items: center; justify-content: center; min-height: 62vh; padding: clamp(40px, 8vw, 80px) 0; }
.b-nf__panel { position: relative; width: 760px; max-width: 100%; padding: clamp(34px, 5vw, 64px) clamp(24px, 5vw, 60px); background: var(--snow); border: 2px solid var(--navy); border-radius: var(--notch); text-align: center; overflow: hidden; }
.b-nf__rgb { width: 240px; max-width: 60%; margin: 0 auto 28px; }
.b-nf__panel .b-eyebrow { display: inline-block; margin-bottom: 12px; }
.b-nf__code { font-family: var(--sans); font-weight: 200; font-size: clamp(84px, 22vw, 140px); line-height: 1; letter-spacing: -3px; color: var(--navy); margin: 0 0 12px; }
.b-nf__code-em { background: var(--rgb-spectrum); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.b-nf__title { font-family: var(--sans); font-weight: 200; font-size: clamp(26px, 3.4vw, 40px); line-height: 1.15; color: #000; margin: 0 0 16px; }
.b-nf__title b { font-weight: 500; }
.b-nf__body { font-weight: 400; font-size: clamp(16px, 1.8vw, 20px); line-height: 1.55; color: color-mix(in srgb, #000 82%, var(--snow)); max-width: 520px; margin: 0 auto 32px; }
.b-nf__ctas { display: flex; gap: 16px; flex-wrap: wrap; justify-content: center; }
/* 404 editor page — the big code numeral (an h1) + its RGB-gradient digit (the
   bold char). Scoped to the 404 page so it doesn't affect other h1s. */
/* Error pages (404/403/400/500) — the big RGB-gradient code numeral (an h1);
   the bold char is the gradient digit. Shared `template-errorpage` body class so
   one rule styles every editable error page (was scoped to template-notfoundpage). */
.template-errorpage .b-h1 { font-size: clamp(84px, 22vw, 140px); letter-spacing: -3px; line-height: 1; color: var(--navy); }
.template-errorpage .b-h1 b { font-weight: 200; background: var(--rgb-spectrum); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
/* Full-bleed (video) hero on mobile: content is top-aligned and the hero is pulled
   flush to the viewport top (behind the nav), so add extra top padding to clear
   the nav bar — otherwise the heading touches it. Framed heros don't need this
   (they sit --page-gap-top below the top). */
@media (max-width: 767px) {
    .b-hero-frame--full .b-hero__inner { padding-top: calc(var(--page-gap-top) + var(--nav-inset) + var(--nav-h) + 34px); }
}
/* File dropzone copy: "Drag & drop" only makes sense with a pointer. On touch
   (mobile/tablet, ≤1024px) show "Tap to upload" and drop the "or browse" hint. */
.b-cvdrop__title--tap { display: none; }
@media (max-width: 1024px) {
    .b-cvdrop__title--drop, .b-cvdrop .b-cvdrop__hint { display: none; }
    .b-cvdrop__title--tap { display: block; }
}
/* Smooth in-page anchor transitions (e.g. an Apply CTA jumping to the form),
   disabled for reduced-motion. Anchored sections clear the sticky nav. */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.b-formsec { scroll-margin-top: calc(var(--nav-h, 66px) + 40px); }
/* Editor-anchored section (SectionBlock "Anchor ID"): offset the scroll target
   so the fixed nav doesn't cover the section top when a CTA jumps to it. */
.b-sec-anchor { scroll-margin-top: calc(var(--nav-h, 66px) + 24px); }

/* ─────────────────────────────────────────────────────────────────────────────
   Feature card add-ons: numbered kicker + RGB top bar
   ("01 / Silicon Nitride Photonics Platform" boxes on the Technology page).
   ───────────────────────────────────────────────────────────────────────────── */
.b-card__kicker {
    position: relative; z-index: 2; display: block;
    font-family: var(--mono); font-weight: 500; font-size: 13px;
    letter-spacing: .5px; color: var(--navy); margin-bottom: 2px;
}
/* Image cards are dark, so the kicker has to flip like the title does. */
.b-card--img .b-card__kicker, .dark-section .b-card__kicker { color: color-mix(in srgb, var(--white) 78%, transparent); }
/* The bar uses ::after, NOT ::before: .b-card--rgb::before already draws the
   gradient outline (with a mask + 2px padding). Sharing one pseudo-element would
   merge the two rules' properties and the mask would swallow the bar — so "RGB
   outline" and "RGB top bar" can be combined and each still renders. */
.b-card--bar { position: relative; }
.b-card--bar::after {
    content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
    background: var(--rgb-spectrum); z-index: 3; pointer-events: none;
    /* Round the bar's own top corners to match --notch's top pair rather than
       clipping the card — .b-card is deliberately overflow: visible. */
    border-radius: var(--r-md) var(--r-md) 0 0;
}

/* ─────────────────────────────────────────────────────────────────────────────
   Media stat card (MediaStatCardBlock) — 4:3 image + tag chip + prose + figures.
   ───────────────────────────────────────────────────────────────────────────── */
.b-mscard {
    display: flex; flex-direction: column; height: 100%; min-width: 0;
    background: var(--white); border: 2px solid color-mix(in srgb, var(--navy) 14%, transparent);
    border-radius: var(--notch); overflow: hidden;
}
.b-mscard--link { transition: transform .2s ease, box-shadow .2s ease; }
.b-mscard--link:hover { transform: translateY(-3px); box-shadow: 0 18px 40px -24px rgba(5, 4, 22, .5); }
.b-mscard__media { position: relative; aspect-ratio: 4 / 3; background: var(--deep-navy); overflow: hidden; }
.b-mscard__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.b-mscard__tag {
    position: absolute; left: 16px; top: 16px; z-index: 2;
    display: inline-flex; align-items: center; height: 28px; padding: 0 13px;
    background: color-mix(in srgb, var(--deep-navy) 62%, transparent);
    backdrop-filter: blur(6px); border: 1px solid rgba(255, 255, 255, .28);
    border-radius: var(--r-pill-sm);
    font-family: var(--mono); font-weight: 500; font-size: 11px;
    text-transform: uppercase; letter-spacing: .5px; color: var(--white);
}
.b-mscard__body { display: flex; flex-direction: column; flex: 1; gap: 14px; padding: 28px 30px 34px; }
/* --fs is the per-block "Text size" from Advanced → Text; capped so an oversized
   editor setting can't blow the card out, while a smaller one still passes through. */
.b-mscard__title { font-weight: 300; font-size: min(var(--fs, clamp(20px, 2.3vw, 28px)), 28px); line-height: 1.2; color: var(--black); }
.b-mscard__title--h2 { font-size: min(var(--fs, clamp(24px, 2.8vw, 32px)), 32px); }
.b-mscard__text { font-weight: 400; font-size: 16px; line-height: 1.55; color: color-mix(in srgb, var(--black) 70%, transparent); }
/* margin-top:auto pins the figure row to the card's bottom edge so a rail of
   cards with different copy lengths still lines its numbers up. */
.b-mscard__stats {
    display: flex; flex-wrap: wrap; gap: 20px 30px; margin-top: auto; padding-top: 22px;
    border-top: 1px solid color-mix(in srgb, var(--navy) 14%, transparent);
}
.b-mstat { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.b-mstat__n { font-weight: 500; font-size: 24px; line-height: 1; letter-spacing: -.3px; font-variant-numeric: tabular-nums; }
.b-mstat__suffix { font-size: .52em; font-weight: 500; margin-left: 3px; letter-spacing: 0; color: color-mix(in srgb, var(--black) 60%, transparent); }
.b-mstat__l { font-family: var(--mono); font-weight: 500; font-size: 11px; letter-spacing: .4px; text-transform: uppercase; color: color-mix(in srgb, var(--black) 60%, transparent); }
.dark-section .b-mscard { background: color-mix(in srgb, var(--white) 6%, transparent); border-color: rgba(255, 255, 255, .16); }
.dark-section .b-mscard__title { color: var(--white); }
.dark-section .b-mscard__text, .dark-section .b-mstat__l, .dark-section .b-mstat__suffix { color: rgba(255, 255, 255, .76); }
.dark-section .b-mscard__stats { border-top-color: rgba(255, 255, 255, .16); }
@media (max-width: 1024px) {
    .b-mscard__body { padding: 24px 24px 28px; }
}
@media (max-width: 640px) {
    .b-mscard { border-radius: 20px 20px 60px 20px; }
    .b-mscard__body { padding: 22px 22px 26px; gap: 12px; }
    .b-mscard__title { font-size: min(var(--fs, clamp(20px, 2.3vw, 28px)), 22px); }
    .b-mscard__title--h2 { font-size: min(var(--fs, clamp(24px, 2.8vw, 32px)), 24px); }
    .b-mscard__text { font-size: 15px; }
    .b-mscard__stats { gap: 14px 20px; padding-top: 18px; }
    .b-mstat__n { font-size: 21px; }
}
/* Three 21px figures side by side clip on a small phone — go two-up instead. */
@media (max-width: 560px) {
    .b-mscard__stats { display: grid; grid-template-columns: 1fr 1fr; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   Download card add-on: description line between the title and the type line.
   ───────────────────────────────────────────────────────────────────────────── */
.b-dl__sub { font-weight: 400; font-size: 14px; line-height: 1.5; color: color-mix(in srgb, var(--black) 60%, transparent); margin-top: 4px; }
.dark-section .b-dl__sub { color: rgba(255, 255, 255, .72); }

/* ─────────────────────────────────────────────────────────────────────────────
   CTA band (CtaBandBlock) — closing panel on a dark gradient.
   The backdrop is three brand radial glows over a diagonal charcoal gradient;
   colours come from the brand tokens so a rebrand flows through.
   ───────────────────────────────────────────────────────────────────────────── */
.b-ctaband { position: relative; overflow: hidden; border-radius: var(--r-md); }
.b-ctaband--dark {
    color: var(--white);
    background:
        radial-gradient(42% 60% at 82% 8%, color-mix(in srgb, var(--cyan) 20%, transparent), transparent 60%),
        radial-gradient(46% 62% at 12% 96%, color-mix(in srgb, var(--green) 16%, transparent), transparent 62%),
        radial-gradient(34% 48% at 68% 104%, color-mix(in srgb, var(--red) 14%, transparent), transparent 60%),
        linear-gradient(150deg, #2a2d38 0%, #23242c 46%, #191a20 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), inset 0 0 0 1px rgba(255, 255, 255, .05);
}
.b-ctaband--light { background: var(--snow); color: var(--black); border: 2px solid color-mix(in srgb, var(--navy) 14%, transparent); }
.b-ctaband__inner { position: relative; z-index: 2; padding: clamp(44px, 6vw, 80px) clamp(24px, 4vw, 60px); }
.b-ctaband__strip { width: 100%; max-width: 1280px; margin-bottom: clamp(26px, 4vw, 40px); }
.b-ctaband--dark .b-ctaband__eyebrow { color: color-mix(in srgb, var(--white) 80%, transparent); }
.b-ctaband__heading { max-width: 760px; margin-top: 14px; }
.b-ctaband--dark .b-ctaband__heading .b-h1,
.b-ctaband--dark .b-ctaband__heading .b-h2,
.b-ctaband--dark .b-ctaband__heading .b-h3 { color: var(--white); }
.b-ctaband__sub { font-weight: 200; font-size: clamp(17px, 2vw, 24px); line-height: 1.5; max-width: 640px; margin: 20px 0 40px; }
.b-ctaband--dark .b-ctaband__sub { color: color-mix(in srgb, var(--snow) 82%, transparent); }
.b-ctaband__ctas { display: flex; gap: 16px; flex-wrap: wrap; align-items: center; }
@media (max-width: 640px) {
    .b-ctaband__inner { padding: 52px 30px; }
    .b-ctaband__sub { margin: 16px 0 30px; }
    /* Stack the buttons full-width rather than letting them wrap raggedly. */
    .b-ctaband__ctas { gap: 12px; }
    .b-ctaband__ctas .b-cta { flex: 1 1 100%; justify-content: center; }
}
