/* Copied verbatim from variants/v3-family/base.css by site-src/build_v3.py. */
/* ==========================================================================
   Prismatic Data Solutions — V3 "Control Room" family: BASE stylesheet
   Everything the family shares: reset, type, layout, components. Contains no
   palette colours of its own. Every colour here resolves through a token that
   a palette's theme.css supplies:

     --ground, --ground-rgb, --ground-deep, --panel, --panel-2, --panel-menu,
     --text, --text-rgb, --muted, --int, --int-rgb, --int-hi, --on-int,
     --line, --line-strong, --well-top, --cta-ground, --header-bg,
     --edge-core, --glow, --scrim-rgb

   The only colours declared below are brand constants that are identical in
   every palette: the ten module band hues, the spectrum tile, the three
   refraction fringe hues, and the maple-leaf red.

   Load order from a palette folder:
     ../base.css  ->  ../transitions.css  ->  theme.css
   Type: Bricolage Grotesque (display) + Albert Sans (body), both OFL, loaded
   from the Google Fonts CDN for this prototype only — the production rollout
   self-hosts them (per docs/design-notes.md).
   ========================================================================== */

/* --- Brand constants and non-colour tokens -------------------------------- */
:root {
  --maple: #D52B1E;

  /* Display face. ONE variable for every display-face rule, so the family can
     be changed in one place (Jessica 2026-09-09, comment 1: Bricolage
     Grotesque is out). Default: Overpass. The review build switches it with
     ?f=<slug>, which writes html[data-f] and overrides this line. */
  --font-display: 'Schibsted Grotesk', 'Albert Sans', system-ui, sans-serif;   /* Jessica 2026-09-10 (was Overpass) */

  /* Module band hues (spectral order) — decorative ticks only, never text */
  --h-incident: #E50000;
  --h-security: #DD4B00;
  --h-hazard: #D2B200;
  --h-risk: #A4CA00;
  --h-inspections: #7FC600;
  --h-contractor: #39BF00;
  --h-rtw: #00C66E;
  --h-committee: #00A9AE;
  --h-training: #001FD2;
  --h-document: #9A00D9;

  /* Full-spectrum tile: opens and closes on the same red so the loop has no
     seam and the static (unanimated) state still shows every colour. */
  --spectrum: linear-gradient(90deg,
    #E50000 0%, #DD4B00 10%, #D2B200 21%, #A4CA00 31%, #39BF00 42%,
    #00C66E 52%, #00A9AE 62%, #001FD2 76%, #9A00D9 88%, #E10060 95%, #E50000 100%);
  /* Same stops running top to bottom (the beam transition's leading edge). */
  --spectrum-v: linear-gradient(180deg,
    #E50000 0%, #DD4B00 10%, #D2B200 21%, #A4CA00 31%, #39BF00 42%,
    #00C66E 52%, #00A9AE 62%, #001FD2 76%, #9A00D9 88%, #E10060 95%, #E50000 100%);

  /* Refraction fringe hues (red / green / violet dispersion) */
  --f1: rgba(229, 0, 0, .85);
  --f2: rgba(0, 198, 110, .8);
  --f3: rgba(154, 0, 217, .9);

  /* Type scale (1.25) */
  --t--1: 0.8125rem;
  --t-0: 1rem;
  --t-1: 1.25rem;
  --t-2: 1.5rem;
  --t-3: 1.9375rem;
  --t-4: 2.4375rem;
  --t-5: 3.0625rem;

  /* Spacing — 8px grid */
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 32px;
  --s-5: 48px;
  --s-6: 64px;
  --s-7: 96px;
  --int-2: #476EAE;      /* in-site button blue (2026-09-10) */
  --int-2-rgb: 71, 110, 174;
  --int-2-hi: #5A82C2;
  --on-int-2: #FFFFFF;
  --sec: 68px;          /* section padding, each side (2026-09-10) */
  --sec-narrow: 44px;   /* the same below 900px */

  --wrap: 1200px;
  --header-h: 76px;
  --logo-size: 50px;      /* header prism */
  --lockup-h: 41px;       /* header wordmark lockup */
}

/* --- Reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--ground); }
body {
  margin: 0;
  background: var(--ground);
  color: var(--text);
  font-family: 'Albert Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--t-0);
  line-height: 1.62;
  overflow-x: hidden;
}
img, svg, iframe { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: 0;
  color: var(--text);
  text-wrap: balance;
}
h2 { font-size: var(--t-4); }
h3 { font-size: var(--t-2); }
h4 { font-size: var(--t-1); }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; }
a { color: var(--int); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--int-hi); }
button { font: inherit; color: inherit; }
strong { color: var(--text); font-weight: 500; }

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

.skip-link {
  position: absolute;
  left: var(--s-2);
  top: -100px;
  z-index: 450;
  background: var(--int);
  color: var(--on-int);
  padding: var(--s-1) var(--s-2);
  font-weight: 500;
  border-radius: 3px;
  text-decoration: none;
  transition: top 120ms;
}
.skip-link:focus { top: var(--s-2); }

/* --- Utilities ----------------------------------------------------------- */
.wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--s-3);
}
.measure { max-width: 66ch; }
/* Section rhythm: 68px each side (was 96, Jessica 2026-09-10: "a bit too much
   room between sections", about 30% less). --sec / --sec-narrow are the
   two values every band shares. */
.section { padding-block: var(--sec); position: relative; }
.section--tight { padding-block: var(--sec-narrow); }
.section--well { background: linear-gradient(180deg, var(--well-top), var(--ground)); }
.section__head { margin-bottom: var(--s-5); }
.section__head h2 + p { margin-top: var(--s-2); max-width: 74ch; }
.section__head--narrow { max-width: 40ch; }

.eyebrow {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.lede { font-size: var(--t-1); line-height: 1.5; color: var(--muted); }
p.body { color: var(--muted); }

/* Band tick — the module's hue, small and quiet */
.tick { position: relative; padding-top: var(--s-2); }
.tick::before {
  content: "";
  position: absolute;
  top: 0; left: 0;
  width: 34px; height: 3px;
  background: var(--band, var(--int));
}

/* --- Signature: the chromatic refraction edge ----------------------------
   A 1px light edge along the top of a panel, with the light splitting just
   below it into three offset hairlines (red / green / violet). The offsets
   widen and the fringe brightens on hover and focus. Static by default, so
   there is nothing to "finish": the resting state IS the design.           */
.rp { position: relative; }
.rp::before,
.rp::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  pointer-events: none;
}
.rp::before {
  height: 1px;
  z-index: 2;
  background: linear-gradient(90deg,
    rgba(var(--text-rgb), 0) 0%,
    rgba(var(--text-rgb), .45) 12%,
    var(--edge-core) 50%,
    rgba(var(--text-rgb), .45) 88%,
    rgba(var(--text-rgb), 0) 100%);
}
.rp::after {
  height: 4px;
  z-index: 1;
  opacity: .6;
  background-image:
    linear-gradient(90deg, transparent 2%, var(--f1) 50%, transparent 98%),
    linear-gradient(90deg, transparent 2%, var(--f2) 50%, transparent 98%),
    linear-gradient(90deg, transparent 2%, var(--f3) 50%, transparent 98%);
  background-size: 100% 1px, 100% 1px, 100% 1px;
  background-position: -9px 1px, 0 2px, 9px 3px;
  background-repeat: no-repeat;
  transition: background-position 260ms ease, opacity 260ms ease;
}
.rp:hover::after,
.rp:focus-visible::after,
.rp:focus-within::after {
  opacity: .95;
  background-position: -20px 1px, 0 2px, 20px 3px;
}
@media (prefers-reduced-motion: reduce) {
  .rp::after { transition: none; }
}

/* --- Illuminated media --------------------------------------------------- */
.lit {
  position: relative;
  background: var(--ground-deep);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: 0 40px 70px -40px var(--glow),
              0 2px 0 0 rgba(var(--text-rgb), .02) inset;
}
.lit img { filter: brightness(1.05) contrast(1.03) saturate(1.02); }
.lit::after {                       /* dark surround so the panel glows */
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 70px 12px rgba(var(--ground-rgb), .55);
  background: linear-gradient(180deg, rgba(var(--ground-rgb), .12) 0%, rgba(var(--ground-rgb), 0) 30%, rgba(var(--ground-rgb), .35) 100%);
}

/* --- Buttons ------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-1);
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t-0);
  line-height: 1;
  padding: 15px var(--s-3);
  border: 1px solid transparent;
  border-radius: 3px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 140ms, border-color 140ms, color 140ms, box-shadow 140ms;
}
.btn--primary {
  background: var(--int);
  border-color: var(--int);
  color: var(--on-int);
  box-shadow: 0 14px 28px -16px rgba(var(--int-rgb), .8);
}
.btn--primary:hover { background: var(--int-hi); border-color: var(--int-hi); color: var(--on-int); }
/* Button meaning (Jessica 2026-09-10 evening): amber (--int) is reserved for
   the buttons that go to the contact page (Schedule a Demo, Contact Us);
   every in-site button is the brand blue --int-2 (the blue approved for the
   email header band), so the amber keeps one meaning across the site.
   White on #476EAE measures 5.1:1. */
