/* ==========================================================================
   Threeum Models. Atmospheric page system.
   Original Threeum work. Self-hosted open-licensed faces (DM Sans, Montserrat).
   Light and dark, motion gated behind prefers-reduced-motion.
   ========================================================================== */

@font-face { font-family: "DM Sans"; font-weight: 400; font-style: normal; font-display: swap; src: url(/assets/fonts/dm-sans-400.woff2) format("woff2"); }
@font-face { font-family: "DM Sans"; font-weight: 500; font-style: normal; font-display: swap; src: url(/assets/fonts/dm-sans-500.woff2) format("woff2"); }
@font-face { font-family: "DM Sans"; font-weight: 700; font-style: normal; font-display: swap; src: url(/assets/fonts/dm-sans-700.woff2) format("woff2"); }
@font-face { font-family: "Montserrat"; font-weight: 400; font-style: normal; font-display: swap; src: url(/assets/fonts/montserrat-400.woff2) format("woff2"); }

/* Palette is the homepage's: white paper, near black ink, grey rules.
   Monochrome throughout, with the solid black acting as the accent. */
:root {
  /* Palette taken from the reference's own tokens: text-primary #1e232c,
     text-primary-bluish #152443, brand #4d6bfe, brand-deep #3a65c2,
     bg-page #f9f8f8, border-default rgba(0,0,0,.1), surface-raised
     hsla(0,0%,100%,.45), bg-input hsla(0,0%,100%,.2). */
  --ink: #1e232c;
  --ink-deep: #152443;
  /* Their description tier is rgba(0,0,0,.65); flattened here so it composites
     predictably over the moving ground. Measures above AA on this page. */
  --ink-soft: #3f444d;
  /* Their placeholder #8691a1 measures ~3.2:1, under AA, so real text uses a
     darker tier and only the input placeholders keep their value. */
  --ink-faint: #3f444d;
  --placeholder: #8691a1;

  --brand: #4d6bfe;
  --brand-deep: #3a65c2;
  --link-hover: #2f56ad;
  --input-border: #7c8798;
  --on-brand: #ffffff;

  --page: #f9f8f8;
  --grad-top: #eaf1fb;
  --grad-mid: #f9f8f8;
  --grad-bot: #fbfbfc;

  /* Deepened from their #dbe6fb/#e6ecf6/#eef1f7 so the drift stays visible. */
  --blob-a: #9dbcea;
  --blob-b: #b4cdf0;
  --blob-c: #cadef5;

  --glass: hsla(0, 0%, 100%, .30);
  --glass-strong: hsla(0, 0%, 100%, .45);
  --nav-glass: hsla(0, 0%, 100%, .45);
  --card-fill: hsla(0, 0%, 100%, .2);
  --pill-fill: hsla(0, 0%, 100%, .35);
  --pill-fill-on: hsla(0, 0%, 100%, .62);
  --btn-fill: hsla(0, 0%, 100%, .40);
  --btn-fill-hover: hsla(0, 0%, 100%, .62);
  --modal-fill: hsla(0, 0%, 100%, .86);
  --glass-sheen: rgba(255, 255, 255, .65);
  --glass-drop: rgba(9, 45, 78, .07);
  --nav-border: rgba(0, 0, 0, .1);
  --nav-ripple: rgba(0, 0, 0, .04);
  --nav-shadow: rgba(0, 0, 0, .08);
  --nav-text: #121c31;
  --nav-seg-idle: rgba(0, 0, 0, .65);
  --nav-seg-on: #1e232c;
  --glass-edge: rgba(255, 255, 255, .80);
  --grid-line: rgba(21, 36, 67, .045);

  --line: rgba(0, 0, 0, .1);
  --line-soft: rgba(0, 0, 0, .06);
  --btn-border: rgba(9, 45, 78, .18);
  --btn-border-hover: rgba(9, 45, 78, .30);

  --ok: #1e232c;
  --warn: #234792;

  --display: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --body: "DM Sans", -apple-system, "Helvetica Neue", Arial, sans-serif;

  --r-card: 16px;
  --r-pill: 999px;
  --blur: 12px;
  --maxw: 1140px;
  --maxw-scrolled: 980px;
  --maxw-panel: 880px;
}

