/* ==========================================================================
   AI L3 TECH — design system
   Palette and type from the AI L3 Tech Brand Kit. See BRAND-CI.md, which
   records what the kit specifies, what the numbers allow, and why the four
   derived values below exist.
   ========================================================================== */

/* The faces are requested from the page head, not with @import. An @import
   here is only discovered once this file has been fetched and parsed, so the
   fonts queue behind it; a link in the head is found by the preload scanner
   straight away. */

/* ---------- 1. Tokens ---------------------------------------------------- */
:root {
  /* ---- the five issued brand colours, and nothing derived from them -----
     Earlier this file carried lighter siblings of the green and the cyan so
     that small text would clear 4.5:1 on a navy band. Those were not brand
     colours, and the lighter green in particular read as lime and outnumbered
     the real green on the page. They are gone. Where an issued colour cannot
     carry text, the text is white or near-black instead. */
  --navy:   #1F4480;   /* primary: headers, key UI, the navy + white layout */
  --green:  #2DB522;   /* secondary: bullets, highlights, AI content, CTAs */
  --cyan:   #00BCED;   /* accent: underlines, borders, interactive elements */
  --ink:    #1A1A1A;   /* text: body copy, in place of pure black */
  --paper:  #F5F7FA;   /* background: the page, in place of pure white */
  --white:  #FFFFFF;   /* cards and panels that lift off the page */

  /* The kit gives exactly one dark surface, so the second dark band and the
     raised panel are that same navy. Near-black is the kit's TEXT colour and
     using it as a full-bleed band was reading as a black stripe the palette
     never called for. The cost is less tonal variety; the palette has one
     dark and this is what that means. */
  --navy-deep:   var(--navy);
  --navy-raised: var(--navy);

  /* ---- text -----------------------------------------------------------
     Muted and faint are transparencies of white and of the near-black, so
     every value on the page still resolves to a brand colour over a brand
     surface. No new hues. */
  --text-on-dark:        var(--white);            /* 9.56:1 on navy  */
  --text-on-dark-muted:  rgba(255, 255, 255, .78);/* 6.53:1 on navy  */
  --text-on-dark-faint:  rgba(255, 255, 255, .70);/* 5.60:1 on navy  */
  --text-on-light:       var(--ink);              /* 16.2:1 on paper */
  --text-on-light-muted: rgba(26, 26, 26, .72);   /* 6.64:1 on paper */
  --text-on-light-faint: rgba(26, 26, 26, .65);   /* 5.26:1 on paper */

  /* ---- lines ----------------------------------------------------------- */
  --line-dark:  rgba(255, 255, 255, .16);
  --line-light: rgba(26, 26, 26, .12);
  --edge-control-dark:  rgba(255, 255, 255, .46);
  --edge-control-light: rgba(26, 26, 26, .50);

  /* ---- type ------------------------------------------------------------ */
  --font-display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-body:    'Open Sans', 'Helvetica Neue', Arial, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* Space scale (density 4/10, marketing). Kept complete even where a step is
     not currently called on: a scale with a hole in it stops being a scale,
     and the next person reaching for the smallest step should find it here
     rather than inventing a value. */
  --space-1: .25rem;
  --space-2: .5rem;
  --space-3: .75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  --wrap: 1280px;
  --gutter: 1.5rem;
  --nav-h: 80px;

  /* Label type. Small caps labels read at 11px on a desktop pointer, but on a
     phone that is below the 12px floor, so both step up at the breakpoint. */
  /* One size for every small caps label. There used to be a second at 10px,
     a single pixel apart, which no reader could tell was deliberate. */
  --fs-label:    .6875rem;   /* 11px, lifting to 12 on touch below */
  --fs-label-sm: var(--fs-label);

  --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ---------- 2. Reset ----------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
}

body {
  margin: 0;
  /* A single long token, an email address or a URL in the legal pages, must
     not be able to push the page wider than the phone it is read on. */
  overflow-wrap: break-word;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-on-light);
  background: var(--paper);   /* the kit's page background, in place of pure white */
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

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

button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

h1, h2, h3, h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.04;
}

p { margin: 0; }
/* The kit lists Open Sans at 400 and 600, so bold body copy is 600. Left alone
   the browser would ask for 700 and the browser would synthesise it. */
strong, b { font-weight: 600; }
ul { margin: 0; padding: 0; list-style: none; }

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

.skip-link {
  position: absolute;
  left: var(--gutter);
  top: -100px;
  z-index: 200;
  background: var(--green);
  color: var(--ink);
  padding: .75rem 1.25rem;
  font-weight: 600;
  font-size: .875rem;
}
.skip-link:focus { top: 1rem; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- 3. Layout ---------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--space-9); position: relative; }

.band-dark  { background: var(--navy);      color: var(--text-on-dark); }
.band-deep  { background: var(--navy-deep); color: var(--text-on-dark); }
.band-light { background: var(--paper);    color: var(--text-on-light); }
.band-white { background: var(--white);    color: var(--text-on-light); }

/* Figures are set in the mono face the kit names for data and metrics:
   durations, counts, prices, step numerals. It is not a body or heading face. */
.stat .v,
.stat--lime .v,
.delta .v,
.price-fig,
.flow-step .n,
.method .n,
.row .n,
.pain .n { font-family: var(--font-mono); font-feature-settings: "tnum" 1; }

/* Headings are navy on a light surface. The kit gives navy the headers and the
   key UI; before this every heading on a light band came through in the body
   text colour, so whole sections carried no brand colour at all. Body copy
   stays near-black. 8.91:1 on the page, 9.56:1 on a white card. */
.band-light h1, .band-light h2, .band-light h3,
.band-white h1, .band-white h2, .band-white h3 { color: var(--navy); }
/* except where the heading sits on a panel that carries its own navy */
.band-light .card--feature h3, .band-white .card--feature h3,
.band-light .price--featured h3, .band-white .price--featured h3,
.band-light .door-panel--msp h3, .band-white .door-panel--msp h3,
.band-light .card--feature h2, .band-white .card--feature h2 { color: var(--text-on-dark); }

/* ---------- 4. Type primitives ------------------------------------------ */
/* balance, so a display heading does not drop its last word onto a line of its
   own. "Get set up." was breaking after "set" and leaving "up." stranded.
   Browsers without it just wrap as before. */
.display-1,
.display-2 { text-wrap: balance; }
.display-1 { font-size: clamp(2.6rem, 6.2vw, 4.6rem); }
.display-2 { font-size: clamp(2.1rem, 4.6vw, 3.4rem); }
/* The third step. Used by the booking fallback heading, which only appears when
   the calendar is blocked, so it never showed up in a normal page review and
   was rendering at the browser's default h2 size. */
.display-3 { font-size: clamp(1.6rem, 3.2vw, 2.4rem); }

.lead {
  font-size: clamp(1rem, 1.25vw, 1.125rem);
  line-height: 1.7;
  color: var(--text-on-dark-muted);
  max-width: 58ch;
}
.band-light .lead,
.band-white .lead { color: var(--text-on-light-muted); }

/* Display-size highlights sit in the accent cyan on a navy band and in the
   navy itself on a light one. Green stays where the kit puts it: the bullets,
   the small marks and the calls to action. */
.accent { color: var(--cyan); }

.band-light .accent,
.band-white .accent { color: var(--navy); }
.muted  { color: var(--text-on-dark-muted); }

/* small caption label above a block */
.micro {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-on-dark-faint);
}
.band-light .micro,
.band-white .micro { color: var(--text-on-light-faint); }

/* Eyebrow: 11px, .18em tracking, lime marker */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .625rem;
  font-family: var(--font-body);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.band-light .eyebrow,
.band-white .eyebrow { color: var(--text-on-light-muted); }
.eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  background: var(--green);
  flex: none;
}

/* Numbered section tag: "03 / MEASURED IMPACT" */
.section-tag {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
  margin-bottom: var(--space-5);
}
.band-dark .section-tag,
.band-deep .section-tag { color: var(--text-on-dark-faint); }