.btn--secondary {
  background: var(--int-2);
  border-color: var(--int-2);
  color: var(--on-int-2);
  box-shadow: 0 14px 28px -16px rgba(var(--int-2-rgb), .8);
}
.btn--secondary:hover { background: var(--int-2-hi); border-color: var(--int-2-hi); color: var(--on-int-2); }
.btn--quiet {
  background: rgba(var(--text-rgb), .04);
  border-color: var(--line-strong);
  color: var(--text);
}
.btn--quiet:hover { border-color: var(--int); color: var(--text); background: rgba(var(--int-rgb), .12); }
.btn--sm { padding: 10px var(--s-2); font-size: var(--t--1); }
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-2); }

/* --- Header -------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 400;                     /* below the 500 page transition overlay */
  background: var(--header-bg);
  backdrop-filter: blur(10px);
}
/* Spectrum hairline under the header. Static state uses one full tile, so
   every colour is present when animations are off; the animated state swaps
   to a 200% tile whose ends match, drifting rightwards seam-free. */
.site-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 2px;
  background-image: var(--spectrum);
  background-size: 100% 100%;
  background-repeat: repeat-x;
}
@keyframes hairline-drift {
  from { background-position: 200% 0; }
  to { background-position: 0 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .site-header::after {
    background-size: 200% 100%;
    animation: hairline-drift 20s linear infinite;
    animation-delay: var(--drift20, 0s);   /* wall-clock phase, set in the head script, so the strip continues across page loads */
  }
}
.header-bar {
  position: relative;
  max-width: 1440px;
  margin-inline: auto;
  padding: 0 var(--s-3);
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  gap: var(--s-4);
}
.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--text);
  margin-right: 0;                  /* the product tag carries the auto margin on desktop */
  flex: none;                       /* Jessica (2026-09-05): the prism was the only shrinkable item in the bar and was squeezed to a 10px sliver near the breakpoint */
}
.brand svg.logo-anim { width: var(--logo-size); height: var(--logo-size); flex: none; }
.brand .wordmark-lockup { height: var(--lockup-h); width: auto; }
/* Header wordmark = the "Prismatic" line-1 cutout only (Jessica, 2026-09-05);
   the footer keeps the full two-line lockup. --wordmark-h is the one knob. */
.brand .wordmark { height: var(--wordmark-h, 30px); width: auto; }

/* Product tag beside the brand: what the visitor is looking at. Live type
   (not the wordmark font), a hairline divider, two lines. Jessica
   (2026-09-05): everything is collision-driven. The descriptor drops only
   when the nav would touch it (1100px), the nav folds into a hamburger only
   when "Safety Spectrum" alone would touch it (1010px), and the tag stays in
   the bar until it would meet the Menu button (660px). */
.product-tag {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 1px;
  margin-right: auto;               /* the tag, not the brand, pushes the nav right when present */
  /* Sits close to the wordmark (Jessica, 2026-09-05): 18px to the divider,
     16px after it. The negative margin cancels the header bar's 32px gap. */
  margin-left: calc(18px - var(--s-4));
  padding-left: var(--s-2);
  border-left: 1px solid var(--line-strong);
  min-height: 34px;
  text-decoration: none;
  color: var(--text);
  line-height: 1.15;
  white-space: nowrap;
}
.product-tag__name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: -0.005em;
  color: var(--text);
}
.product-tag__desc {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.product-tag:hover .product-tag__name { color: var(--int-hi); }
.product-tag--nav { display: none; }
/* Collision order (Jessica, 2026-09-05): as the bar narrows, first the
   descriptor line goes, then the nav becomes a hamburger, and only when the
   tag would meet the Menu button does the tag leave the bar.
   Measured widths: brand 250; two-line tag 243; one-line tag 154; tightened
   nav 535; bar gap 24; padding 24 each side.
     brand + two-line tag + nav = 1089  -> descriptor drops below 1100px
     brand + one-line tag + nav = 1001  -> hamburger below 1010px */
@media (max-width: 1240px) and (min-width: 1011px) {
  .nav .nav__link, .nav .nav__btn { padding: 11px 9px; font-size: 0.9rem; }
  .nav .btn { white-space: nowrap; padding-inline: 14px; margin-left: var(--s-1); }
  .header-bar > .product-tag { margin-left: calc(14px - var(--s-3)); padding-left: 14px; }
  .header-bar { gap: var(--s-3); }
}
@media (max-width: 1100px) and (min-width: 1011px) {
  .header-bar > .product-tag .product-tag__desc { display: none; }
}
/* Hamburger range, full two-line tag back in the bar (1010px down to 660px):
   with the nav folded away there is nothing for it to collide with. */
@media (max-width: 1010px) {
  .header-bar > .product-tag { margin-left: calc(18px - var(--s-3)); }
  .header-bar { gap: var(--s-3); }
}
/* Below 660px the tag would run into the Menu button: it moves into the nav. */
@media (max-width: 659px) {
  .header-bar > .product-tag { display: none; }
  .brand { margin-right: auto; }    /* tag gone: the brand pushes the Menu button right again */
  .nav .product-tag--nav {
    display: flex;
    margin: 0 0 var(--s-2);
    padding: 0 0 var(--s-3);
    border-left: 0;
    border-bottom: 1px solid var(--line);
    white-space: normal;
  }
  .nav .product-tag--nav .product-tag__desc { display: block; }
}

.nav { display: flex; align-items: center; gap: 2px; }
.nav__item { position: relative; }
.nav__item--mega { position: static; }
.nav .nav__link, .nav .nav__btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: none;
  border: 0;
  padding: 11px 13px;
  color: var(--text);
  font-weight: 500;
  font-size: 0.9375rem;
  text-decoration: none;
  border-radius: 3px;
  cursor: pointer;
}
.nav__link:hover, .nav__btn:hover { background: rgba(var(--text-rgb), .08); color: var(--text); }
.nav__btn .chev {
  width: 7px; height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 150ms;
}
.nav__btn[aria-expanded="true"] .chev { transform: translateY(2px) rotate(225deg); }
.nav__btn[aria-expanded="true"] { background: rgba(var(--text-rgb), .12); }
.nav .btn { margin-left: var(--s-2); }

/* Menu panels. z-index 3 keeps them above the header's spectrum hairline
   (a ::after in the same stacking context). */
.panel {
  position: absolute;
  top: calc(100% + 2px);
  z-index: 3;
  background: var(--panel-menu);
  color: var(--text);
  border: 1px solid var(--line-strong);
  box-shadow: 0 34px 60px -20px rgba(var(--ground-rgb), .8);
  /* Open: fade in and settle down 8px. Close: fade out and lift. Visibility
     flips after the fade so a closed panel is out of the tab order, as
     display:none was. Below 1010px the panels sit inside the accordion and
     use display instead (see the mobile block). */
  display: block;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 220ms ease, transform 220ms ease, visibility 0s linear 220ms;
}
.panel[data-open] {
  opacity: 1;
  visibility: visible;
  transform: none;
  pointer-events: auto;
  transition: opacity 240ms ease, transform 240ms ease, visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .panel, .panel[data-open] { transition: none; transform: none; }
}
.panel--mega {
  right: var(--s-3);
  width: min(980px, calc(100vw - 48px));
  padding: var(--s-4) var(--s-4) 0;
}
.panel--drop { left: 0; min-width: 250px; padding: var(--s-1); }

.mega__groups { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-4); }
.mega__group-label {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s-2);
  padding-bottom: var(--s-1);
  border-bottom: 1px solid var(--line);
}
.mega__list { list-style: none; }
.mega__list a, .panel--drop a {
  display: block;
  position: relative;
  padding: 9px 10px 9px 22px;
  color: var(--text);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 500;
  border-radius: 3px;
  line-height: 1.35;
}
.mega__list a::before {
  content: "";
  position: absolute;
  left: 4px; top: 15px;
  width: 3px; height: 14px;
  background: var(--band, var(--muted));
}
.mega__list a:hover, .panel--drop a:hover { background: rgba(var(--int-rgb), .14); color: var(--text); }
.mega__list a[aria-current="page"] { color: var(--int-hi); }
.mega__foot {
  margin: var(--s-4) calc(var(--s-4) * -1) 0;
  padding: var(--s-3) var(--s-4);
  background: rgba(var(--text-rgb), .04);
  border-top: 1px solid var(--line);
}
.mega__foot a {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2);
  text-decoration: none;
  color: var(--text);
  font-weight: 500;
}
.mega__foot a:hover .m { color: var(--int-hi); }
.mega__foot .m { font-size: var(--t--1); letter-spacing: .16em; text-transform: uppercase; color: var(--int); }
.mega__foot .d { font-weight: 400; color: var(--muted); font-size: 0.9375rem; }

.nav-toggle { display: none; }
/* Phone-size brand tokens. Decoupled from the hamburger breakpoint (Jessica,
   2026-09-05): the prism and wordmark keep their desktop size until 640px. */