:root[data-theme="dark"] {
  --ink: #d8d8d4;
  --ink-deep: #dbe3f2;
  --ink-soft: #9a9a96;
  --ink-faint: #8a8a8a;
  --placeholder: #7d8798;

  --brand: #6f8dff;
  --brand-deep: #8ea6ff;
  --link-hover: #8ea6ff;
  --input-border: #6a6a6a;
  --on-brand: #0b1020;

  --page: #0d0d0d;
  --grad-top: #141414;
  --grad-mid: #0d0d0d;
  --grad-bot: #0a0a0a;

  --blob-a: #16233f;
  --blob-b: #131c31;
  --blob-c: #111826;

  --glass: hsla(0, 0%, 100%, .05);
  --glass-strong: hsla(0, 0%, 100%, .08);
  --nav-glass: hsla(0, 0%, 0%, .45);
  --card-fill: hsla(0, 0%, 100%, .05);
  --pill-fill: hsla(0, 0%, 100%, .06);
  --pill-fill-on: hsla(0, 0%, 100%, .13);
  --btn-fill: hsla(0, 0%, 100%, .06);
  --btn-fill-hover: hsla(0, 0%, 100%, .13);
  --modal-fill: hsla(0, 0%, 7%, .88);
  --glass-sheen: rgba(255, 255, 255, .09);
  --glass-drop: rgba(0, 0, 0, .45);
  --nav-border: rgba(255, 255, 255, .12);
  --nav-ripple: rgba(255, 255, 255, .06);
  --nav-shadow: rgba(0, 0, 0, .5);
  --nav-text: #e4e4e0;
  --nav-seg-idle: rgba(255, 255, 255, .65);
  --nav-seg-on: #f2f2f0;
  --glass-edge: rgba(255, 255, 255, .10);
  --grid-line: rgba(232, 232, 228, .05);

  --line: #242424;
  --line-soft: rgba(255, 255, 255, .07);
  --btn-border: rgba(255, 255, 255, .18);
  --btn-border-hover: rgba(255, 255, 255, .32);

  --ok: #d8d8d4;
  --warn: #9a9a96;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ink: #d8d8d4;
    --ink-deep: #dbe3f2;
    --ink-soft: #9a9a96;
    --ink-faint: #8a8a8a;
    --placeholder: #7d8798;
    --brand: #6f8dff;
    --brand-deep: #8ea6ff;
    --link-hover: #8ea6ff;
    --input-border: #6a6a6a;
    --on-brand: #0b1020;
    --page: #0d0d0d;
    --grad-top: #141414;
    --grad-mid: #0d0d0d;
    --grad-bot: #0a0a0a;
    --blob-a: #16233f;
    --blob-b: #131c31;
    --blob-c: #111826;
    --glass: hsla(0, 0%, 100%, .05);
    --glass-strong: hsla(0, 0%, 100%, .08);
    --nav-glass: hsla(0, 0%, 0%, .45);
    --card-fill: hsla(0, 0%, 100%, .05);
    --pill-fill: hsla(0, 0%, 100%, .06);
    --pill-fill-on: hsla(0, 0%, 100%, .13);
    --btn-fill: hsla(0, 0%, 100%, .06);
    --btn-fill-hover: hsla(0, 0%, 100%, .13);
    --modal-fill: hsla(0, 0%, 7%, .88);
    --glass-sheen: rgba(255, 255, 255, .09);
    --glass-drop: rgba(0, 0, 0, .45);
    --nav-border: rgba(255, 255, 255, .12);
    --nav-ripple: rgba(255, 255, 255, .06);
    --nav-shadow: rgba(0, 0, 0, .5);
    --nav-text: #e4e4e0;
    --nav-seg-idle: rgba(255, 255, 255, .65);
    --nav-seg-on: #f2f2f0;
    --glass-edge: rgba(255, 255, 255, .10);
    --grid-line: rgba(232, 232, 228, .05);
    --line: #242424;
    --line-soft: rgba(255, 255, 255, .07);
    --btn-border: rgba(255, 255, 255, .18);
    --btn-border-hover: rgba(255, 255, 255, .32);
    --ok: #d8d8d4;
    --warn: #9a9a96;
  }
}

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }
html { color-scheme: light; scroll-behavior: smooth; }
:root[data-theme="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; } }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--page);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* ---------- atmosphere ------------------------------------------------- */

.atmosphere {
  position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none;
  background: linear-gradient(160deg, var(--grad-top) 0%, var(--grad-mid) 45%, var(--grad-bot) 100%);
  background-size: 200% 200%;
  animation: field 20s ease-in-out infinite alternate;
}
@keyframes field {
  from { background-position: 0% 0%; }
  to   { background-position: 100% 100%; }
}
@media (prefers-reduced-motion: reduce) { .atmosphere { animation: none; } }
.atmosphere::before {
  content: ""; position: absolute; inset: -2px;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: 64px 64px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse 80% 60% at 50% 30%, #000 30%, transparent 78%);
}
.blob { position: absolute; border-radius: 50%; filter: blur(60px); opacity: 1; will-change: transform; }
.blob--a { width: 62vw; height: 62vw; left: -12vw; top: -22vw; background: radial-gradient(circle at 40% 40%, var(--blob-a) 0%, transparent 78%); animation: drift-a 15s ease-in-out infinite alternate; }
.blob--b { width: 56vw; height: 56vw; right: -16vw; top: -6vw; background: radial-gradient(circle at 50% 50%, var(--blob-b) 0%, transparent 78%); animation: drift-b 19s ease-in-out infinite alternate; }
.blob--c { width: 48vw; height: 48vw; left: 22vw; bottom: -26vw; background: radial-gradient(circle at 50% 50%, var(--blob-c) 0%, transparent 78%); animation: drift-c 23s ease-in-out infinite alternate; }

@keyframes drift-a { from { transform: translate3d(-6vw,-4vw,0) scale(1); } to { transform: translate3d(22vw,14vw,0) scale(1.18); } }
@keyframes drift-b { from { transform: translate3d(5vw,-3vw,0) scale(1.12); } to { transform: translate3d(-20vw,18vw,0) scale(.92); } }
@keyframes drift-c { from { transform: translate3d(4vw,3vw,0) scale(.95); } to { transform: translate3d(-18vw,-16vw,0) scale(1.14); } }

@media (prefers-reduced-motion: reduce) { .blob { animation: none; } }

/* ---------- header ------------------------------------------------------ */

/* Wrapper is the fixed 54px band. The bar inside it is the pill that glasses on scroll. */
/* Wrapper geometry copied from the reference: a fixed, centred column whose
   width is a min() of the viewport minus a breakpoint-dependent gutter, with
   8px of top padding rather than a fixed-height band. */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  margin: 0 auto; padding: 8px 0 0;
  width: min(100% - 48px, 1140px);
}
@media (min-width: 768px)  { .header { width: min(100% - 144px, 1140px); } }
@media (min-width: 1280px) { .header { width: min(100% - 160px, 1280px); } }
.header__inner { width: 100%; margin: 0 auto; }