/* ---------- 5. Buttons --------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-height: 52px;
  padding: .875rem 1.5rem;
  font-family: var(--font-body);
  font-size: .9375rem;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 0;
  cursor: pointer;
  transition: background-color .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .2s var(--ease);
}
/* Arrows are drawn, not typed. Inter has no U+2197 and Inter Tight has no
   U+2192, so as characters they fell out of the webfont into whatever the
   operating system happened to provide: Segoe UI Symbol on Windows, Apple
   Symbols on iOS, Noto on Android. Three platforms, three arrow shapes. */
.arw,
.delta .arrow { display: inline-flex; }
.arw svg,
.delta .arrow svg {
  display: block;
  /* fixed, not 1em: at 1em the same arrow came out 15px beside a 15px label
     and 16px inside a button */
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

.btn .arw { font-size: 1rem; line-height: 1; transition: transform .2s var(--ease); }
.btn:hover .arw { transform: translate(3px, -3px); }

/* White label on the green, with a green edge. Asked for directly, and worth
   recording what it costs: white on this green is 2.71:1 where body text needs
   4.5, and a green edge against the page is 2.53:1 where a control boundary
   needs 3. The button is still perfectly usable to most people; it is people
   with low vision or a poor screen in bright light who lose it. Darkening the
   green to #22891A would carry white text at 4.51:1 and need no border at all,
   but that is not the green the kit issues. */
.btn--lime {
  background: var(--green);
  color: var(--white);
  border-color: var(--green);
}
/* Green is 2.53:1 against the off-white page, so on a light band the fill is
   not enough to mark the control and it carries the darkened green as an edge.
   On navy the fill alone is 3.53:1 and needs none. */
.band-light .btn--lime,
.band-white .btn--lime { border-color: var(--green); }
.btn--lime:hover { background: #3ACC2E; }

.btn--outline { border-color: var(--edge-control-dark); color: var(--text-on-dark); }
.btn--outline:hover { border-color: var(--cyan); color: var(--cyan); }
.band-light .btn--outline,
.band-white .btn--outline { border-color: var(--edge-control-light); color: var(--text-on-light); }
.band-light .btn--outline:hover,
.band-white .btn--outline:hover { border-color: var(--navy); background: var(--navy); color: var(--white); }

.btn--dark { background: var(--navy); color: var(--white); }
.btn--dark:hover { box-shadow: inset 0 0 0 999px rgba(255, 255, 255, .14); }

/* A finger gets no hover state, so without this a tap looks like nothing
   happened until the next page paints. The press is the only feedback a touch
   visitor ever sees, and it reads on a mouse too. */
.btn:active { transform: translateY(1px); }
.btn:active .arw { transform: none; }
.btn--lime:active { background: #249314; }
.btn--outline:active { border-color: var(--cyan); color: var(--cyan); }
.band-light .btn--outline:active,
.band-white .btn--outline:active { border-color: var(--navy); background: var(--navy); color: var(--white); }
.btn--dark:active { box-shadow: inset 0 0 0 999px rgba(26, 26, 26, .14); }
.link-arrow:active { color: var(--cyan); }
.nav-links a:not(.btn):active { color: var(--white); }
.footer-cols a:active,
.footer-bottom a:active { color: var(--cyan); }
.legal a:active { color: var(--cyan); }
.vtab:active { color: var(--text-on-dark); }
.card:active { transform: translateY(-1px); }   /* settles out of the hover lift */
.pain:active { background: var(--paper); }   /* the card is white now */

/* The platform's grey flash fights the brand press state above. The press is
   still visible, so nothing is lost by turning the flash off. */
a, button, summary, [role="tab"] { -webkit-tap-highlight-color: transparent; }

.btn--sm { min-height: 44px; padding: .625rem 1.125rem; font-size: .875rem; gap: var(--space-4); }
.btn--block { width: 100%; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  font-size: .9375rem;
  font-weight: 600;
  min-height: 44px;
  transition: color .2s var(--ease);
}
.link-arrow:hover { color: var(--cyan); }
.card--feature .link-arrow:hover { color: #3ACC2E; }
.link-arrow .arw { transition: transform .2s var(--ease); }
.link-arrow:hover .arw { transform: translate(3px, -3px); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }

/* ---------- 6. Nav ------------------------------------------------------- */
.nav {
  position: sticky;
  top: 0;
  z-index: 100;
  /* Opaque, not 94%. Translucent, the bar composited against whatever was
     behind it, so the green button on it measured 3.70:1 over the old dark
     page and 3.01:1 over the off-white one, right on the line. The blur went
     with it: it does nothing behind an opaque fill. */
  background: var(--navy);
  border-bottom: 1px solid var(--line-dark);
}
.nav .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  min-height: var(--nav-h);
}
.nav-logo { display: inline-flex; align-items: center; min-height: 44px; }
.nav-logo img { height: 34px; width: auto; }
.nav-links { display: flex; align-items: center; gap: var(--space-6); }
.nav-links a:not(.btn) {
  display: inline-flex;
  align-items: center;
  min-height: 44px;          /* tablets get this nav and tap it with a finger */
  font-size: .875rem;
  font-weight: 600;   /* the kit lists 400 and 600 */
  color: var(--text-on-dark-muted);
  transition: color .2s var(--ease);
}
.nav-links a:not(.btn):hover { color: var(--white); }

.nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
}
.nav-toggle span { display: block; width: 20px; height: 1.5px; background: currentColor; position: relative; }
.nav-toggle span::before,
.nav-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 20px;
  height: 1.5px;
  background: currentColor;
  transition: transform .2s var(--ease), top .2s var(--ease);
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { top: 0; transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { top: 0; transform: rotate(-45deg); }

/* ---------- 7. Hero ------------------------------------------------------ */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(3.5rem, 8vw, 6.5rem) var(--space-9);
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(900px 520px at 78% 12%, rgba(45, 90, 142, .32), transparent 62%),
    radial-gradient(640px 420px at 12% 6%, rgba(30, 58, 95, .20), transparent 60%);
  pointer-events: none;
}
.hero > .wrap { position: relative; }
.hero-grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.hero h1 { margin-block: var(--space-5) var(--space-5); }
.hero .lead { margin-bottom: var(--space-7); }

.trust-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5) var(--space-7);
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-dark);
}
.trust-row li {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.trust-row .tick { color: var(--green); }

/* Live panel (right side of hero) */
.panel {
  background: var(--navy-raised);
  border: 1px solid var(--line-dark);
  padding: var(--space-5);
}
.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Two tracked labels will not both fit on a 320px phone. Wrapping puts the
     status on its own line instead of squeezing it into three. */
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--line-dark);
  margin-bottom: var(--space-5);
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.pulse { display: inline-flex; align-items: center; gap: .5rem; color: var(--white); }
.pulse::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green);
  animation: pulse 2.4s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .25; }
}

.panel-label { font-size: .875rem; color: var(--text-on-dark); margin-bottom: var(--space-4); }

.flow {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.flow-step { border: 1px solid var(--line-dark); padding: var(--space-4); }
.flow-step.is-active { border-color: var(--cyan); }
.flow-step .n { font-size: var(--fs-label); color: var(--text-on-dark-faint); }
.flow-step .t { font-size: .875rem; font-weight: 600; margin-top: .375rem; }
.flow-step.is-active .t { color: var(--white); }
.flow-step .d { font-size: .75rem; color: var(--text-on-dark-faint); margin-top: .25rem; line-height: 1.45; }

.delta {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto;
  align-items: center;
  gap: var(--space-4);
  border-left: 2px solid var(--cyan);
  background: rgba(255, 255, 255, .02);
  padding: var(--space-5);
}
.delta .k {
  font-size: var(--fs-label-sm);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-on-dark-faint);
}
.delta .v {
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.03em;
  margin-top: .25rem;
}
.delta .arrow { color: var(--text-on-dark-faint); font-size: 1.125rem; }
.delta .badge {
  background: rgba(0, 195, 245, .16);
  color: var(--white);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: .1em;
  padding: .5rem .75rem;
  white-space: nowrap;
}
.panel-note { font-size: .75rem; color: var(--text-on-dark-faint); margin-top: var(--space-4); }