@media (max-width: 640px) {
  :root { --header-h: 66px; --logo-size: 42px; --lockup-h: 34px; --wordmark-h: 26px; }
}
/* Hamburger breakpoint: 1010px, the width below which the brand, the one-line
   product tag and the five desktop nav items no longer fit on one bar. */
@media (max-width: 1010px) {
  /* No backdrop-filter below the mobile breakpoint: it would make the header
     the containing block for the fixed full-screen nav panel and collapse it
     to the header's own height. Solid ground instead. */
  .site-header { background: var(--ground); backdrop-filter: none; }
  .nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--s-1);
    background: none;
    border: 1px solid var(--line-strong);
    border-radius: 3px;
    color: var(--text);
    font-weight: 500;
    font-size: 0.875rem;
    padding: 9px 12px;
    cursor: pointer;
  }
  .nav-toggle .bars { width: 16px; height: 10px; position: relative; }
  .nav-toggle .bars::before, .nav-toggle .bars::after, .nav-toggle .bars i {
    content: ""; position: absolute; left: 0; right: 0; height: 2px; background: currentColor;
  }
  .nav-toggle .bars::before { top: 0; }
  .nav-toggle .bars i { top: 4px; }
  .nav-toggle .bars::after { bottom: 0; }

  .nav {
    display: none;
    position: fixed;
    inset: var(--header-h) 0 0;
    background: var(--ground);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: var(--s-3) var(--s-3) var(--s-7);
    overflow-y: auto;
    border-top: 1px solid var(--line);
  }
  .nav[data-open] { display: flex; }
  .nav__item { border-bottom: 1px solid var(--line); }
  .nav .nav__link, .nav .nav__btn {
    width: 100%;
    justify-content: space-between;
    padding: 16px 4px;
    font-size: var(--t-1);
    border-radius: 0;
  }
  .nav .btn { margin: var(--s-4) 0 0; }
  .panel {
    position: static;
    width: auto;
    border: 0;
    box-shadow: none;
    background: transparent;
    padding: 0 0 var(--s-3);
    display: none;
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
    transition: none;
  }
  .panel[data-open] { display: block; }
  .panel--mega { padding: 0 0 var(--s-3); }
  .mega__groups { grid-template-columns: 1fr; gap: var(--s-3); }
  .mega__foot { margin: var(--s-2) 0 0; padding: var(--s-3) 0 0; background: transparent; }
}

/* --- Hero ---------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--ground);
}
/* Signature moment 1 of 2: the light beam. A wide soft spectrum wash with a
   crisp core, raking across the top of the page. */
.beam, .beam-core {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  background-image: var(--spectrum);
  background-size: 100% 100%;
  background-repeat: repeat-x;
}
/* Jessica (2026-09-04): the beam should read across the whole width, with
   only a light fade at the ends and no heavy fall-off on the left. Mask
   fades over the outer 9% only; wash and core both brighter; core 3px. */
/* Fixed geometry (Jessica, 2026-09-05): the beam is the same size on every
   page regardless of how tall the hero is. Height and offsets are in viewport
   units clamped to the values the 1440px homepage had. */
.beam {
  left: -12%; right: -12%;
  top: clamp(-28px, -2vw, -12px);
  height: clamp(120px, 14.6vw, 210px);
  transform: rotate(-10deg);
  filter: blur(40px);
  opacity: .58;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.beam-core {
  left: -12%; right: -12%;
  top: clamp(44px, 5.4vw, 78px);
  height: 3px;
  transform: rotate(-10deg);
  filter: blur(0.6px);
  opacity: 1;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
/* Keeps the ground dark under the copy, so the beam lands on the screen
   rather than on the headline. Lighter on the left than before so the beam
   is not swallowed there (text contrast re-measured after the change). */
.hero__scrim {
  position: absolute;
  z-index: 1;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(104deg, rgba(var(--scrim-rgb), .86) 0%, rgba(var(--scrim-rgb), .7) 30%,
      rgba(var(--scrim-rgb), .3) 58%, rgba(var(--scrim-rgb), .1) 100%),
    linear-gradient(0deg, var(--ground) 0%, rgba(var(--scrim-rgb), .1) 34%);
}
/* Photo heroes used to dim the beam to .34/.85; Jessica wants the beam
   identical on every page (2026-09-05), so no override. */
@media (prefers-reduced-motion: no-preference) {
  .beam, .beam-core {
    background-size: 200% 100%;
    animation: hairline-drift 9s linear infinite;    /* Jessica (2026-09-05): 46s -> 35s -> 25s -> 15s -> 9s */
    animation-delay: var(--drift9, 0s);
  }
}
.hero__inner {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: minmax(0, 1.22fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(var(--s-5), 5vw, var(--s-7));
  padding-block: clamp(var(--s-6), 7vw, 104px) clamp(var(--s-5), 5vw, 80px);
}
.hero__meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2) var(--s-3); }
.hero .eyebrow {
  font-size: 1.125rem;
  letter-spacing: .18em;
  color: color-mix(in srgb, var(--text) 60%, var(--muted));
}
.hero h1 {
  font-size: clamp(var(--t-3), 3.7vw, 2.8125rem);
  margin-top: var(--s-3);
}
/* Homepage tagline (Jessica's tradeshow copy, 2026-09-03): a short line, so
   it runs larger than a module-page h1, with the former headline beneath it
   as a lede in the full text colour. */
.hero h1.hero__tagline { font-size: clamp(2.375rem, 4.6vw, 3.625rem); letter-spacing: -0.02em; }
.hero__lede {
  margin-top: var(--s-3);
  font-size: clamp(1.1875rem, 1.6vw, 1.375rem);
  line-height: 1.4;
  font-weight: 500;
  color: var(--text);
  max-width: 44ch;
  text-wrap: balance;
}
.hero__lede + .hero__sub { margin-top: var(--s-2); }
.hero__sub {
  margin-top: var(--s-3);
  font-size: var(--t-1);
  line-height: 1.5;
  color: color-mix(in srgb, var(--text) 60%, var(--muted));
  max-width: 52ch;
}
.hero .btn-row { margin-top: var(--s-5); }
/* Homepage: the Canadian chip sits between the supporting line and the
   buttons (Jessica, 2026-09-05 pm), so the demo button closes the copy. It
   stays away from the product name so it reads as a statement about the
   company. Tighter gap to the buttons than the buttons had to the copy. */
.hero .origin--before { margin-top: var(--s-4); }
.hero .origin--before + .btn-row { margin-top: var(--s-4); }
.hero .origin--after { margin-top: var(--s-4); }   /* kept for the prototype pages */
.hero__media { position: relative; margin: 0; }   /* UA figure margin (1em 40px) was insetting the media 40px each side */
/* The product shot is framed like a monitor in the room, not a wide strip. */
.hero__media .lit { aspect-ratio: 5 / 4; }
.hero__media .lit img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 46%; }
.hero__media figcaption {
  margin-top: var(--s-2);
  font-size: var(--t--1);
  color: var(--muted);
}
/* Cut-out hero media (Jessica, 2026-09-05): the transparent multi-device PNG
   floats on the ground with the device band's soft glow behind it, no frame.
   The glow is wider than in the band so it reads as the hero's light source. */
.hero__media--cutout .device-shot {
  padding: var(--s-3) 0;
  background: radial-gradient(70% 64% at 50% 50%, rgba(var(--int-rgb), .26), rgba(var(--ground-rgb), 0) 74%);
}
.hero__media--cutout .device-shot img { width: 100%; height: auto; display: block; }
.hero__media--cutout figcaption { text-align: center; }
/* With the cut-out, the media column takes the larger share (the copy needs
   ~50ch, the devices reward every pixel) and the figure bleeds into the
   right-hand page margin, up to the viewport edge minus the bar padding, so
   the devices read as coming in from the edge of the screen rather than
   sitting in a box (Jessica, 2026-09-05: "larger"). Bleed is 0 below the
   1200px wrap, 96px at 1440 and above. */
.hero__inner--cutout {
  --bleed: clamp(0px, (100vw - 1200px) / 2 - var(--s-3), 96px);
  /* Equal columns and a fixed 40px gutter: measured 2026-09-05, the lede
     needs >= ~556px at 21px to hold two lines at 1440, and >= 506px at 19px
     at 1100. 1.18fr gave the copy 502px and the lede wrapped to three. The
     bleed keeps the image wide (652px at 1440) despite the equal split. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 40px;
}
.hero__inner--cutout .hero__media { margin-right: calc(-1 * var(--bleed)); }
/* Lede capped at 21px instead of 22px in the cut-out hero: the one pixel is
   the difference between two lines and three at 1440. */
.hero__inner--cutout .hero__lede { font-size: clamp(1.1875rem, 1.6vw, 1.3125rem); }

/* Module hero with photography: the scene reads as a lit wall panel on the
   right of the room, while the copy sits on plain ground at full contrast. */
.hero__photo { position: absolute; z-index: 0; inset: 0 0 0 38%; }
.hero__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 52% 42%;
  filter: brightness(1.04) saturate(1.03);
}
.hero__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--ground) 0%, rgba(var(--scrim-rgb), .72) 18%, rgba(var(--scrim-rgb), .06) 56%, rgba(var(--scrim-rgb), .42) 100%);
}
.hero__inner--single { grid-template-columns: minmax(0, 56ch); }
.hero--photo .hero__sub { max-width: 46ch; }