/* The bar contracts as it glasses: it gives up width and insets its contents,
   then expands back at the top of the page. Width and padding are transitioned
   alongside the colour change so the whole thing moves as one gesture. */
.navbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  height: 46px; border-radius: 100px;
  max-width: var(--maxw); margin: 0 auto; padding: 4px 0;
  border: 1px solid transparent; background: transparent; box-shadow: none;
  transition:
    background-color .3s ease,
    border-color .3s ease,
    backdrop-filter .3s ease,
    max-width .38s cubic-bezier(.22, .61, .36, 1),
    padding .38s cubic-bezier(.22, .61, .36, 1);
}
.navbar.is-scrolled {
  max-width: var(--maxw-scrolled); padding: 4px 6px 4px 16px;
  background: var(--nav-glass); border-color: var(--nav-border);
  backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur));
}
@media (prefers-reduced-motion: reduce) {
  .navbar { transition: background-color .3s ease, border-color .3s ease, backdrop-filter .3s ease; }
}

.brand { display: inline-flex; align-items: center; gap: 9px; font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: var(--ink-deep); flex: none; }

/* Brand blue mark. Deliberately NOT inverted on a dark ground: the homepage
   inverts because its mark is drawn black, but inverting blue yields orange.
   The blue reads on both grounds, so it is left alone and lifted slightly in
   dark to sit with the lighter dark-theme brand. */