/* ---------- 8. Tagline band ---------------------------------------------- */
.tagline-band { border-block: 1px solid var(--line-dark); background: var(--navy-deep); }
.tagline-band .wrap {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding-block: var(--space-5);
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--text-on-dark-faint);
}
.tagline-band b { color: var(--white); font-weight: 600; }

/* ---------- 9. Section headers ------------------------------------------ */
.sec-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
  margin-bottom: var(--space-8);
}

/* ---------- 10. Stat strip ----------------------------------------------- */
.stat-strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--line-light);
}
.band-dark .stat-strip,
.band-deep .stat-strip { border-top-color: var(--line-dark); }

.stat {
  padding: var(--space-7) var(--space-5);
  border-right: 1px solid var(--line-light);
  border-bottom: 1px solid var(--line-light);
}
.band-dark .stat,
.band-deep .stat { border-color: var(--line-dark); }
.stat:last-child { border-right: 0; }
.stat .v {
  font-weight: 600;
  font-size: clamp(2.2rem, 3.6vw, 3rem);
  letter-spacing: -.035em;
  line-height: 1;
}
.stat .k {
  font-size: .875rem;
  color: var(--text-on-light-muted);
  margin-top: var(--space-4);
  max-width: 24ch;
}
.band-dark .stat .k,
.band-deep .stat .k { color: var(--text-on-dark-muted); }

.stat--lime { background: var(--green); color: var(--white); border-right: 0; }
.stat--lime .v { font-size: clamp(1.5rem, 2.2vw, 1.9rem); }
.stat--lime .k,
.band-dark .stat--lime .k,
.band-deep .stat--lime .k { color: var(--ink); }   /* 6.42:1 on green; the translucent version was 4.33 */

/* ---------- 11. Cards ---------------------------------------------------- */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
}
/* Fixed 3-up, so a six-card set makes two full rows instead of a ragged one */
.card-grid--3 { grid-template-columns: repeat(3, 1fr); }
.card {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line-light);
  margin-left: -1px;
  margin-top: -1px;
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px -20px rgba(26, 26, 26, .22);
  z-index: 2;
}
.card .n {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  font-size: .75rem;
  color: var(--text-on-light-faint);
}
.card .card-kicker {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
}
.card p { color: var(--text-on-light-muted); font-size: .9375rem; line-height: 1.65; }
.card h3 { font-size: clamp(1.25rem, 1.8vw, 1.55rem); letter-spacing: -.025em; }
.card .card-foot {
  margin-top: auto;
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-light);
}

/* Feature card — the dark "01" card from the concept */
.card--feature {
  background: var(--navy);
  color: var(--text-on-dark);
  border-color: var(--navy);
  box-shadow: 0 24px 60px -30px rgba(26, 26, 26, .40);
  z-index: 3;
}
.card--feature .card-kicker { color: var(--white); }
.card--feature p { color: var(--text-on-dark-muted); }
.card--feature .n { color: var(--text-on-dark-faint); }
.card--feature .card-foot { border-top-color: var(--line-dark); }
.card--feature .link-arrow { color: var(--white); }

/* Dark pain cards — 1px gap draws the grid lines, so any column count works */
.pain-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--line-dark);
  border: 1px solid var(--line-dark);
}
.pain-grid--3 { grid-template-columns: repeat(3, 1fr); }
.pain {
  padding: var(--space-6);
  /* The kit names white for cards and panels. Near-black is its text colour,
     and using it as a card surface was the last place it acted as one. */
  background: var(--white);
  color: var(--text-on-light);
  display: flex;
  flex-direction: column;
  transition: background-color .25s var(--ease);
}

.pain .n { font-size: .75rem; color: var(--white); letter-spacing: .1em; }
.pain h3 { font-size: 1.125rem; margin-block: var(--space-7) var(--space-4); }
.pain p { font-size: .875rem; line-height: 1.65; color: var(--text-on-dark-muted); }

/* Plus list */
.plus-list { margin-top: var(--space-2); }
.plus-list li {
  display: flex;
  gap: var(--space-4);
  align-items: baseline;
  padding-block: var(--space-4);
  border-top: 1px solid var(--line-light);
  font-size: .9375rem;
}
.card--feature .plus-list li { border-top-color: var(--line-dark); }
/* Joins the existing per-band overrides. Without it the rule is drawn in the
   light token on a dark surface, which is invisible, and the items read as
   floating text with unexplained gaps. */
.band-dark .plus-list li,
.band-deep .plus-list li { border-top-color: var(--line-dark); }
.plus-list li::before { content: "+"; color: var(--green); font-weight: 600; flex: none; }
.card--feature .plus-list li::before { color: var(--green); }

/* ---------- 12. Numbered method list ------------------------------------ */
.method-grid { display: grid; grid-template-columns: .85fr 1.15fr; gap: clamp(2rem, 5vw, 5rem); }
.method-list { border-top: 1px solid var(--line-light); }
.band-dark .method-list,
.band-deep .method-list { border-top-color: var(--line-dark); }

.method {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: var(--space-5);
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--line-light);
}
.band-dark .method,
.band-deep .method { border-bottom-color: var(--line-dark); }
.method .n { font-size: .8125rem; color: var(--text-on-light-faint); padding-top: .4rem; }
.band-dark .method .n,
.band-deep .method .n { color: var(--text-on-dark-faint); }
.method .kicker {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--navy);
}
.band-dark .method .kicker,
.band-deep .method .kicker { color: var(--white); }
.method h3 { font-size: clamp(1.25rem, 2vw, 1.6rem); margin-block: var(--space-3); }
.method p { font-size: .9375rem; color: var(--text-on-light-muted); }
.band-dark .method p,
.band-deep .method p { color: var(--text-on-dark-muted); }

/* Note card with lime rule */
.note-card {
  background: var(--white);
  border-left: 3px solid var(--cyan);
  padding: var(--space-6);   /* matches the card family */
  margin-top: var(--space-7);
  box-shadow: 0 16px 40px -28px rgba(26, 26, 26, .28);
}
.note-card strong { display: block; font-size: .9375rem; margin-bottom: .375rem; color: var(--text-on-light); }
.note-card p { font-size: .8125rem; color: var(--text-on-light-muted); line-height: 1.6; }

/* ---------- 13. Pricing -------------------------------------------------- */
.price-grid { display: grid; grid-template-columns: repeat(3, 1fr); }
.price {
  position: relative;
  background: var(--white);
  border: 1px solid var(--line-light);
  margin-left: -1px;
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
}
.price--featured {
  background: var(--navy);
  color: var(--text-on-dark);
  border-color: var(--navy);
  box-shadow: 0 28px 60px -32px rgba(26, 26, 26, .34);
  z-index: 2;
}
.price-name {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
}
.price--featured .price-name { color: var(--white); }
.price-fig {
  font-weight: 600;
  font-size: clamp(2.2rem, 3.4vw, 2.9rem);
  letter-spacing: -.035em;
  margin-top: var(--space-4);
  line-height: 1;
}
.price-fig .per {
  font-family: var(--font-body);
  font-size: .9375rem;
  font-weight: 600;   /* the kit lists 400 and 600 */
  letter-spacing: 0;
  color: var(--text-on-light-faint);
}
.price--featured .price-fig .per { color: var(--text-on-dark-faint); }
.price-specs { margin-top: var(--space-6); }
.price-specs li {
  padding-block: var(--space-4);
  border-top: 1px solid var(--line-light);
  font-size: .9375rem;
  display: flex;
  gap: var(--space-4);
}
.price--featured .price-specs li { border-top-color: var(--line-dark); }
.price-specs li::before { content: "+"; color: var(--green); font-weight: 600; }
.price--featured .price-specs li::before { color: var(--green); }
.price-for {
  font-size: .8125rem;
  color: var(--text-on-light-muted);
  margin-block: var(--space-5) var(--space-6);
}
.price--featured .price-for { color: var(--text-on-dark-muted); }
.price .btn { margin-top: auto; }
.price-note {
  margin-top: var(--space-6);
  font-size: .875rem;
  color: var(--text-on-light-muted);
  max-width: 78ch;
}
.tag-flag {
  position: absolute;
  top: 0;
  right: 0;
  background: var(--green);
  color: var(--ink);
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .375rem .75rem;
}