/* Canadian company chip */
.origin {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 15px 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: rgba(var(--text-rgb), .04);
  font-size: var(--t--1);
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--text) 80%, var(--muted));
}
.origin svg { width: 21px; height: 21px; fill: var(--maple); flex: none; margin-block: -1px; }

/* --- Module wall: one tile per module -------------------------------------
   Ten photographs, one label each, laid out 5x2 (or 2x5 below 1240px) so the
   wall never leaves an orphan row. Quiet at rest: the photograph and the
   module name, nothing else. The refraction edge is a hover/focus event. */
.mod-wall {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
  list-style: none;
}
.mod-wall > li { display: flex; }
.mod-tile {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ground-deep);
  border: 1px solid var(--line);
  text-decoration: none;
  color: var(--text);
  transition: border-color 200ms ease;
}
.mod-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: filter 220ms ease;
}
/* The scrim is anchored to the label block rather than to a fixed fraction of
   the tile, so a two-line module name sits on the same depth of scrim as a
   one-line name. Measured worst case over the brightest pixel of any of the
   ten photographs: 7.6:1 (see docs/status/v3-family-midnight-build.md). */
.mod-tile__label {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-2);
  background: linear-gradient(180deg, rgba(var(--ground-rgb), .80) 0%, rgba(var(--ground-rgb), .96) 100%);
}
.mod-tile__label::after {          /* the photograph fading into the scrim */
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 100%;
  height: 46px;
  background: linear-gradient(180deg, rgba(var(--ground-rgb), 0) 0%, rgba(var(--ground-rgb), .80) 100%);
}
.mod-tile__label::before {         /* band tick */
  content: "";
  display: block;
  width: 34px; height: 3px;
  margin-bottom: 10px;
  background: var(--band, var(--int));
}
.mod-tile__label h3 {
  font-size: 1.0625rem;
  letter-spacing: -0.005em;
  line-height: 1.2;
  color: var(--text);
  transition: color 200ms ease;
}
/* Refraction edge along the tile's top edge, hidden until hover or focus. */
.mod-tile::before,
.mod-tile::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 220ms ease;
}
.mod-tile::before {
  height: 1px;
  z-index: 3;
  background: linear-gradient(90deg,
    rgba(var(--text-rgb), 0) 0%,
    rgba(var(--text-rgb), .45) 12%,
    var(--edge-core) 50%,
    rgba(var(--text-rgb), .45) 88%,
    rgba(var(--text-rgb), 0) 100%);
}
.mod-tile::after {
  height: 4px;
  z-index: 2;
  background-image:
    linear-gradient(90deg, transparent 2%, var(--f1) 50%, transparent 98%),
    linear-gradient(90deg, transparent 2%, var(--f2) 50%, transparent 98%),
    linear-gradient(90deg, transparent 2%, var(--f3) 50%, transparent 98%);
  background-size: 100% 1px, 100% 1px, 100% 1px;
  background-position: -20px 1px, 0 2px, 20px 3px;
  background-repeat: no-repeat;
}
.mod-tile:hover, .mod-tile:focus-visible { border-color: var(--line-strong); }
.mod-tile:hover img, .mod-tile:focus-visible img { filter: brightness(1.08); }
.mod-tile:hover::before, .mod-tile:focus-visible::before { opacity: 1; }
.mod-tile:hover::after, .mod-tile:focus-visible::after { opacity: .95; }
.mod-tile:hover .mod-tile__label h3,
.mod-tile:focus-visible .mod-tile__label h3 { color: var(--int-hi); }
@media (prefers-reduced-motion: reduce) {
  .mod-tile, .mod-tile img, .mod-tile::before, .mod-tile::after,
  .mod-tile__label h3 { transition: none; }
}

/* Core-system strip under the wall */
/* Jessica (2026-09-06, late): headline top left, button top right on the
   same row, body text full width beneath both. The wrapper div is dissolved
   with display:contents so the two paragraphs become grid items. */
.core-strip {
  margin-top: var(--s-3);
  background: var(--panel);
  border: 1px solid var(--line);
  padding: var(--s-4);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: var(--s-4);
  align-items: start;
}
.core-strip p { color: var(--muted); max-width: none; }
.core-strip > div { display: contents; }
.core-strip__claim { grid-column: 1; grid-row: 1; }
.core-strip > .btn { grid-column: 2; grid-row: 1; justify-self: end; margin-top: 2px; }
/* Nine core features as a three-column grid (Jessica, 2026-09-06): each item
   carries a short prismatic bar, echoing the hue bars on the cards above. */
.core-grid {
  grid-column: 1 / -1; grid-row: 2;
  list-style: none; margin: var(--s-2) 0 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-2) var(--s-4);
}
.core-grid li {
  position: relative; padding-left: 1.25rem;
  color: var(--text); font-size: var(--t-0); line-height: 1.45;
}
.core-grid li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .7rem; height: 3px; border-radius: 2px;
  background: linear-gradient(90deg, #e0412f, #f2a33a, #58c26a, #3b8fe6, #8b5cf6);
}
/* The commercial headline (Jessica, 2026-09-04): unlimited users is the fact
   that answers per-seat pricing, so it leads the strip in the display face. */
.core-strip__claim {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-2);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--text);
  max-width: none;
  margin-bottom: var(--s-2);
  text-wrap: balance;
}

/* --- Who we work with: client types, not names ---------------------------- */
.proof {
  background: var(--ground);
  border-block: 1px solid var(--line);
}
.proof__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2) var(--s-5);
  padding-block: var(--s-4);
}
.proof__list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-4);
}
.proof__list li {
  position: relative;
  padding-left: 18px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-1);
  letter-spacing: -0.005em;
  color: var(--text);
  white-space: nowrap;
}
.proof__list li::before {
  content: "";
  position: absolute;
  left: 0; top: 50%;
  width: 10px; height: 3px;
  transform: translateY(-50%);
  background: var(--band, var(--int));
}
.proof__note { flex: 1 1 24rem; color: var(--muted); font-size: 0.9375rem; max-width: 52ch; }
@media (max-width: 640px) {
  .proof__list li { font-size: var(--t-0); white-space: normal; }
}

/* --- Video band ---------------------------------------------------------- */
.video-band__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: clamp(var(--s-4), 5vw, var(--s-6));
  align-items: center;
}
.video-figure { margin: 0; }
.video-figure__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--ground-deep);
  border: 1px solid var(--line);
  overflow: hidden;
  box-shadow: 0 40px 70px -40px var(--glow);
}
.video-figure iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-figure figcaption {
  margin-top: var(--s-2);
  font-size: var(--t--1);
  letter-spacing: .04em;
  color: var(--muted);
}

/* --- Splits -------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
  gap: clamp(var(--s-4), 5vw, var(--s-6));
  align-items: start;
}
.split--centre { align-items: center; }
.split__media { margin: 0; }
.split__media img { width: 100%; }
.split__media figcaption {
  margin-top: var(--s-2);
  font-size: var(--t--1);
  color: var(--muted);
  max-width: 52ch;
}
.reasons { display: grid; gap: var(--s-4); }
.reasons h3 {
  font-size: var(--t-1);
  letter-spacing: .02em;
  margin-bottom: 6px;
}
.reasons p { color: var(--muted); max-width: 62ch; }

/* --- Data band ----------------------------------------------------------- */
.data-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--ground);
  border-block: 1px solid var(--line);
}
.data-band__bg { position: absolute; inset: 0; z-index: -2; }
.data-band__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 72% 50%;
  filter: brightness(1.04);
}
.data-band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg,
    rgba(var(--scrim-rgb), .97) 0%, rgba(var(--scrim-rgb), .93) 36%,
    rgba(var(--scrim-rgb), .55) 62%, rgba(var(--scrim-rgb), .2) 100%);
}
.data-band__inner { padding-block: clamp(var(--s-6), 8vw, 116px); }
.data-band__copy { max-width: 34rem; }
.data-band__copy p {
  margin-top: var(--s-3);
  color: color-mix(in srgb, var(--text) 60%, var(--muted));
  max-width: 46ch;
}

/* --- Device / responsive band -------------------------------------------- */
.device-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-2);
  margin-top: var(--s-4);
}
.device-list li {
  font-size: var(--t--1);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text);
  border: 1px solid var(--line-strong);
  background: rgba(var(--text-rgb), .04);
  padding: 6px 12px;
  border-radius: 999px;
}
.device-shot {
  position: relative;
  padding: var(--s-4);
  background: radial-gradient(64% 60% at 50% 46%, rgba(var(--int-rgb), .22), rgba(var(--ground-rgb), 0) 72%);
}
.device-shot img { margin-inline: auto; }