.mark { height: 26px; width: auto; flex: none; display: block; }
:root[data-theme="dark"] .mark { filter: brightness(1.18) saturate(1.05); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .mark { filter: brightness(1.18) saturate(1.05); }
}

/* Desktop action group. No page links up here, the bottom nav carries those. */
.navtools { display: flex; align-items: center; gap: 8px; }
.navtools__cta {
  font-family: inherit; cursor: pointer;
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  height: 36px; min-width: 80px; padding: 8px 12px; border-radius: 100px; box-sizing: border-box;
  font-size: 15px; font-weight: 400; line-height: 1.2; color: var(--nav-text);
  border: 1px solid transparent; background: transparent;
  overflow: hidden; isolation: isolate; transition: border-color .2s;
}
/* Radial fill grows from the centre on hover, matching the reference. */
.navtools__cta::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 150%; aspect-ratio: 1 / 1;
  border-radius: 50%; opacity: 0; z-index: -1; background: var(--nav-ripple);
  transform: translate(-50%, -50%) scale(0);
  transition: transform .36s ease-out, opacity .1s;
}
.navtools__cta:hover { border-color: var(--nav-border); }
.navtools__cta:hover::after { opacity: 1; transform: translate(-50%, -50%) scale(1); }
/* Segmented control, same construction as the reference's locale pill:
   32px outer with 3px padding, 24px items, the active one raised on a
   translucent white with a soft shadow. */
.seg {
  display: flex; align-items: center; height: 32px; padding: 3px; flex: none;
  border: 1px solid var(--nav-border); border-radius: 100px; background: transparent;
  box-sizing: border-box;
}
.seg__item {
  display: flex; align-items: center; justify-content: center; height: 100%;
  padding: 0 12px; border: 0; border-radius: 100px; background: transparent; cursor: pointer;
  font-family: inherit; font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap;
  color: var(--nav-seg-idle);
  transition: color .2s, background-color .2s, box-shadow .2s;
}
.seg__item[aria-checked="true"] { background: var(--ink); color: var(--page); box-shadow: none; }
.seg__item:hover { color: var(--nav-seg-on); }
.mobile-menu__seg { margin-top: 26px; display: flex; }

/* Colour mode docked bottom-left, floating clear of the page flow. It sits
   below the full-screen menu (z 9990), which carries its own copy of the
   control so the setting stays reachable while the menu covers the page. */
.mode-dock {
  position: fixed; left: 24px; bottom: 24px; z-index: 60;
}
.mode-dock .seg {
  background: var(--nav-glass);
  border-color: var(--nav-border);
  backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur));
}
@media (max-width: 767px) {
  .mode-dock { left: 16px; bottom: 16px; }
}

/* Burger replaces the action group below the md breakpoint. */
/* Flex column, not grid: grid rows stretch to the button height, which pushes the
   bars 8.5px apart and makes the X collapse into a chevron. Flex keeps the pitch
   at exactly the bar height plus its margin, so translateY(6.5px) lands true. */
.nav-burger {
  display: none; flex-direction: column; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: none; cursor: pointer;
  border: 0; border-radius: var(--r-pill); background: transparent; color: var(--ink); padding: 0;
}
.nav-burger span { display: block; width: 18px; height: 1.5px; background: currentColor; border-radius: 2px; transition: transform .25s ease, opacity .2s ease; }
.nav-burger span + span { margin-top: 5px; }
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

@media (max-width: 767px) {
  .navtools { display: none; }
  .nav-burger { display: flex; }
}

/* The close control inside the menu is always shown, at any width. */
.mobile-menu .nav-burger { display: flex; }

/* Full screen menu. Fades in, matching their opacity transition rather than a slide. */
.mobile-menu {
  position: fixed; inset: 0; z-index: 9990; display: flex; flex-direction: column;
  background: var(--page); opacity: 0; pointer-events: none; visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}
.mobile-menu.is-open { opacity: 1; pointer-events: auto; visibility: visible; transition: opacity .2s ease, visibility 0s; }
.mobile-menu__head { display: flex; align-items: center; justify-content: space-between; height: 54px; padding: 0 20px 0 26px; flex: none; }
.mobile-menu__body { padding: 20px 26px 40px; overflow-y: auto; }
.mobile-menu__body h2 { font-size: 12px; font-weight: 500; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-faint); margin: 26px 0 8px; }
.mobile-menu__body h2:first-child { margin-top: 6px; }
/* Direct children only. A descendant selector here outranks .btn and would
   flatten the call to action into a plain block link. */