/* ---------- 14. Compare rows --------------------------------------------- */
.rows { border-top: 1px solid var(--line-light); }
.band-dark .rows,
.band-deep .rows { border-top-color: var(--line-dark); }
.row {
  display: grid;
  grid-template-columns: 3rem 1fr 1.45fr;
  gap: var(--space-5);
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--line-light);
  align-items: start;
}
.band-dark .row,
.band-deep .row { border-bottom-color: var(--line-dark); }
.row .n { font-size: .75rem; color: var(--text-on-light-faint); padding-top: .2rem; }
.band-dark .row .n,
.band-deep .row .n { color: var(--text-on-dark-faint); }
.row .t { font-size: .9375rem; font-weight: 600; }
.row .d { font-size: .875rem; color: var(--text-on-light-muted); line-height: 1.65; }
.band-dark .row .d,
.band-deep .row .d { color: var(--text-on-dark-muted); }

/* ---------- 15. Tier table ----------------------------------------------- */
/* The tier table cannot usefully reflow below about 720px, so it scrolls.
   A scrollable region needs to be focusable, or a keyboard user cannot reach
   the columns at all. The right edge fades to signal there is more to see. */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line-light);
  background: var(--white);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}
.table-wrap:focus-visible { outline: 3px solid var(--navy); outline-offset: 3px; }
@media (max-width: 800px) {
  .table-wrap {
    background:
      linear-gradient(to right, var(--white) 30%, rgba(255, 255, 255, 0)) left / 3rem 100% no-repeat,
      linear-gradient(to left, var(--white) 30%, rgba(255, 255, 255, 0)) right / 3rem 100% no-repeat,
      radial-gradient(farthest-side at 0 50%, rgba(26, 26, 26, .14), transparent) left / 1rem 100% no-repeat,
      radial-gradient(farthest-side at 100% 50%, rgba(26, 26, 26, .14), transparent) right / 1rem 100% no-repeat,
      var(--white);
    background-attachment: local, local, scroll, scroll, local;
  }
}
table.tiers { width: 100%; border-collapse: collapse; min-width: 720px; font-size: .875rem; }
table.tiers th,
table.tiers td {
  text-align: left;
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--line-light);
  vertical-align: top;
}
table.tiers thead th {
  font-size: var(--fs-label);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
  font-weight: 600;
  background: var(--paper);
}
table.tiers tbody th {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  width: 4.5rem;
  color: var(--text-on-light);
}
table.tiers td { color: var(--text-on-light-muted); }
table.tiers tbody tr:last-child { background: rgba(45, 181, 34, .10); }
table.tiers tbody tr:last-child th,
table.tiers tbody tr:last-child td { border-bottom: 0; }

/* ---------- 16. FAQ ------------------------------------------------------ */
.faq { border-top: 1px solid var(--line-light); }
.faq details { border-bottom: 1px solid var(--line-light); }
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding-block: var(--space-5);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-weight: 700;
  letter-spacing: -.02em;
  min-height: 44px;
  transition: color .2s var(--ease);
}
/* The rows are the only control in this section and had no hover at all. */
.faq summary:hover { color: var(--navy); }
.band-dark .faq summary:hover,
.band-deep .faq summary:hover { color: var(--cyan); }

.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+";
  color: var(--cyan);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1;
  flex: none;
  transition: transform .2s var(--ease);
}
.faq details[open] summary::after { transform: rotate(45deg); }
.faq .answer {
  padding-bottom: var(--space-6);
  font-size: .9375rem;
  line-height: 1.7;
  color: var(--text-on-light-muted);
  max-width: 78ch;
}

/* a bordered aside for a standing note under a section */
.cohort-note {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--line-dark);
  border-left: 3px solid var(--cyan);
  font-size: .875rem;
  color: var(--text-on-dark-muted);
}

/* ---------- 18. Final CTA ------------------------------------------------ */
.cta-final { position: relative; overflow: hidden; text-align: center; padding-block: var(--space-10); }
.cta-final::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--line-dark) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-dark) 1px, transparent 1px);
  background-size: 76px 76px;
  mask-image: radial-gradient(ellipse 60% 62% at 50% 50%, #000, transparent 72%);
  -webkit-mask-image: radial-gradient(ellipse 60% 62% at 50% 50%, #000, transparent 72%);
  pointer-events: none;
}
.cta-final > .wrap { position: relative; }
.cta-final h2 { margin-block: var(--space-5); }
.cta-final .lead { margin-inline: auto; margin-bottom: var(--space-7); }
.cta-final .btn { margin-inline: auto; }
.cta-note {
  margin-top: var(--space-6);
  font-size: var(--fs-label);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-on-dark-faint);
}

/* ---------- 19. Footer --------------------------------------------------- */
.footer { background: var(--navy-deep); border-top: 1px solid var(--line-dark); padding-block: var(--space-8) var(--space-6); }
.footer-top {
  display: grid;
  grid-template-columns: 1.4fr 2fr;
  gap: clamp(2rem, 5vw, 4rem);
  padding-bottom: var(--space-7);
  border-bottom: 1px solid var(--line-dark);
}
.footer-logo { display: inline-flex; align-items: center; min-height: 48px; }
.footer-logo img { height: 42px; width: auto; }
.footer-tag { font-size: .8125rem; color: var(--text-on-dark-faint); margin-top: var(--space-5); max-width: 36ch; line-height: 1.6; }
.footer-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-6); }
.footer-cols h2 {
  font-family: var(--font-display);   /* a heading, so Archivo, small though it is */
  font-size: var(--fs-label);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-dark-faint);
  margin-bottom: var(--space-5);
}
.footer-cols a {
  font-size: .875rem;
  color: var(--text-on-dark-muted);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  transition: color .2s var(--ease);
}
.footer-cols a:hover { color: var(--cyan); }
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  align-items: center;
  padding-top: var(--space-6);
  font-size: .75rem;
  color: var(--text-on-dark-faint);
}
.footer-bottom a:hover { color: var(--cyan); }

/* ---------- 20. Legal pages ---------------------------------------------- */
.legal-hero { padding-block: clamp(3rem, 7vw, 5rem) var(--space-8); border-bottom: 1px solid var(--line-dark); }
.legal-hero h1 { margin-block: var(--space-5) var(--space-4); }
.legal-hero .sub { font-size: .9375rem; color: var(--text-on-dark-muted); }

.legal { background: var(--paper); color: var(--text-on-light); padding-block: var(--space-8) var(--space-9); }