/* --- Panels and lists ---------------------------------------------------- */
.two-col {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}
.panel-card {
  background: var(--panel);
  border: 1px solid var(--line);
  padding: var(--s-4);
}
.panel-card > h3 { font-size: var(--t-2); margin-bottom: var(--s-1); }
.check-list { list-style: none; display: grid; gap: var(--s-2); margin-top: var(--s-3); }
.check-list li {
  position: relative;
  padding-left: 28px;
  color: var(--muted);
  font-size: 0.9375rem;
}
.check-list li::before {
  content: "";
  position: absolute;
  left: 2px; top: 8px;
  width: 11px; height: 6px;
  border-left: 2px solid var(--int);
  border-bottom: 2px solid var(--int);
  transform: rotate(-45deg);
}

/* --- Lifecycle panels ----------------------------------------------------
   Four stages of one process, not a numbered checklist: the panels carry the
   stage name and what happens there, and nothing else. */
.steps {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}
.steps > li {
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 28px;
}
.steps h3 { font-size: var(--t-1); letter-spacing: .04em; text-transform: uppercase; margin-bottom: 6px; }
.steps p { color: var(--muted); font-size: 0.9375rem; }

/* --- Feature clusters ---------------------------------------------------- */
.feature-groups {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-3);
}
.feature-group h3 { font-size: var(--t-1); }

/* --- Add-ons -------------------------------------------------------------
   A stack of full-width boxes: each add-on gets the whole measure, so the one
   with five bullets and the one with a single sentence sit as equals. */
.addons {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-3);
}
.addon {
  background: var(--panel);
  border: 1px solid var(--line);
  padding: var(--s-3);
  display: flex;
  flex-direction: column;
}
.addon--wide > p { max-width: 78ch; }
.chip {
  align-self: flex-start;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--on-int);
  background: var(--int);
  padding: 4px 10px;
  border-radius: 999px;
  margin-bottom: var(--s-2);
}
.addon h3 { font-size: var(--t-1); margin-bottom: 6px; }
/* :not(.chip) so the body colour cannot outrank the chip's own colour, which
   is set on a single class and would otherwise lose the cascade. */
.addon p:not(.chip) { color: var(--muted); font-size: 0.9375rem; }
.addon__list { list-style: none; margin-top: var(--s-2); display: grid; gap: 7px; }
.addon__list li { position: relative; padding-left: 16px; font-size: 0.9375rem; color: var(--muted); }
.addon__list li::before {
  content: "";
  position: absolute;
  left: 0; top: 11px;
  width: 7px; height: 2px;
  background: var(--band, var(--int));
}
@media (min-width: 900px) {
  .addon__list { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--s-4); }
}

/* --- Cross links --------------------------------------------------------- */
.xlinks { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-3); list-style: none; }
.xlink {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--panel);
  border: 1px solid var(--line);
  padding: var(--s-3);
  text-decoration: none;
  color: var(--text);
  transition: background-color 180ms, border-color 180ms;
}
.xlink:hover { background: var(--panel-2); border-color: var(--line-strong); }
.xlink h3 { font-size: var(--t-1); }
.xlink p { color: var(--muted); font-size: 0.9375rem; }
.xlink span { margin-top: auto; padding-top: var(--s-2); color: var(--int); font-weight: 500; font-size: 0.875rem; }

/* --- CTA band ------------------------------------------------------------
   Signature moment 2 of 2: the full gradient at scale, spilling light up
   through the band. */
.cta-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--cta-ground);
}
.cta-band__wash {
  position: absolute;
  z-index: 0;
  left: -8%; right: -8%;
  bottom: -66%;
  height: 130%;
  background-image: var(--spectrum);
  background-size: 100% 100%;
  background-repeat: repeat-x;
  filter: blur(66px);
  opacity: .42;
  pointer-events: none;
}
.cta-band::before {                 /* crisp spectrum edge on the band top */
  content: "";
  position: absolute;
  z-index: 1;
  inset-inline: 0; top: 0;
  height: 3px;
  background-image: var(--spectrum);
  background-size: 100% 100%;
}
.cta-band::after {                  /* hairline under the band, like the footer's (Jessica 2026-09-10) */
  content: "";
  position: absolute;
  z-index: 1;
  inset-inline: 0; bottom: 0;
  height: 1px;
  background: var(--line-strong);
}
@media (prefers-reduced-motion: no-preference) {
  .cta-band__wash {
    background-size: 200% 100%;
    animation: hairline-drift 46s linear infinite;
    animation-delay: var(--drift46, 0s);
  }
}
.cta-band__inner {
  position: relative;
  z-index: 2;
  padding-block: var(--s-7);   /* the CTA band keeps its original height (Jessica 2026-09-10) */;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}
.cta-band h2 { font-size: var(--t-3); }
.cta-band p {
  margin-top: var(--s-2);
  color: color-mix(in srgb, var(--text) 60%, var(--muted));
  max-width: 50ch;
}

/* --- Footer -------------------------------------------------------------- */
.site-footer {
  position: relative;
  background: var(--ground);
  color: var(--muted);
  border-top: 1px solid transparent;
}
.footer__cols {
  padding-block: var(--s-6) var(--s-5);
  display: grid;
  grid-template-columns: 1.5fr repeat(3, 1fr);
  gap: var(--s-5) var(--s-4);
}
.footer__brand { display: flex; align-items: center; gap: 12px; text-decoration: none; }
.footer__brand svg.logo-anim { width: 48px; height: 48px; }
.footer__brand .wordmark-lockup { height: var(--footer-lockup-h, 36px); width: auto; }  /* legacy single-image lockup (prototypes) */
/* Footer lockup composed from the two line cutouts (Jessica, 2026-09-05:
   "Data Solutions" a bit bigger). Each line is its own knob. */