.mobile-menu__body > a { display: block; font-size: 19px; color: var(--ink-deep); padding: 11px 0; border-bottom: 1px solid var(--line-soft); }
.mobile-menu__cta { margin-top: 30px; }
.mobile-menu__cta .btn { width: 100%; justify-content: center; }
@media (prefers-reduced-motion: reduce) { .mobile-menu { transition: none; } .nav-burger span { transition: none; } }
body.is-locked { overflow: hidden; }

/* ---------- layout ------------------------------------------------------ */

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 20px; }
.section { padding: 84px 0; }
.section--tight { padding: 56px 0; }
.eyebrow {
  font-size: 12px; font-weight: 500; letter-spacing: .10em; text-transform: uppercase;
  color: var(--brand); margin-bottom: 14px;
}
h2 { font-family: var(--display); font-weight: 400; font-size: clamp(28px, 4vw, 42px); line-height: 1.18; letter-spacing: -.015em; color: var(--ink-deep); }
h3 { font-size: 19px; font-weight: 500; letter-spacing: -.01em; }
.lead { margin-top: 14px; max-width: 62ch; font-size: 17px; color: var(--ink-soft); }
.small { font-size: 14px; color: var(--ink-faint); }

/* ---------- reveal ------------------------------------------------------ */

/* The hidden state is scoped to .js, which an inline script sets before paint.
   Without JavaScript, or if this script never runs, every section stays visible. */
.js [data-reveal] { opacity: 0; transform: translateY(14px); transition: opacity .6s cubic-bezier(.22,.61,.36,1), transform .6s cubic-bezier(.22,.61,.36,1); }
.js [data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js [data-reveal] { opacity: 1; transform: none; transition: none; } }

/* ---------- hero -------------------------------------------------------- */

.hero {
  min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
  padding: 96px 0 72px; text-align: center;
}
@supports not (min-height: 100svh) { .hero { min-height: 100vh; } }

/* .wrap is a flex item inside the centred hero, so without this it shrinks to
   its content and the 880px panel can never reach its intended width. */
.hero > .wrap { width: 100%; }

/* Rotating headline. The animated half is aria-hidden and a static sentence
   sits beside it in a visually-hidden span, so the accessible name of the h1
   never changes and screen readers are not spammed on every keystroke. */
/* Cursor lens over the title, as in the reference: a circle that follows the
   pointer and inverts whatever sits beneath it. difference against a white
   fill flips the dark letters light and the light ground dark, so the effect
   comes from blending rather than from a second copy of the text. */
.title-lens {
  position: absolute; left: 0; top: 0;
  width: 56px; height: 56px; border-radius: 50%;
  background: #fff; mix-blend-mode: difference;
  pointer-events: none; opacity: 0;
  transform: translate3d(-100px, -100px, 0) translate(-50%, -50%);
  transition: opacity .18s ease;
  will-change: transform;
}
.hero__title.is-lensing .title-lens { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .title-lens { display: none; } }
@media (hover: none) { .title-lens { display: none; } }

/* Big static title, as in the reference. */
.hero .hero__title {
  position: relative;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(34px, 6.4vw, 50px); line-height: 1.55; letter-spacing: normal;
  color: var(--ink-deep); text-align: center;
  /* Box hugs the text so the cursor lens only arms over the letters. As a
     full width block the hover region spanned the whole column and the lens
     appeared far from the title. The reference's region hugs its text too. */
  width: fit-content; max-width: 100%; margin: 0 auto;
}
.caret {
  display: inline-block; width: 1.5px; height: 1.05em; margin-left: .08em;
  background: currentColor; vertical-align: -.06em;
  animation: caret 1s steps(1, end) infinite;
}
@keyframes caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .caret { animation: none; opacity: 1; } }
.announce {
  max-width: 560px; margin: 0 auto 24px; padding: 0;
  border: 0; background: none; backdrop-filter: none;
  font-family: var(--body);
  font-size: 15px; line-height: 24px; text-align: center;
  /* The reference renders this at 0.55 opacity, which lands under 3:1 against
     its ground. Size, leading and column width are matched; the colour is a
     token that actually passes AA. */
  color: var(--ink-soft);
}
.announce .dot { display: inline-block; margin-right: 8px; vertical-align: middle; }
.announce .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex: none; animation: pulse 2.6s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: .45; transform: scale(.75); } 50% { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .announce .dot { animation: none; opacity: 1; } }