/* Long legal documents get a jump-link index beside the text */
.legal-wrap {
  max-width: 1140px;
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.legal-body { max-width: 78ch; }
/* The cap has to sit on the element whose font-size it is measured in, or a
   15px paragraph inside a 16px container gets a wider line than intended. */
.legal-body p,
.legal-body li { max-width: 66ch; }
.method p,
.case-situation { max-width: 66ch; }

.legal-toc {
  position: sticky;
  top: calc(var(--nav-h) + 1.5rem);
  /* dvh, not vh: a large tablet in landscape has a collapsing browser bar, and
     vh measures the tallest state, which would run the list off the screen. */
  max-height: calc(100dvh - var(--nav-h) - 4rem);
  overflow-y: auto;
  border-left: 2px solid var(--line-light);
  padding-left: var(--space-5);
}
.legal-toc-title {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
  margin-bottom: var(--space-4);
}
.legal .legal-toc ol { list-style: none; padding: 0; margin: 0; }
.legal .legal-toc li { margin-top: 0; padding-left: 0; }
.legal .legal-toc a {
  display: block;
  padding-block: .4375rem;
  font-size: .8125rem;
  line-height: 1.4;
  color: var(--text-on-light-muted);
  text-decoration: none;
  transition: color .2s var(--ease);
}
.legal .legal-toc a:hover { color: var(--text-on-light); text-decoration-color: var(--cyan); }
.legal-toc a:focus-visible { outline-offset: 1px; }
.legal p,
.legal li { font-size: .9375rem; line-height: 1.75; color: var(--text-on-light-muted); }
.legal p + p,
.legal ul,
.legal ol { margin-top: var(--space-4); }
.legal h2 {
  font-size: clamp(1.25rem, 2.2vw, 1.6rem);
  color: var(--text-on-light);
  margin-top: var(--space-8);
  margin-bottom: var(--space-4);
  padding-top: var(--space-5);
  border-top: 1px solid var(--line-light);
}
.legal h2:first-of-type { margin-top: var(--space-5); }
.legal h3 { font-size: 1.0625rem; color: var(--text-on-light); margin-top: var(--space-6); margin-bottom: var(--space-3); }
.legal strong { color: var(--text-on-light); font-weight: 600; }
.legal ul { list-style: none; padding-left: 0; }
.legal ul li { position: relative; padding-left: 1.5rem; margin-top: var(--space-3); }
.legal ul li::before { content: "+"; position: absolute; left: 0; color: var(--cyan); font-weight: 700; }
.legal ol { list-style: decimal; padding-left: 1.35rem; }
.legal ol li { margin-top: var(--space-3); padding-left: .25rem; }
.legal ol li::marker { color: var(--text-on-light-faint); font-size: .875rem; }
.legal a {
  color: var(--text-on-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--cyan);
}
.legal a:hover { color: var(--cyan); }
.legal hr { border: 0; border-top: 1px solid var(--line-light); margin-block: var(--space-7); }

/* Classes inherited from the published legal documents. Without these the
   contract reads flat: 43 sub-clauses render identically to body text. */
.legal .legal-intro {
  font-size: 1.0625rem;
  color: var(--text-on-light);
  font-weight: 600;
}
.legal .clause {
  margin-left: 1.5rem;
  margin-top: var(--space-4);
}
.legal .clause-2 {
  margin-left: 3rem;
  margin-top: var(--space-4);
}
.legal .notice-block {
  margin-top: var(--space-5);
  padding: var(--space-5);
  background: var(--white);
  border-left: 3px solid var(--line-light);
  font-size: .9375rem;
  line-height: 1.7;
  color: var(--text-on-light-muted);
}

/* A long URL in legal copy is a single unbreakable token. As a grid item with
   the default min-width: auto it becomes the column's floor, so the track grows
   past the gutter rather than the word wrapping - which is what pushed the
   privacy policy 2px wide once text spacing was increased. anywhere, not
   break-word: only anywhere lowers the min-content size the track is sized on. */
.legal-body,
.legal-toc {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ---------- 21. Vertical switcher (Claude Launch Program) ---------------- */
.vtabs {
  display: flex;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line-dark);
  margin-bottom: var(--space-8);
}
.band-light .vtabs,
.band-white .vtabs { border-bottom-color: var(--line-light); }

.vtab {
  padding: .875rem 1.25rem;
  min-height: 48px;
  font-family: var(--font-body);
  font-size: .875rem;
  font-weight: 600;
  color: var(--text-on-dark-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .2s var(--ease), border-color .2s var(--ease);
}
.vtab:first-child { padding-left: 0; }
.vtab:hover { color: var(--text-on-dark); }
.vtab[aria-selected="true"] { color: var(--white); border-bottom-color: var(--white); }

.vpanel {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.vpanel[hidden] { display: none; }
.vpanel + .vpanel { margin-top: var(--space-8); }

.hook {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.06;
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  margin-block: var(--space-4) var(--space-4);
}
.hook-accent { color: var(--cyan); }
.hook-sub {
  font-size: .9375rem;
  color: var(--text-on-dark-muted);
  padding-bottom: var(--space-5);
  border-bottom: 2px solid var(--cyan);
  display: inline-block;
}

.compliance-note {
  margin-top: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--line-dark);
  border-left: 3px solid var(--cyan);
  font-size: .875rem;
  color: var(--text-on-dark-muted);
}

/* Claude prompt mock, lifted from the one-pagers */
.claude-panel {
  background: var(--navy-raised);
  border: 1px solid var(--line-dark);
  padding: var(--space-5);
}
.claude-head {
  display: flex;
  align-items: center;
  gap: .625rem;
  font-size: .9375rem;
  font-weight: 600;
  margin-bottom: var(--space-5);
}
.claude-head svg { width: 16px; height: 16px; flex: none; }

.prompt-list li {
  display: flex;
  align-items: center;
  gap: .75rem;
  padding: .8125rem 1rem;
  border: 1px solid var(--line-dark);
  background: rgba(255, 255, 255, .02);
  font-size: .875rem;
  color: var(--text-on-dark);
}
.prompt-list li + li { margin-top: .5rem; }
.prompt-list li::before {
  content: "";
  width: 16px;
  height: 16px;
  flex: none;
  background: rgba(78, 134, 199, .35);
  border: 1px solid var(--cyan);
}

/* ---------- 22. Motion --------------------------------------------------- */
/* Entrance motion only. Nothing is hidden by default, so if the script never
   runs the content is still there. Hiding first and revealing with JS means a
   blocked or failed script takes the section with it. */
@keyframes reveal-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
.reveal.is-in { animation: reveal-in .6s var(--ease) both; }
.reveal-stagger.is-in > * { animation: reveal-in .5s var(--ease) both; }
.reveal-stagger.is-in > *:nth-child(2) { animation-delay: .07s; }
.reveal-stagger.is-in > *:nth-child(3) { animation-delay: .14s; }
.reveal-stagger.is-in > *:nth-child(4) { animation-delay: .21s; }

/* ---------- 26. Two-door homepage -------------------------------------- */
/* The choice is offered once, as a full-bleed split: the page divides in two
   so the two paths are the layout, not two cards sitting on a band. Each half
   carries its own surface and accent so a visitor self-selects at a glance. */
.hero-solo { max-width: 62ch; }
.hero-solo h1 { margin-block: var(--space-5); }
.hero-solo .lead { margin-bottom: var(--space-6); }

.section--doors { padding-block: var(--space-9) 0; }

.doors-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  margin-top: var(--space-8);
}

.door-panel {
  /* The kit puts CTAs in green, so both doors lead with the same green button.
     The two paths are told apart by the panel itself, navy against white,
     which is the kit's own navy + white layout. */
  --door-accent: var(--green);
  --door-accent-hover: #3ACC2E;
  --door-accent-press: #249314;
  position: relative;
  --door-gap: clamp(1.5rem, 3vw, 3.5rem);   /* breathing room at the seam */
  padding-block: clamp(2.25rem, 4.5vw, 4rem) clamp(2.5rem, 5vw, 4.5rem);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  border-top: 3px solid transparent;
  transition: background-color .3s var(--ease), border-color .3s var(--ease);
}
.door-panel--msp { background: var(--navy); border-top-color: var(--green); }
/* The navy door sits inside a light section, so it has to declare its own
   text colours rather than inherit the section's. Without these the copy
   comes through in near-black on navy. */
.door-panel--msp { color: var(--text-on-dark); }
.door-panel--msp h3 { color: var(--text-on-dark); }
.door-panel--msp .door-eyebrow { color: var(--text-on-dark-muted); }
.door-panel--msp .door-promise { color: var(--white); }
.door-panel--msp .lead { color: var(--text-on-dark-muted); }
.door-panel--msp .door-tags li {
  border-color: var(--line-dark);
  color: var(--text-on-dark-muted);
}

/* The second door inverts to white. Near-black was the kit's text colour, not
   a surface, and two navies side by side read as a rendering fault rather than
   two routes. */
.door-panel--biz {
  background: var(--white);
  color: var(--text-on-light);
  border-top-color: var(--cyan);
}
.door-panel--biz .door-eyebrow { color: var(--text-on-light-muted); }
.door-panel--biz .door-eyebrow::before { background: var(--cyan); }
.door-panel--biz h3 { color: var(--navy); }
.door-panel--biz .lead { color: var(--text-on-light-muted); }
.door-panel--biz .door-promise { color: var(--navy); }   /* the white door */
.door-panel--biz .door-tags li {
  border-color: var(--line-light);
  color: var(--text-on-light-muted);
}
/* The split is full-bleed, but each half aligns its outer edge to the page
   gutter and holds --door-gap back from the seam. Percentage padding resolves
   against the panel's own width, so this never depends on 100vw, which would
   include the scrollbar. */
.door-panel--msp {
  padding-left: max(var(--gutter), calc(100% - var(--wrap) / 2 + var(--gutter)));
  padding-right: var(--door-gap);
}
.door-panel--biz {
  padding-left: var(--door-gap);
  padding-right: max(var(--gutter), calc(100% - var(--wrap) / 2 + var(--gutter)));
}
.door-inner {
  width: 100%;
  /* fill the panel so the button's margin-top:auto has space to push against
     and both buttons land on the same baseline whatever the copy length */
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: flex-start;
}
/* a deliberate seam between the two halves */
.door-panel--biz { box-shadow: inset 1px 0 0 var(--line-light); }
.door-panel--msp:hover,
.door-panel--msp:focus-within { background: var(--navy-raised); border-top-color: var(--door-accent); }
.door-panel--biz:hover,
.door-panel--biz:focus-within { background: var(--paper); border-top-color: var(--door-accent); }

.door-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .625rem;
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--text-on-dark-muted);
}
.door-eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  background: var(--door-accent);
  flex: none;
}