.footer__wordmark { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.footer__wordmark .fw-line1 { height: var(--footer-line1-h, 28px); width: auto; }
.footer__wordmark .fw-line2 { height: var(--footer-line2-h, 15px); width: auto; margin-left: var(--footer-line2-indent, 20px); }
.footer__tag { margin-top: var(--s-3); font-size: 0.9375rem; max-width: 32ch; color: var(--muted); }
.footer__cols h2 {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: var(--s-2);
}
.footer__list { list-style: none; display: grid; gap: 7px; }
.footer__list a { color: color-mix(in srgb, var(--text) 80%, var(--muted)); text-decoration: none; font-size: 0.9375rem; }
.footer__list a:hover { color: var(--text); text-decoration: underline; }
.footer__legal {
  border-top: 1px solid var(--line);
  padding-block: var(--s-4) var(--s-5);
  display: grid;
  gap: var(--s-1);
}
.footer__legal p { font-size: 0.8125rem; color: var(--muted); max-width: 92ch; }

/* --- Scroll reveal ------------------------------------------------------- */
.js .reveal > * { transition: opacity 460ms ease, transform 460ms ease; }
@media (prefers-reduced-motion: no-preference) {
  .js .reveal:not(.is-in) > * { opacity: 0; transform: translateY(10px); }
  .js .reveal > * { transition-delay: calc(var(--i, 0) * 55ms); }
}

/* --- Responsive ---------------------------------------------------------- */
@media (min-width: 1240px) {
  .mod-wall { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

@media (max-width: 1080px) {
  .hero__inner, .hero__inner--single { grid-template-columns: 1fr; gap: var(--s-5); }
  .hero__sub { max-width: 60ch; }
  /* Narrow screens: the scene becomes an illuminated strip at the foot of the
     hero instead of a scrim behind the copy, so both stay legible. */
  .hero--photo { --strip: clamp(190px, 40vw, 300px); }
  .hero__photo { inset: auto 0 0 0; height: var(--strip); z-index: 2; }
  .hero__photo img { object-position: 56% 34%; }
  .hero__photo::after {
    background: linear-gradient(180deg, var(--ground) 0%, rgba(var(--scrim-rgb), .62) 26%, rgba(var(--scrim-rgb), .18) 100%);
  }
  .hero--photo .hero__inner { padding-bottom: calc(var(--strip) + var(--s-4)); }
  .video-band__grid { grid-template-columns: 1fr; }
  .xlinks { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
  .core-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :root { --t-4: 2.0625rem; --t-5: 2.5rem; }
  .section { padding-block: var(--sec-narrow); }
  .split { grid-template-columns: 1fr; }
  .two-col, .feature-groups { grid-template-columns: 1fr; }
  .data-band::before {
    background: linear-gradient(180deg, rgba(var(--scrim-rgb), .96) 0%, rgba(var(--scrim-rgb), .9) 55%, rgba(var(--scrim-rgb), .7) 100%);
  }
  .data-band__bg img { object-position: 62% 50%; }
  .footer__cols { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  :root { --t-3: 1.6875rem; --t-4: 1.8125rem; }
  .mod-tile__label { padding: 12px; }
  .mod-tile__label h3 { font-size: 0.9375rem; }
  .mod-tile__label::before { margin-bottom: 8px; }
  .mod-tile__label::after { height: 34px; }
  .steps { grid-template-columns: 1fr; }
  .steps > li { padding: var(--s-3); }
  .footer__cols { grid-template-columns: 1fr; gap: var(--s-4); }
  .core-strip { padding: var(--s-3); grid-template-columns: minmax(0, 1fr); }
  .core-strip > .btn { grid-column: 1; grid-row: 3; justify-self: stretch; margin-top: var(--s-3); }
  .core-grid { grid-template-columns: minmax(0, 1fr); }
  .panel-card { padding: var(--s-3); }
  .hero__sub, .lede { font-size: 1.0625rem; }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; align-items: stretch; }
  .cta-band__inner { padding-block: var(--s-6); }
  .device-shot { padding: var(--s-2); }
}

/* Raised frame (Jessica, 2026-09-06): on the well gradient the plain .lit
   frame read as a rectangle painted on the background. A wide soft shadow
   lifts it, a brighter hairline defines it, and a thin prismatic edge along
   the bottom ties it to the module cards. Used on the Incident lifecycle
   figure; opt in with .lit--raised. */
.lit--raised {
  transform: translateY(-6px);
  border-color: color-mix(in srgb, var(--line) 40%, var(--text) 60%);
  /* the prismatic edge is a 3px strip of the frame's own background under
     the image (.rp already owns ::before for its top line, ::after is the
     dark surround), so no extra element is needed */
  padding-bottom: 3px;
  background:
    linear-gradient(90deg, #e0412f, #f2a33a, #58c26a, #3b8fe6, #8b5cf6) left bottom / 100% 3px no-repeat,
    var(--ground-deep);
  box-shadow: 0 36px 70px -18px rgba(0, 0, 0, .8),
              0 14px 28px -14px rgba(0, 0, 0, .6),
              0 0 60px -12px var(--glow),
              0 1px 0 0 rgba(255, 255, 255, .14) inset;
}
.lit--raised img { display: block; }

/* ==========================================================================
   Change round 2026-09-10 (Jessica and Meghan's review of 2026-09-08).
   New components and adjustments, kept together so the round is easy to read
   and to unpick: screen-reader utility, the large call-to-action button, the
   current-section underline in the nav, the Features band with its product
   image, the module core-system strip, related-module grids, the video
   poster, the device carousel, the "problems we solve" cards, the services
   pillar row and the Trust lead panel.
   ========================================================================== */

/* Visible to a screen reader, to nothing else. The only <figcaption> left on
   the site (the video's) uses it. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* The closing call to action carries the page's largest button (comment 7).
   15px + 20px line + 15px + 2px border = 56px. */
.btn--lg {
  padding: 17px var(--s-4);
  font-size: var(--t-1);
}

/* The nav item whose page (or whose panel's page) you are on. */
.nav .nav__btn[data-current],
.nav .nav__link[aria-current="page"] { position: relative; }
.nav .nav__btn[data-current]::after,
.nav .nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 13px; right: 13px; bottom: 5px;
  height: 2px;
  background: var(--int);
}
@media (max-width: 1010px) {
  .nav .nav__btn[data-current]::after,
  .nav .nav__link[aria-current="page"]::after { left: 4px; right: auto; width: 34px; bottom: 10px; }
  /* Touch target for the demo button in the mobile menu (top issue 10). */
  .nav .btn { min-height: 44px; }
}

/* --- Features band -------------------------------------------------------
   The product image bleeds off the left edge and fades out before the copy
   starts: the opposite of the hero, where the photograph sits on the right
   (top issue 1, comment 64). Above 1080px the image is absolutely positioned
   behind the band and masked; below it, the band simply stacks and the image
   sits in the same illuminated frame as every other figure, unmasked. */
.features__band { position: relative; }
.features__head .section__head { margin-bottom: 0; }
.features__band + .wrap { margin-top: var(--s-6); }
/* The feature groups under the band's heading, each with its one-line intro
   (moved up from the cards, Jessica 2026-09-10: the band had "a lot of blank
   space"). The cards below keep the heading and the list. */
.features__index {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
  max-width: 52ch;
}
.features__index li {
  position: relative;
  padding-left: 22px;
}
.features__index li::before {
  content: "";
  position: absolute;
  left: 0; top: .6em;
  width: 12px; height: 3px;
  background: var(--band, var(--int));
}
.features__index b {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-1);
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--text);
}
.features__index span {
  display: block;
  margin-top: 4px;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--muted);
}
@media (min-width: 1081px) {
  .features__copy { padding-block: var(--s-5); }
}

/* Section head with a button at its right (homepage Key features). */
.section__head--split {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-3) var(--s-5);
}
.section__head--split > div { flex: 1 1 0; min-width: min(100%, 40ch); }
.section__head--split > div > .lede { margin-top: var(--s-2); max-width: 74ch; }
.section__head--split > .btn { flex: 0 0 auto; margin-bottom: 4px; }

/* "Works on all devices" with generated device photographs (Jessica
   2026-09-10: devices at a slight angle, not straight-on frames). The image
   is the whole device, so the CSS frame, neck and foot are dropped and the
   cut-out floats on the ground like the hero devices. */
.devices--photo .device__frame,
.devices--photo .device--phone .device__frame,
.devices--photo .device--tablet .device__frame,
.devices--photo .device--laptop .device__frame,
.devices--photo .device--desktop .device__frame {
  height: var(--dev-h);
  aspect-ratio: auto;
  padding: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}
/* Named per device: the laptop base bar and the desktop neck and foot are
   set on `.device--laptop .device__frame::after` etc., and a plain
   `.devices--photo .device__frame::after` did not outrank them everywhere
   (Jessica 2026-09-10: "a weird black bar" under the laptop, "an extra black
   piece under the monitor"). */
.devices--photo .device__frame::before,
.devices--photo .device__frame::after,
.devices--photo .device--laptop .device__frame::after,
.devices--photo .device--desktop .device__frame::before,
.devices--photo .device--desktop .device__frame::after { content: none; display: none; }
.devices--photo .device__frame img {
  width: auto; height: 100%;
  max-width: 100%;
  object-fit: contain;
  object-position: center;
  border: 0;
  border-radius: 0;
}
.devices--photo .devices__stage {
  background: radial-gradient(60% 56% at 50% 46%, rgba(var(--int-rgb), .22), rgba(var(--ground-rgb), 0) 74%);
}
/* The photographs carry their own bezels and stands, so they can run taller
   than the CSS frames did without crowding the column. */
.devices--photo { --dev-h: 420px; }
@media (max-width: 900px) { .devices--photo { --dev-h: 340px; } }
@media (max-width: 640px) { .devices--photo { --dev-h: 280px; } }
.features__fade { display: none; }

/* Jessica 2026-09-10: the band should look like the hero, "with its proper
   background image that fades out on one side". So above 1080px it is the
   hero mirrored: the band sits flush with the section above (no top padding,
   as the hero sits under the header), the photograph is the band's background
   across the left half at full height, and the hero's edge gradient, turned
   round, fades it into the ground before the copy column begins at 50%. The
   copy never sits over the photograph. Below 1081px the band stacks and the
   image sits in the same illuminated frame as every other figure. */
@media (min-width: 1081px) {
  .features { padding-top: 0; }
  .features__band {
    background: var(--ground);
    isolation: isolate;
  }
  .features__head {
    position: relative;
    z-index: 2;
    display: grid;
    grid-template-columns: 50% 50%;
    align-items: center;
    min-height: 520px;
  }
  .features__head > * { grid-column: 2; }
  .features__copy { padding-block: var(--s-6); }
  .features__media {
    position: absolute;
    z-index: 0;
    inset: 0 50% 0 0;
    width: auto;
    padding: 0;
    border: 0;
    transform: none;
    background: none;
    box-shadow: none;
    overflow: hidden;
  }
  .features__media::before,
  .features__media::after { content: none; }
  .features__media img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: left center;
    filter: brightness(1.04) saturate(1.03);
  }
  .features__fade {
    display: block;
    position: absolute;
    z-index: 1;
    inset: 0 50% 0 0;
    pointer-events: none;
    background:
      linear-gradient(90deg, rgba(var(--scrim-rgb), .42) 0%, rgba(var(--scrim-rgb), .06) 40%,
        rgba(var(--scrim-rgb), .72) 80%, var(--ground) 100%);
  }
  /* A picture whose subject spans its whole width (the two Inspections
     monitors): keep it centred rather than left-anchored and start the fade
     later, so the right-hand monitor stays readable; the fade still reaches
     the ground before the copy column begins. */
  .features__band--wide .features__media img { object-fit: contain; object-position: center; }
  .features__band--wide .features__media {
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 12%, #000 88%, transparent);
  }
  .features__band--wide .features__fade {
    background:
      linear-gradient(90deg, rgba(var(--scrim-rgb), .3) 0%, rgba(var(--scrim-rgb), .04) 30%,
        rgba(var(--scrim-rgb), .04) 62%, rgba(var(--scrim-rgb), .6) 88%, var(--ground) 100%);
  }
}
@media (max-width: 1080px) {
  .features__band {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s-3);
  }
  .features__band > .wrap { max-width: none; padding-inline: 0; }
  .features__media { aspect-ratio: 16 / 9; }
  .features__media img { width: 100%; height: 100%; object-fit: cover; }
  .features__head { margin-top: var(--s-5); }
}