.hero h1 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(38px, 7vw, 64px); line-height: 1.1; letter-spacing: -.02em; color: var(--ink-deep);
}
.hero__lead { margin: 22px auto 0; max-width: 60ch; font-size: 18px; color: var(--ink-soft); }

.panel {
  width: 100%; max-width: var(--maxw-panel); margin: 44px auto 0; padding: 24px 26px;
  border: 2px solid var(--glass-edge); border-radius: var(--r-card); background: var(--glass);
  backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur)); text-align: left;
}
.panel__row { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.panel__k { font-size: 13px; color: var(--ink-faint); }
.panel__v { font-size: 15px; color: var(--ink); }
.panel__line { height: 1px; background: var(--line-soft); margin: 14px 0; }

/* Chat-box card, built to the reference's hero input: 880 wide, 24px radius,
   a 2px edge over a translucent fill with a 12px blur, card padding
   4px 10px 10px, a 16px text block carrying its own 12px, then a row of pills
   and a 40x40 round send button. The edge is a neutral rule rather than their
   near-white one, which is invisible on this monochrome ground. */
.chatbox {
  width: 100%; max-width: var(--maxw-panel); margin: 40px auto 0;
  display: flex; flex-direction: column; gap: 4px;
  padding: 4px 10px 10px; border-radius: 24px;
  border: 2px solid var(--glass-edge);
  background: var(--card-fill);
  backdrop-filter: blur(var(--blur)) saturate(180%); -webkit-backdrop-filter: blur(var(--blur)) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glass-sheen), 0 10px 34px var(--glass-drop);
  text-align: left;
}

/* The typed line inside the card. 16px / 22.4px, 12px of its own padding on
   top of the card's 10px, so the first character starts 22px in, matching the
   reference placeholder. The reserve matches their 80px textarea so cycling
   through phrases of different lengths cannot resize the card. */
.chatbox__line {
  margin: 0; padding: 12px; text-align: left;
  font-family: var(--body);
  font-size: 16px; line-height: 22.4px; font-weight: 400; color: var(--ink);
  min-height: 80px;
}

/* Modal. <dialog> is used so focus trapping, Escape and the inert background
   come from the platform rather than hand-rolled JavaScript. */
.modal {
  width: min(100% - 32px, 440px); padding: 0; border: 0; border-radius: 20px;
  background: transparent; color: var(--ink);
  /* A native modal centres via its UA `margin: auto`, which the global
     `* { margin: 0 }` reset at the top of this file wipes out. Without this
     the dialog pins to the top left corner. */
  margin: auto;
}
.modal::backdrop { background: rgba(12, 12, 12, .42); backdrop-filter: blur(3px); }

.modal__card {
  display: flex; flex-direction: column; gap: 14px;
  padding: 26px; border-radius: 20px;
  border: 1px solid var(--glass-edge); background: var(--modal-fill);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 18px 48px rgba(9, 45, 78, .18);
  text-align: left;
}

.modal__title {
  font-family: var(--display); font-weight: 400; font-size: 24px; line-height: 1.2;
  letter-spacing: -.01em; color: var(--ink-deep); margin: 0;
}
.modal__lede { margin: -6px 0 2px; font-size: 14.5px; color: var(--ink-soft); }

/* First and last name share a row; they stack once the card is narrower
   than two comfortable inputs. */
.modal__row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 420px) { .modal__row { grid-template-columns: 1fr; } }
.modal__field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.modal__field > span { font-size: 13px; color: var(--ink-soft); }
.modal__field input {
  width: 100%; padding: 11px 12px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card-fill);
  font-family: var(--body); font-size: 15px; color: var(--ink);
}
.modal__field input::placeholder { color: var(--placeholder); }
.modal__field input:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-color: var(--brand); }

.modal__status { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--ink-soft); }
.modal__status[data-state="error"] { color: var(--warn); }
.modal__status[data-state="ok"] { color: var(--ink); }