.door-panel h3 {
  font-size: clamp(1.9rem, 3.2vw, 2.9rem);
  letter-spacing: -.03em;
  margin-top: var(--space-2);
}
.door-promise {
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  font-weight: 600;
  line-height: 1.45;
  color: var(--white);   /* on the navy door; green is 3.53:1 here, under the 4.5 this size needs */
}
.door-panel .lead { font-size: .9375rem; max-width: 44ch; }

/* compact capability chips instead of stacked bordered rows */
.door-tags { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: var(--space-2); }
.door-tags li {
  font-size: .8125rem;
  padding: .375rem .75rem;
  border: 1px solid var(--line-dark);
  color: var(--text-on-dark-muted);
}

.door-inner .btn { margin-top: auto; }
.door-inner .btn::after { content: ""; position: absolute; inset: 0; }
.btn--door {
  background: var(--door-accent);
  color: var(--ink);
  /* The two doors are a symmetric pair, so their buttons match rather than
     each sizing to its own label. Capped at the space available: a flat 19rem
     is wider than a 320px phone can hold once the panel padding is taken off,
     and it pushed the whole page out to 352px. */
  min-width: min(19rem, 100%);
  justify-content: space-between;
}
/* Green against the white door is 2.71:1, under the 3 a control needs, so on
   that panel the button carries the darkened green as an edge. On navy the
   fill alone is 3.53:1 and no edge is needed. */
.door-panel--biz .btn--door { border-color: var(--green); }
/* This button carries the stretched overlay above, which is anchored to the
   panel. filter and transform both create a containing block, and the overlay
   would re-anchor to the button, shrink from 720px to 297px, drop the cursor,
   release the hover, expand again and start over: a 60-per-second flicker.
   So the door button gives its feedback with colour alone. */
.btn--door:hover { background: var(--door-accent-hover); }
.btn--door:active { background: var(--door-accent-press); transform: none; }

/* ---------- 27. Case study / example build cards ------------------------ */
/* One card format for both, per the spec's five-part scope rule. Real work
   closes on "Result"; invented scenarios are badged "Example build" and close
   on "Designed to", never on a fabricated number. */
.case-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
  margin-top: var(--space-7);
}

.case-card {
  background: var(--white);
  border: 1px solid var(--line-light);
  padding: clamp(1.5rem, 2.4vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.band-dark .case-card,
.band-deep .case-card {
  background: var(--navy-raised);
  border-color: var(--line-dark);
}

/* short, nowrap pill: a compact label must not wrap to a second line */
.case-badge {
  align-self: flex-start;
  display: inline-block;
  white-space: nowrap;
  font-size: var(--fs-label-sm);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: .375rem .75rem;
  border: 1px solid var(--navy);
  color: var(--text-on-light);
}
.band-dark .case-badge,
.band-deep .case-badge { color: var(--cyan); border-color: rgba(0, 195, 245, .55); }

.case-card h3 { font-size: clamp(1.15rem, 1.7vw, 1.4rem); letter-spacing: -.02em; }
.case-situation { font-size: .9375rem; line-height: 1.65; color: var(--text-on-light-muted); }
.band-dark .case-situation,
.band-deep .case-situation { color: var(--text-on-dark-muted); }

/* ---------- 27b. Work showcase - screen carousel ------------------------ */
/* An example-build card whose head is a gallery of real screens. The track is
   the only thing that moves, and it holds nothing but images: a transform makes
   a containing block, so anything positioned that sat inside it would re-anchor
   to the moving element and flicker. The dots and the caption stay outside it. */
.work-card {
  padding: 0;
  gap: 0;
  overflow: hidden;
}
.work-shots {
  background: var(--paper);
  border-bottom: 1px solid var(--line-light);
}
.work-viewport {
  overflow: hidden;
  /* Reserved here, so the row never collapses while the images decode. */
  aspect-ratio: 16 / 10;
  /* Vertical panning stays with the browser so the page still scrolls under a
     finger. Horizontal is ours: without this the browser claims the gesture,
     fires pointercancel, and the swipe handler never sees a pointerup. */
  touch-action: pan-y;
}
.work-track {
  display: flex;
  height: 100%;
  transition: transform .62s var(--ease);
}
.work-slide {
  flex: 0 0 100%;
  min-width: 0;
  margin: 0;
}
/* <picture> is an inline box by default, so the image's height: 100% would be
   resolving against an auto-height parent. It happens to land right because the
   files are already 16:10, but it would break the day one is not. */
.work-slide picture {
  display: block;
  height: 100%;
}
.work-slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}

/* the bar under the gallery: pause, what you are looking at, and the dots */
.work-bar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: .5rem .75rem .5rem .5rem;
  border-top: 1px solid var(--line-light);
  background: var(--white);
}
.work-pause {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  background: none;
  border: 1px solid transparent;
  border-radius: 2px;
  color: var(--text-on-light-muted);
  cursor: pointer;
}
.work-pause:hover { color: var(--text-on-light); border-color: var(--line-light); }
.work-pause svg { width: 13px; height: 13px; fill: currentColor; }
.work-pause .ico-play { display: none; }
.work-pause[aria-pressed="true"] .ico-play { display: block; }
.work-pause[aria-pressed="true"] .ico-pause { display: none; }