/* One sentence between a feature group's heading and its list. */
.feature-group__intro {
  margin-top: var(--s-1);
  margin-bottom: var(--s-2);
  font-size: 0.9375rem;
  color: var(--muted);
}
.feature-group__intro + .check-list { margin-top: 0; }

/* --- Core-system strip on a module page ----------------------------------
   The homepage strip, one line long, closing the Features section (top issue
   5). --band carries the module's hue, and the strip's light edge takes it,
   so the strip belongs to the page it is on. */
.core-strip--module {
  --edge-core: var(--band, var(--int));
  margin-top: var(--s-5);
  align-items: center;
  overflow: hidden;
  isolation: isolate;
  border-color: var(--line-strong);
}
/* Jessica 2026-09-10: the strip should stand apart from the feature cards,
   and not in the display face. It is the one statement on the page about
   every module at once, so it carries the whole spectrum (the prism motif:
   one beam, all the modules) as a faint wash behind the text and as its top
   edge, where the feature cards carry the module's single hue. The sentence
   is set in the body face, in the full text colour, so it reads as a plain
   statement rather than another headline. */
.core-strip--module::before {
  background: var(--spectrum);
  background-size: 100% 100%;
  height: 2px;
}
.core-strip--module::after { content: none; }
.core-strip--module .core-strip__wash {
  position: absolute;
  z-index: -1;
  left: -10%; right: -10%;
  top: -60%; bottom: -60%;
  background-image: var(--spectrum);
  background-size: 100% 100%;
  filter: blur(60px);
  opacity: .12;
  pointer-events: none;
}
.core-strip--module .eyebrow { grid-column: 1; grid-row: 1; color: color-mix(in srgb, var(--text) 70%, var(--muted)); }
.core-strip--module .core-strip__claim {
  grid-column: 1; grid-row: 2;
  margin: var(--s-1) 0 0;
  font-family: 'Albert Sans', sans-serif;
  font-size: var(--t-1);
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--text);
  max-width: 78ch;
  text-wrap: pretty;
}
.core-strip--module > .btn { grid-row: 1 / span 2; align-self: center; margin-top: 0; }
@media (max-width: 640px) {
  .core-strip--module > .btn { grid-row: 3; justify-self: stretch; margin-top: var(--s-3); }
}

/* --- Related modules: the grid follows the count -------------------------- */
.xlinks--1 { grid-template-columns: minmax(0, 1fr); max-width: 30rem; }
.xlinks--3 { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 641px) {
  .xlinks--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 901px) {
  .xlinks--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Trust and security: the first panel leads at full width, the rest are an
   equal-height grid beneath it (top issue 12). */
.panel-card--lead { margin-bottom: var(--s-3); }
.panel-card--lead > p { max-width: 90ch; }

/* --- Video poster --------------------------------------------------------- */
.video-poster {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: 0 40px 70px -40px var(--glow);
  text-decoration: none;
  color: var(--text);
}
.video-poster__bg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.video-poster__text {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  display: grid;
  gap: 6px;
  padding: var(--s-7) var(--s-4) var(--s-3);
  /* Deep enough under the words for AA against any photograph: at the kicker
     the overlay is ~0.85 black, so even a white pixel behind it reads as
     rgb(38,38,38) and #E9ECF8 on it is over 12:1. */
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .55) 34%,
    rgba(0, 0, 0, .85) 62%, rgba(0, 0, 0, .93) 100%);
}
.video-poster__kicker {
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: #E9ECF8;
}
.video-poster__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-3);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: #FFFFFF;
}
.video-poster__play {
  position: absolute;
  z-index: 3;
  top: 50%; left: 50%;
  width: 64px; height: 64px;
  margin: -32px 0 0 -32px;
  border-radius: 50%;
  background: var(--int);
  display: grid;
  place-items: center;
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .7);
  transition: background-color 160ms ease, transform 160ms ease;
}
.video-poster__play::before {
  content: "";
  width: 0; height: 0;
  margin-left: 5px;
  border-left: 19px solid var(--on-int);
  border-top: 12px solid transparent;
  border-bottom: 12px solid transparent;
}
.video-poster:hover .video-poster__play,
.video-poster:focus-visible .video-poster__play {
  background: var(--int-hi);
  transform: scale(1.06);
}
@media (prefers-reduced-motion: reduce) {
  .video-poster__play { transition: none; }
  .video-poster:hover .video-poster__play,
  .video-poster:focus-visible .video-poster__play { transform: none; }
}
/* The injected iframe keeps a focus ring of its own. */
.video-figure__frame iframe:focus-visible {
  outline: 2px solid var(--int);
  outline-offset: -3px;
}
@media (max-width: 640px) {
  .video-poster__text { padding: var(--s-6) var(--s-3) var(--s-3); }
  .video-poster__play { width: 52px; height: 52px; margin: -26px 0 0 -26px; }
  .video-poster__play::before { border-left-width: 15px; border-top-width: 10px; border-bottom-width: 10px; }
}

/* --- Device carousel ------------------------------------------------------
   Four real screenshots in device frames drawn here in CSS (comment 6). The
   stage keeps a fixed height so the section never jumps as the device
   changes. Without JavaScript the four stack and all four are visible; with
   it they share one cell and cross-fade. */
.devices { --dev-h: 340px; display: grid; gap: var(--s-4); }
.devices__stage {
  display: grid;
  gap: var(--s-5);
  justify-items: center;
  align-items: center;
  min-height: var(--dev-h);
}
.js .devices__stage { grid-template-areas: "stage"; gap: 0; }
.js .device { grid-area: stage; opacity: 0; transition: opacity 400ms ease; }
.js .device.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .js .device { transition: none; }
}
.device { margin: 0; display: flex; align-items: center; justify-content: center; }
.device__frame {
  position: relative;
  background: #0B0E17;
  box-shadow: 0 26px 50px -24px rgba(0, 0, 0, .85);
}
.device__frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: top;
  border: 1px solid var(--line);
  display: block;
}
.device--phone .device__frame {
  height: var(--dev-h);
  aspect-ratio: 9 / 19.5;
  padding: 9px;
  border-radius: 28px;
}
.device--phone .device__frame img { border-radius: 20px; }
.device--tablet .device__frame {
  height: var(--dev-h);
  aspect-ratio: 3 / 4;
  padding: 11px;
  border-radius: 18px;
}
.device--tablet .device__frame img { border-radius: 8px; }
.device--laptop .device__frame {
  height: calc(var(--dev-h) - 76px);
  aspect-ratio: 16 / 10;
  padding: 7px;
  border-radius: 7px 7px 3px 3px;
}
.device--laptop .device__frame::after {     /* the base bar under the screen */
  content: "";
  position: absolute;
  left: 50%; top: 100%;
  transform: translateX(-50%);
  width: 116%; height: 12px;
  background: #0B0E17;
  border-radius: 0 0 9px 9px;
  box-shadow: 0 10px 20px -12px rgba(0, 0, 0, .9);
}
.device--desktop .device__frame {
  height: calc(var(--dev-h) - 108px);
  aspect-ratio: 16 / 9;
  padding: 7px;
  border-radius: 5px;
}
.device--desktop .device__frame::after {    /* neck */
  content: "";
  position: absolute;
  left: 50%; top: 100%;
  transform: translateX(-50%);
  width: 54px; height: 26px;
  background: #0B0E17;
}
.device--desktop .device__frame::before {   /* foot */
  content: "";
  position: absolute;
  left: 50%; top: calc(100% + 26px);
  transform: translateX(-50%);
  width: 152px; height: 10px;
  border-radius: 3px;
  background: #0B0E17;
}
.devices__tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
}
.devices__tablist { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.devices__tab,
.devices__pause {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 16px;
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .1em;
  text-transform: uppercase;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 160ms ease, color 160ms ease, border-color 160ms ease;
}
.devices__tab { border-color: color-mix(in srgb, var(--band) 55%, transparent); }
.devices__tab:hover, .devices__pause:hover { color: var(--text); border-color: var(--band, var(--int)); }
/* Filled with the band hue when selected. White text on the three dark hues,
   near-black on the seven light ones: measured, never assumed. */
.devices__tab[aria-selected="true"] {
  background: var(--band);
  border-color: var(--band);
  color: #FFFFFF;
}
.devices__tab.is-dark[aria-selected="true"] { color: #10162A; }
.devices__pause { margin-left: auto; }
@media (prefers-reduced-motion: reduce) {
  .devices__tab, .devices__pause { transition: none; }
  .devices__pause { display: none; }
}
@media (max-width: 900px) { .devices { --dev-h: 300px; } }
@media (max-width: 640px) {
  .devices { --dev-h: 250px; }
  .devices__pause { margin-left: 0; }
}

/* --- Problems we solve ----------------------------------------------------
   Six cards, three across (comment 24). The problem is what the visitor's
   organization deals with today, in muted type under a neutral label; the
   answer is full strength under the module-hue label, so the two can never
   be read the wrong way round. */
.problems {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-3);
}
@media (max-width: 900px) { .problems { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .problems { grid-template-columns: minmax(0, 1fr); } }
.problems > .problem { height: 100%; }
.problem__label {
  position: relative;
  padding-left: 20px;
  font-family: 'Albert Sans', sans-serif;
  font-weight: 500;
  font-size: var(--t--1);
  letter-spacing: .14em;
  text-transform: uppercase;
}
.problem__label--before { color: var(--muted); }
.problem__label--before::before {
  content: "";
  position: absolute;
  left: 0; top: .62em;
  width: 11px; height: 2px;
  background: var(--muted);
}
/* `.panel-card > p` in pages.css sets the muted colour with higher
   specificity, so the "after" label names both classes to stay full strength
   (reviewer 2026-09-10). */
.panel-card > .problem__label--after,
.problem__label--after { margin-top: var(--s-3); color: var(--text); }
.problem__label--after::before {
  content: "";
  position: absolute;
  left: 2px; top: .34em;
  width: 10px; height: 5px;
  border-left: 2px solid var(--band, var(--int));
  border-bottom: 2px solid var(--band, var(--int));
  transform: rotate(-45deg);
}
.problem > h3 {
  margin-top: var(--s-2);
  margin-bottom: 0;
  font-size: var(--t-1);
  color: var(--muted);
}
.problem .problem__answer {
  margin-top: var(--s-1);
  color: var(--text);
  font-size: 0.9375rem;
}

/* --- Services: the four "how we work" pillars in a row -------------------- */
.reasons--row {
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-4) var(--s-3);
  margin-bottom: var(--s-5);
}
.reasons--row h3 { font-size: var(--t-1); }
@media (max-width: 1080px) { .reasons--row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .reasons--row { grid-template-columns: minmax(0, 1fr); } }

/* Four short claims beside the solutions-page photograph. */
.claim-list { list-style: none; display: grid; gap: var(--s-2); margin-top: var(--s-4); }
.claim-list li {
  position: relative;
  padding-left: 22px;
  color: var(--muted);
  font-size: 0.9375rem;
}
.claim-list li::before {
  content: "";
  position: absolute;
  left: 0; top: .58em;
  width: 12px; height: 3px;
  background: var(--band, var(--int));
}
.claim-list strong { color: var(--text); }

/* The proof strip carries five audience entries (Jessica 2026-09-10: the two
   fact chips left, school districts got their own item). The eyebrow takes
   its own row, the five run as one row of five equal columns from 1081px so
   they line up, two or three rows narrower, and the note follows underneath
   at full measure. */
.proof__list { flex: 1 1 100%; }
.proof__note { flex: 1 1 100%; max-width: 88ch; margin-top: var(--s-1); }
@media (min-width: 1081px) {
  .proof__list { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: var(--s-2) var(--s-4); }
  /* Five columns of about 205px: the two longest labels take two lines at
     1rem (three at 1.25rem), so the size steps down and the marker sits on
     the first line rather than at the middle of the block. */
  .proof__list li { font-size: var(--t-0); line-height: 1.35; padding-left: 20px; }
  .proof__list li::before { top: .68em; transform: none; }
}
@media (min-width: 641px) and (max-width: 1080px) {
  .proof__list { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2) var(--s-4); }
}
.proof__list li { white-space: normal; }
/* Under the hero on the homepage the strip is the first thing after the
   beam; the top hairline would double the hero's bottom edge. */