.modal__actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 2px; }

/* The footer "Get started" is a button now; keep it reading as a footer link. */
.footer__linkbtn {
  display: block; padding: 5px 0; border: 0; background: none; cursor: pointer;
  font-family: inherit; font-size: 14.5px; color: var(--ink-soft); text-align: left;
  transition: color .18s ease;
}
.footer__linkbtn:hover { color: var(--link-hover); }

/* Honeypot, same convention as the contact form. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.chatbox__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding-left: 12px; }

.chatbox__pills { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chatbox__pill {
  display: inline-flex; align-items: center; height: 34px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 18px;
  background: var(--pill-fill);
  backdrop-filter: blur(var(--blur)) saturate(180%); -webkit-backdrop-filter: blur(var(--blur)) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glass-sheen);
  font-size: 13px; line-height: 1; color: var(--ink-soft); white-space: nowrap;
}
.chatbox__pill--on {
  border-color: var(--btn-border); color: var(--ink);
  background: var(--pill-fill-on);
}
@media (max-width: 599px) { .chatbox__pill { height: 30px; padding: 0 10px; font-size: 12px; } }

.chatbox__send {
  flex: none; width: 40px; height: 40px; display: grid; place-items: center; cursor: pointer;
  border: 0; border-radius: 50%; background: var(--brand); color: var(--on-brand);
  transition: background-color .2s ease, opacity .2s ease, transform .2s ease;
}
.chatbox__send:hover { background: var(--brand-deep); }
.chatbox__send:active { transform: scale(.94); }
.chatbox__send[disabled] { opacity: .45; cursor: default; }


.cta-row { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 40px; }
.cta-row--left { justify-content: flex-start; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; padding: 12px 20px; box-sizing: border-box;
  border-radius: 100px; border: 1px solid var(--line); background: var(--card-fill);
  backdrop-filter: blur(var(--blur)) saturate(180%); -webkit-backdrop-filter: blur(var(--blur)) saturate(180%);
  box-shadow: inset 0 1px 0 var(--glass-sheen);
  font-family: var(--body); font-size: 15px; font-weight: 500; line-height: 1; color: var(--ink); cursor: pointer;
  transition: border-color .22s ease, background-color .22s ease, transform .22s ease;
}
.btn:hover { border-color: var(--brand); background: var(--glass); transform: translateY(-1px); }
.btn { background: var(--btn-fill); border-color: var(--btn-border); color: var(--ink); }
.btn:hover { background: var(--btn-fill-hover); border-color: var(--btn-border-hover); }
/* Deliberately not a brand fill. White on #4d6bfe measures 4.33:1, under the
   4.5 floor for 15px text. The reference keeps both hero CTAs ghost for the
   same reason and uses the brand only on the icon button. */
.btn--primary { font-weight: 500; }
.btn .arrow { transition: transform .22s ease; }
.btn:hover .arrow { transform: translateX(3px); }

/* ---------- pilot phases ------------------------------------------------ */

.phases { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin-top: 30px; counter-reset: phase; }
@media (max-width: 860px) { .phases { grid-template-columns: 1fr; } }
.phase {
  position: relative; padding: 28px 26px; border: 1px solid var(--line-soft); border-radius: var(--r-card);
  background: var(--glass); backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur));
  transition: border-color .28s ease;
}
.phase:hover { border-color: var(--brand); }
.phase__n {
  display: inline-block; margin-bottom: 10px; font-size: 12px; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase; color: var(--brand);
}
.phase h3 { font-family: var(--display); font-weight: 400; font-size: 24px; letter-spacing: -.01em; color: var(--ink-deep); }
.phase p { margin-top: 12px; font-size: 15.5px; color: var(--ink-soft); }
.phase__note {
  margin-top: 16px !important; padding-top: 14px; border-top: 1px solid var(--line-soft);
  font-size: 14px !important; color: var(--ink-faint) !important;
}

/* ---------- points + exits ---------------------------------------------- */

.points { list-style: none; display: grid; gap: 12px; margin-top: 26px; }
.points li { display: flex; gap: 12px; font-size: 15.5px; color: var(--ink-soft); }
.points li::before { content: ""; flex: none; width: 5px; height: 5px; margin-top: 10px; border-radius: 50%; background: var(--brand); }