.work-caption {
  margin: 0;
  min-width: 0;
  font-size: .75rem;
  letter-spacing: .02em;
  color: var(--text-on-light-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.work-dots {
  margin-left: auto;
  display: flex;
  /* 8px clear between adjacent targets, which is the crowding floor the mobile
     audit enforces: two 28px dots 2px apart are each hittable and still wrong. */
  gap: .5rem;
  flex: none;
}
/* 28px of hit area around a small mark, so the target clears 24x24 */
.work-dot {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.work-dot::before {
  content: "";
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 99px;
  background: var(--edge-control-light);
  transition: width .3s var(--ease), background-color .3s var(--ease);
}
/* current reads by shape as well as colour, not colour alone */
.work-dot[aria-current="true"]::before {
  width: 20px;
  background: var(--navy);
}
.work-dot:hover::before { background: var(--text-on-light); }

.work-text {
  padding: clamp(1.5rem, 2.4vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.work-meta {
  margin: 0;
  border-top: 1px solid var(--line-light);
}
.work-meta > div {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: var(--space-4);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--line-light);
}
.work-meta dt {
  font-size: var(--fs-label);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-on-light-faint);
  padding-top: .1rem;
}
.work-meta dd {
  margin: 0;
  font-size: .875rem;
  line-height: 1.6;
  color: var(--text-on-light-muted);
}

/* A finger needs the full 44px. A mouse does not, and at 28px the dot row stays
   a page indicator rather than a toolbar, so the size is spent only where it
   buys something. The bar's padding tightens to keep all of it inside 320px. */
@media (hover: none), (max-width: 560px) {
  .work-bar { padding: .25rem .375rem; gap: var(--space-2); }
  .work-dot,
  .work-pause { width: 44px; height: 44px; }
}

@media (prefers-reduced-motion: reduce) {
  .work-track { transition: none; }
  .work-dot::before { transition: none; }
}

/* ---------- 28. Booking embed ------------------------------------------ */
/* The calendar is a third-party iframe. form_embed.js sets its height once the
   widget reports its size, so the min-height is only there to stop the page
   collapsing and shifting while that happens. */
.booking-frame {
  background: transparent;
  /* The space is reserved HERE, not on the iframe. The embed script lifts the
     iframe out of flow while it starts up, position absolute and off to the
     left, so anything reserved on the iframe stops holding the column open and
     the page collapses by the full height and springs back a few seconds
     later. Measured at 0.21 to 0.59 layout shift before this. */
  min-height: 800px;
}
@media (max-width: 1079px) { .booking-frame { min-height: 960px; } }
@media (max-width: 560px)  { .booking-frame { min-height: 830px; } }
.booking-frame iframe {
  display: block;
  width: 100%;
  min-height: 800px;   /* it settles at 787 above 1080 */
  border: 0;
  overflow: hidden;
}
/* The embed reports its own height once it loads, and the page jumps by
   whatever the reserved space got wrong. These are measured, not guessed: the
   embed stacks its two columns below about 1080 and grows a lot. Reserving
   720 everywhere was costing 232px of shift at 1024 and 67px at 1440.
   Widest first, so the narrower rule wins where it applies. */
@media (max-width: 1079px) {
  .booking-frame iframe { min-height: 960px; }   /* settles at 952 */
}
@media (max-width: 560px) {
  .booking-frame iframe { min-height: 830px; }   /* settles at 820 */
}

/* shown only when the calendar embed is blocked */
.booking-fallback {
  border: 1px solid var(--line-light);
  border-left: 3px solid var(--navy);
  background: var(--white);
  padding: clamp(1.5rem, 3vw, 2.5rem);
}
.booking-fallback h2 { margin-bottom: var(--space-4); }
.booking-fallback .lead { margin-bottom: var(--space-6); }
.booking-fallback[hidden] { display: none; }
.booking-frame[hidden] { display: none; }

/* ---------- 28b. Event capture page (/chat-to-us) ---------------------- */
/* A page people reach by scanning a code at a stand. One job: the form. The
   navigation is cut to the logo and a single action so nothing competes. */
.nav--lean .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.lean-head { max-width: 46rem; }
.lean-head .lead { margin-top: var(--space-5); }

.lean-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-5);
  margin-top: var(--space-7);
}
.lean-grid--three { grid-template-columns: repeat(3, 1fr); }

.lean-card {
  background: var(--white);
  border: 1px solid var(--line-light);
  padding: clamp(1.5rem, 2.4vw, 2rem);
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.lean-card h3 { font-size: clamp(1.15rem, 1.7vw, 1.4rem); letter-spacing: -.02em; }
.lean-card p {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.65;
  color: var(--text-on-light-muted);
}

.lean-vision { max-width: 54rem; }
.lean-vision h2 { margin-top: var(--space-4); }
.lean-vision .lead { margin-top: var(--space-5); color: var(--text-on-light-muted); }

/* ---------- 29. Spacing utilities -------------------------------------- */
/* These exist so no element needs a style attribute, which lets the
   Content-Security-Policy drop 'unsafe-inline' from style-src. */
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }
.mt-7 { margin-top: var(--space-7); }
.btn-row--center { justify-content: center; }
.btn-row--center .btn { margin-inline: 0; }
.btn-row-note { flex: 1 1 320px; margin: 0; }

/* ---------- 24. Responsive ----------------------------------------------- */
/* Small caps labels sit at 11px against a desktop pointer. On a tablet held at
   arm's length that is under the 12px floor, and a 1024px tablet is a touch
   device too, so the floor keys off the input as well as the width. */
@media (max-width: 1080px), (hover: none) {
  :root {
    --fs-label: .75rem;   /* the 12px floor on touch */
  }
}

@media (max-width: 1080px) {
  .doors-split { grid-template-columns: 1fr; }
  .door-panel { padding-inline: var(--gutter); }
  .door-panel--biz { box-shadow: none; border-top-color: var(--line-dark); }
  .door-inner { width: 100%; }
  .case-grid { grid-template-columns: 1fr; }
  .lean-grid,
  .lean-grid--three { grid-template-columns: 1fr; }

  .legal-wrap { grid-template-columns: 1fr; gap: var(--space-6); }
  .legal-toc {
    position: static;
    max-height: 13rem;
    border-left: 0;
    border: 1px solid var(--line-light);
    padding: var(--space-5);
    background: var(--white);
  }
  .legal .legal-toc a { min-height: 44px; display: flex; align-items: center; }
  .vpanel,
  .hero-grid,
  .method-grid,
  .sec-head,
  .footer-top { grid-template-columns: 1fr; }
  .sec-head { gap: var(--space-5); align-items: start; }
  .pain-grid,
  .pain-grid--3 { grid-template-columns: repeat(2, 1fr); }
  .card-grid--3 { grid-template-columns: repeat(2, 1fr); }
  .stat-strip { grid-template-columns: repeat(2, 1fr); }
  .stat:nth-child(2) { border-right: 0; }
  .price-grid { grid-template-columns: 1fr; }
  .price { margin-left: 0; margin-top: -1px; }
  .row { grid-template-columns: 2.5rem 1fr; }
  .row .d { grid-column: 2; }
}

@media (max-width: 860px) {
  :root { --nav-h: 68px; }
  .nav-toggle { display: inline-flex; }
  .nav-links {
    position: fixed;
    inset: var(--nav-h) 0 auto 0;
    /* A phone held sideways leaves roughly 320px below the bar. Without a cap
       the last link and the call button fall off the bottom unreachably. */
    max-height: calc(100dvh - var(--nav-h));
    overflow-y: auto;
    overscroll-behavior: contain;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--navy);
    border-bottom: 1px solid var(--line-dark);
    padding: var(--space-4) var(--gutter) var(--space-6);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
  }
  .nav-links.is-open { transform: none; opacity: 1; visibility: visible; }
  /* position: fixed, not overflow alone. overflow: hidden clamps the document
     scroll position, so opening the menu threw the reader up the page and
     closing it left them there. The JS holds their place in body's top. */
  body.nav-open {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
  }
  .nav-links a:not(.btn) {
    padding-block: var(--space-4);
    border-bottom: 1px solid var(--line-dark);
    font-size: 1rem;
  }
  .nav-links .btn { margin-top: var(--space-5); justify-content: center; }
  .flow { grid-template-columns: 1fr; }
  .delta { grid-template-columns: 1fr auto 1fr; row-gap: var(--space-5); }
  .delta .badge { grid-column: 1 / -1; justify-self: start; }
  .footer-cols { grid-template-columns: 1fr 1fr; }
  .section { padding-block: var(--space-8); }
}