.hero + .proof { border-top-color: transparent; }
/* Homepage: the hero hands straight over to the strip, so its bottom padding
   shrinks (72px at 1440 became about 32) to close the gap under the buttons
   (Jessica 2026-09-10). */
.hero--strip .hero__inner { padding-bottom: clamp(var(--s-3), 2.4vw, var(--s-4)); }

/* --- Homepage key features (Jessica 2026-09-10) ---------------------------
   Two lead cards for the facts about the whole system, then six feature
   cards in module hues. Same panel-card as everywhere else. */
.highlights {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-3);
}
.highlights--lead { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: var(--s-3); }
.highlights > .highlight { height: 100%; }
.highlight > h3 { font-size: var(--t-1); }
.highlight > p { font-size: 0.9375rem; }
.highlight--lead { --edge-core: var(--int); }
.highlight--lead::before { background: var(--spectrum); background-size: 100% 100%; height: 2px; }
.highlight--lead::after { content: none; }
.highlight--lead > h3 { font-size: var(--t-2); }
.highlight--lead > p { font-size: var(--t-0); color: var(--text); max-width: 56ch; }
.highlight__link {
  display: inline-block;
  margin-top: var(--s-2);
  font-size: 0.9375rem;
  color: var(--text);
}
@media (max-width: 900px) { .highlights { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .highlights, .highlights--lead { grid-template-columns: minmax(0, 1fr); } }

/* The `hidden` attribute has to win. A class that sets `display` outranks the
   user-agent's `[hidden] { display: none }`, which silently left the paused
   button and the inactive device panels on the page (caught 2026-09-10 with
   scripting off). Anything here that sets display and can also be hidden
   needs the pair. */
.device[hidden],
.devices__pause[hidden] { display: none; }

/* Five feature groups: two columns with the last card across the foot, its
   list in two columns, so the section closes on a full row instead of a card
   beside half an empty one (Risk Assessment and Inspections, 2026-09-10). */
@media (min-width: 901px) {
  .feature-groups--5 > .feature-group:last-child { grid-column: 1 / -1; }
}

/* --- Features, sticky variant (Jessica 2026-09-10, option 2, Incident only)
   One surface: the product photograph pins on the left while the feature
   groups run down the right. No cards; each group is a heading, its one-line
   intro and its checklist, separated by hairlines. */
.features--sticky { padding-top: 0; }
.features__sticky { position: relative; }
.features--sticky .features__band + .wrap,
.features--sticky .features__sticky + .wrap { margin-top: var(--s-6); }
.feature-rows { display: grid; gap: 0; }
.feature-row { padding-block: var(--s-4); border-top: 1px solid var(--line); }
.feature-row:first-child { border-top: 0; padding-top: var(--s-3); }
.feature-row h3 { font-size: var(--t-1); }
.feature-row .feature-group__intro { margin-top: var(--s-1); margin-bottom: var(--s-2); }
.feature-row .check-list { margin-top: 0; }
.features--sticky .features__copy .section__head { margin-bottom: var(--s-2); }

@media (min-width: 1081px) {
  .features__sticky {
    display: grid;
    grid-template-columns: 50% 50%;
    align-items: start;
  }
  /* The photograph column: pinned below the header, the picture at its own
     3:2 height, faded into the ground on all four sides so it floats. */
  /* Jessica 2026-09-10: let the copy sit over the photograph's faded edge,
     as the hero does. The pinned picture runs to 62vw (124% of its 50%
     column), so the copy column, which starts at 50vw, begins over the last
     fifth of the picture where the fade has already taken it most of the
     way to the ground; the gradient is the hero's, mirrored. */
  .features__pin {
    position: sticky;
    top: calc(var(--header-h) + var(--s-5));
    height: auto;
    min-height: 0;
    width: 124%;
    z-index: 0;
  }
  .features__list { position: relative; z-index: 1; }
  .features--sticky .features__media {
    position: relative;
    inset: auto;
    width: 100%;
    aspect-ratio: 3 / 2;
    padding: 0;
    border: 0;
    transform: none;
    background: none;
    box-shadow: none;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 10%, #000 90%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 10%, #000 90%, transparent);
  }
  .features--sticky .features__media::before,
  .features--sticky .features__media::after { content: none; }
  .features--sticky .features__media img {
    width: 100%; height: 100%;
    object-fit: cover;
    object-position: left center;
    filter: brightness(1.04) saturate(1.03);
  }
  .features--sticky .features__fade {
    display: block;
    position: absolute;
    z-index: 1;
    inset: 0;
    pointer-events: none;
    background:
      linear-gradient(90deg, rgba(var(--scrim-rgb), .42) 0%, rgba(var(--scrim-rgb), .06) 44%,
        rgba(var(--scrim-rgb), .72) 82%, var(--ground) 100%);
  }
  /* The text column keeps the page measure: it starts at the wrap's midpoint
     and ends at the wrap's right edge. */
  .features__list {
    padding-top: var(--s-6);
    padding-right: max(var(--s-3), calc((100vw - var(--wrap)) / 2 + var(--s-3)));
    padding-left: var(--s-6);
  }
  .features__pin { padding-top: var(--s-6); }
}
@media (max-width: 1080px) {
  .features--sticky { padding-top: var(--sec); }
  .features__sticky {
    max-width: var(--wrap);
    margin-inline: auto;
    padding-inline: var(--s-3);
  }
  .features--sticky .features__media { aspect-ratio: 16 / 9; }
  .features--sticky .features__media img { width: 100%; height: 100%; object-fit: cover; }
  .features--sticky .features__fade { display: none; }
  .features__list { margin-top: var(--s-5); }
  .features--sticky .features__sticky + .wrap { margin-top: var(--s-5); }
}
@media (max-width: 900px) { .features--sticky { padding-top: var(--sec-narrow); } }

/* Footer: the Canadian company chip under the tagline (Jessica 2026-09-10). */
.footer__origin { margin-top: var(--s-3); }