.exits { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-top: 30px; }
.exits--two { grid-template-columns: repeat(2, 1fr); max-width: 760px; }
@media (max-width: 860px) { .exits, .exits--two { grid-template-columns: 1fr; } }
.exit {
  display: block; padding: 26px 24px; border: 1px solid var(--line-soft); border-radius: var(--r-card);
  background: var(--glass); backdrop-filter: blur(var(--blur)); -webkit-backdrop-filter: blur(var(--blur));
  transition: transform .28s cubic-bezier(.22,.61,.36,1), border-color .28s ease;
}
.exit:hover { transform: translateY(-3px); border-color: var(--brand); }
@media (prefers-reduced-motion: reduce) { .exit:hover { transform: none; } }
.exit__t { font-size: 17px; font-weight: 500; color: var(--ink-deep); }
.exit__d { margin-top: 8px; font-size: 14.5px; color: var(--ink-soft); }
.exit__a { margin-top: 16px; font-size: 14.5px; color: var(--brand); display: inline-flex; gap: 6px; }
.exit:hover .exit__a .arrow { transform: translateX(3px); }
.exit__a .arrow { transition: transform .22s ease; }

/* ---------- footer ------------------------------------------------------ */

/* Bottom nav. This is where the site's navigation actually lives. */
/* Extra bottom padding so the docked colour-mode control (32px tall, 24px
   from the bottom edge) cannot sit on top of the footer's last row when the
   page is scrolled all the way down. */
.footer { border-top: 1px solid var(--line-soft); padding: 54px 0 112px; margin-top: 30px; }
@media (max-width: 767px) { .footer { padding-bottom: 96px; } }
.footer__grid { display: grid; grid-template-columns: 1.4fr repeat(3, 1fr); gap: 32px; }
@media (max-width: 900px) { .footer__grid { grid-template-columns: 1fr 1fr; gap: 30px 24px; } }
@media (max-width: 520px) { .footer__grid { grid-template-columns: 1fr; } }

.footer__brand { display: inline-flex; align-items: center; gap: 9px; font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: var(--ink-deep); }
.footer__brand .mark { height: 24px; }
.footer__meta { margin-top: 14px; font-size: 13.5px; line-height: 1.75; color: var(--ink-faint); max-width: 34ch; }

.footer__col h2 { font-size: 13px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 14px; }
.footer__col a { display: block; font-size: 14.5px; color: var(--ink-soft); padding: 5px 0; transition: color .18s ease; }
.footer__col a:hover { color: var(--link-hover); }

/* Footer blocks travel a little further and settle a little slower than the
   page reveals, so the whole band reads as one cascade rather than four
   separate pops. */
.js .footer [data-reveal]:not(.is-in) { transform: translateY(20px); }
.js .footer [data-reveal] { transition-duration: .7s; }

.footer__base { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 44px; padding-top: 22px; border-top: 1px solid var(--line-soft); font-size: 13.5px; color: var(--ink-faint); }

/* Announce-only region used by models.js for colour mode changes. */
.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;
}


/* ---------- audit additions ------------------------------------------- */

/* Fixed header and mode dock overlap the page edges; keep focused elements
   clear of both when they are scrolled into view. */
html { scroll-padding-top: 64px; scroll-padding-bottom: 72px; }

.skip-link { position: absolute; left: 16px; top: -100px; z-index: 10000; padding: 10px 14px; border-radius: 999px; background: var(--ink); color: var(--page); font-size: 14px; text-decoration: none; }
.skip-link:focus { top: 12px; outline: 2px solid var(--brand); outline-offset: 2px; }

/* Inputs get a boundary that clears 3:1 on the card in both themes. */
.modal__field input { border-color: var(--input-border); }

/* The status region stays in the tree (so live announcements fire) and only
   collapses visually while empty. */
.modal__status:empty { display: none; }

/* Hover and press transforms are motion too. */
@media (prefers-reduced-motion: reduce) {
  .btn, .btn .arrow, .chatbox__send { transition: none; }
  .btn:hover, .btn:hover .arrow, .chatbox__send:active { transform: none; }
  .js .footer [data-reveal]:not(.is-in) { transform: none; }
}