@media (max-width: 560px) {
  /* Side by side, the before and after pair needs 276px inside a 222px panel,
     which widened the whole hero grid. Below 560 the comparison reads top to
     bottom instead and the arrow turns to follow it. */
  .delta {
    grid-template-columns: 1fr;
    row-gap: var(--space-3);
    justify-items: start;
  }
  .delta .arrow { transform: rotate(90deg); }
  .delta .badge { white-space: normal; }

  .pain-grid,
  .pain-grid--3,
  .stat-strip { grid-template-columns: 1fr; }
  .card-grid--3 { grid-template-columns: 1fr; }
  .stat { border-right: 0; border-bottom: 1px solid var(--line-dark); }
  .stat:last-child { border-bottom: 0; }
  .btn { width: 100%; }
  .btn-row { flex-direction: column; align-items: stretch; }
  .footer-cols { grid-template-columns: 1fr; }
  .trust-row { gap: var(--space-4); flex-direction: column; }
  .work-meta > div  { grid-template-columns: 1fr; gap: var(--space-2); }
  /* the caption is the first thing to go when the bar runs out of room */
  .work-caption { display: none; }
  .footer-bottom { flex-direction: column; align-items: flex-start; }
  .vtabs { flex-direction: column; align-items: stretch; }
  .vtab {
    padding: .875rem 0;
    text-align: left;
    border-bottom: 1px solid var(--line-dark);
    margin-bottom: 0;
  }
  .vtab[aria-selected="true"] { border-bottom-color: var(--white); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal.is-in,
  .reveal-stagger.is-in > * { animation: none !important; }
}

@media print {
  .nav,
  .cta-final,
  .footer-cols,
  .legal-toc,
  .skip-link,
  .btn { display: none; }
  body { background: #fff; color: #000; }
  .legal { background: #fff; padding-block: 0; }
  .legal-wrap { display: block; max-width: none; }
  /* printed contracts need ink-black body text, not the on-screen grey */
  .legal p,
  .legal li,
  .legal h2,
  .legal h3,
  .legal strong { color: #000; }
  .legal a { color: #000; text-decoration: underline; }
  .legal h2 { break-after: avoid; page-break-after: avoid; }
  .legal p, .legal li { orphans: 3; widows: 3; }
}

/* ---------- 25. Forced colors (Windows High Contrast) ------------------- */
/* These markers are drawn with background only, so the forced palette wipes
   them out. Give them a border in the system colour instead. */
@media (forced-colors: active) {
  .eyebrow::before,
  .pulse::before,
  .prompt-list li::before {
    forced-color-adjust: none;
    border: 1px solid CanvasText;
    background: Highlight;
  }
  .stat--lime,
  .tag-flag { border: 1px solid CanvasText; }
  .flow-step.is-active { border-color: Highlight; }
}

/* The gap section carries two paragraphs of plain explanation under the head,
   so it gets a readable measure rather than the full column width. */
.gap-body { max-width: 62ch; margin-top: var(--space-6); }
.gap-body p + p { margin-top: var(--space-4); }
.gap-body .btn-row { margin-top: var(--space-6); }

/* A section-closing call to action. The feedback was that nobody should be
   able to scroll past a section without a way to book, so every section that
   did not already carry one gets this. */
.section-cta {
  margin-top: var(--space-7);
  padding-top: var(--space-6);
  border-top: 1px solid var(--line-light);
}
.band-dark .section-cta,
.band-deep .section-cta { border-top-color: var(--line-dark); }

/* The vertical switcher was built for a navy band. On the light page its
   colours have to flip, or the tabs are white on off-white. */
.band-light .vtab,
.band-white .vtab { color: var(--text-on-light-muted); }
.band-light .vtab:hover,
.band-white .vtab:hover,
.band-light .vtab:active,
.band-white .vtab:active { color: var(--text-on-light); }
.band-light .vtab[aria-selected="true"],
.band-white .vtab[aria-selected="true"] {
  color: var(--navy);
  border-bottom-color: var(--navy);
}
.band-light .vtabs,
.band-white .vtabs { border-bottom-color: var(--line-light); }
.band-light .vpanel .accent,
.band-white .vpanel .accent { color: var(--navy); }

/* The Claude collateral section moved to the light band, so the pieces built
   for navy need their light counterparts. Cyan is 2.08:1 on the page, so the
   hook accent becomes navy rather than a lighter cyan. */
.band-light .hook-accent,
.band-white .hook-accent { color: var(--navy); }
.band-light .hook-sub,
.band-white .hook-sub { color: var(--text-on-light-muted); }
.band-light .compliance-note,
.band-white .compliance-note { color: var(--text-on-light-faint); }
/* this one sits on its own navy card inside the light section */
.band-light .claude-head,
.band-white .claude-head { color: var(--text-on-dark); }

/* Pieces that only ever appeared on a navy band, now that some of those bands
   have gone light. Each needs its light counterpart or it renders white on
   off-white, or near-black on near-black. */
.band-light .muted,
.band-white .muted { color: var(--text-on-light-muted); }
.band-light .cohort-note,
.band-white .cohort-note { color: var(--text-on-light-muted); }

/* White cards read on a navy band and lift off the off-white page, so one
   rule covers both and the on-dark overrides are no longer needed. */
.pain h3 { color: var(--text-on-light); }
.pain p  { color: var(--text-on-light-muted); }
.pain .n { color: var(--navy); }
.pain:hover { background: var(--paper); }

/* ---------- Hero photograph ---------------------------------------------
   The picture carries pure white in places, the window behind the desks, and
   the copy sits over the left of it. A flat wash dark enough for white text
   there would need about 88% and the photograph would be gone, so the wash is
   a gradient: solid navy under the words, thinning across to let the room
   show. Each tier loads its own file; a phone has no use for a 1920px image.
   -------------------------------------------------------------------------- */
/* The picture is named in custom properties so the tier rules below are
   written once and every page that wants a photographic hero only has to say
   which three files it uses. */
.hero--photo {
  --hero-sm: url("../img/hero-image-800.webp");
  --hero-md: url("../img/hero-image-1280.webp");
  --hero-lg: url("../img/hero-image.webp");
  background-image: var(--hero-sm);
  background-size: cover;
  background-position: 70% center;
  background-repeat: no-repeat;
}
/* A control's edge needs 3:1 against what is behind it. Over flat navy the
   46% white edge measures 3.30; over a photograph, where both the edge and
   its backdrop lift, it fell to 3.04. Raising the token here keeps the
   picture and the margin, rather than washing the picture out to save a
   border. The token exists for exactly this. */
.hero--photo { --edge-control-dark: rgba(255, 255, 255, .62); }

.hero--photo-ai {
  --hero-sm: url("../img/hero-ai-800.webp");
  --hero-md: url("../img/hero-ai-1280.webp");
  --hero-lg: url("../img/hero-ai.webp");
}
@media (min-width: 561px) {
  .hero--photo { background-image: var(--hero-md); }
}
@media (min-width: 1281px) {
  .hero--photo { background-image: var(--hero-lg); }
}

/* the wash. ::before so it sits under .hero > .wrap, which is positioned */
.hero--photo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    var(--navy) 0%,
    var(--navy) 40%,
    rgba(31, 68, 128, .88) 58%,
    rgba(31, 68, 128, .66) 100%
  );
}

/* On a tablet and a phone the copy runs the full width, so there is no clear
   side to thin towards. The wash runs top to bottom instead, heaviest where
   the headline sits. */
@media (max-width: 1080px) {
  .hero--photo { background-position: 60% center; }
  .hero--photo::before {
    background: linear-gradient(
      175deg,
      rgba(31, 68, 128, .95) 0%,
      rgba(31, 68, 128, .93) 55%,
      rgba(31, 68, 128, .80) 100%
    );
  }
}

@media (prefers-reduced-motion: no-preference) {
  .hero--photo { background-attachment: scroll; }   /* never fixed: it janks */
}
