/* ============================================================
   AlgoTraders.ai site stylesheet (home, Case studies, Team)
   v3.3 (folder, 2026-10-18): the former v3.6 prototype, kept as the site version after v3.2; the iteration names below (v3.4, v3.5, v3.6) record the design history.
   v3.6: v3.5 with the compact ladder per Claude/DESIGN_v3.6.md
   (smaller display ladder, 16px reading copy in the bands, 64px
   section padding, every home band but the hero inside one 1440 x 900
   screen; Services panel in two columns).
   v3.5: v3.4 consolidated per Claude/DESIGN_v3.5.md (one display
   weight, one display ladder, one label style, one button family,
   two reading sizes, flat grounds, hairlines not shadows).
   One file: tokens (copied from v3.3/css/site.css), then primitives
   (button, text link, section header, nav, product frame, form), then
   the home page sections in page order, then the sub-page sections.
   Rule: every colour, size and spacing comes from a token.
   ============================================================ */

/* ---------------------------------------------------------------
   1. Tokens (copied from Claude/Components/assets/tokens.css)
   --------------------------------------------------------------- */
:root {
  /* Type */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body: "Public Sans", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Type scale (use only these) */
  --t-12: 0.75rem;
  --t-14: 0.875rem;
  --t-16: 1rem;
  --t-18: 1.125rem;
  --t-20: 1.25rem;
  --t-24: 1.5rem;
  --t-32: clamp(1.75rem, 1.4rem + 1.2vw, 2.125rem);   /* section titles, study titles, metrics */
  --t-40: clamp(2rem, 1.6rem + 1.4vw, 2.5rem);        /* page titles */
  /* Display ladder (v3.6, Claude/DESIGN_v3.6.md): hero 62 (v3.2) /
     page titles 40 / section titles 32 / item headings 24 (uses, Why
     statements, ledger groups, members, form success) / 20 tabs,
     contact titles, map names / leads 18 / body 16 / small 14 /
     labels 12.5. Nothing on the home above 32 but the hero. --t-44
     retired (v3.5 section and page titles). Every Fraunces setting is
     weight 400 (the hero title alone keeps 500); at 32 and above it
     sets at --lh-tight and -0.01em, below 32 at --lh-snug with no
     tracking. */
  /* Tracked uppercase labels (v3.5): nav links, nav button, map
     column labels. The wordmark keeps its own (official logotype); the
     hero eyebrow and hero button keep their v3.2 values. */
  --t-label: 12.5px;
  --track-label: 0.1em;
  /* hero only: the v3.2 hero title size (.hero-title, 2026-10-18 update 4) */
  --t-display: clamp(38px, 6vw, 62px);

  --lh-tight: 1.1;
  --lh-snug: 1.25;
  --lh-body: 1.6;

  /* Spacing scale (use only these) */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-12: 48px;
  --s-16: 64px;
  --s-24: 96px;
  --s-32: 128px;

  /* Section vertical padding: two sizes only, fixed (v3.6: from the
     96px and 64px clamps, so every band fits one 1440 x 900 screen) */
  --section-pad: var(--s-16);
  --section-pad-compact: var(--s-12);

  /* Widths */
  --w-content: 1200px;
  --w-narrow: 760px;
  --w-prose: 66ch;
  --gutter: max(16px, env(safe-area-inset-left, 0px));
  /* Fixed nav bar height (the v4.0 bar): 72px, 64px below 760px */
  --nav-h: 72px;

  /* Radii */
  --r-s: 4px;
  --r-m: 8px;

  /* Colour: deep teal tonal scale */
  --dark-0: #00171f;
  --dark-1: #062430;
  --dark-2: #0a3140;
  --brand-deep: #1f4e5e;
  --brand-teal: #3d94b0;
  --teal-light: #7fc1d4;
  --teal-wash: #eef5f7;
  /* The official logotype colour (images/logo/algotraders-with-text.png),
     used only for the wordmark on the white bar */
  --logo-blue: #0d4978;

  /* Neutrals, hue-biased toward the brand */
  --paper: #ffffff;
  --ink: #14323e;
  --ink-soft: #44565e;
  --ink-mute: #6b7c84;
  --line: #dde6e9;
  --line-strong: #c6d3d8;
  --alert: #c0392b; /* form errors and the under-count, from v3.2 */
  --alert-on-dark: #e8927f; /* the alert colour at AA on --dark-1 */

  /* On dark surfaces */
  --on-dark: #ffffff;
  --on-dark-soft: rgba(255, 255, 255, 0.78);
  --on-dark-mute: rgba(255, 255, 255, 0.62); /* AA on --dark-1 */
  --line-dark: rgba(255, 255, 255, 0.12);

  /* The v3.2 hero values (update 4, 2026-10-18): type, colour and
     rhythm of the v3.2 hero title, sub line and ghost button, used only
     inside .hero. */
  --lh-hero-title: 1.08;          /* v3.2 hero value: .hero-title line-height */
  /* Hero rhythm (v3.5 update 1): one scale, increasing down the stack.
     Eyebrow to headline, headline to service row, service row to button;
     below 600px one step smaller each (section 5) */
  --hero-title-gap-top: 0;                 /* the eyebrow's gap alone sets eyebrow to headline */
  --hero-title-gap-bottom: var(--s-8);     /* headline to service row, 32px */
  --hero-brand-gap: var(--s-5);            /* eyebrow to headline, 20px */
  --t-hero-sub: 17px;             /* v3.2 hero value: .hero-sub font-size */
  --t-hero-sub-phone: 15px;       /* v3.2 hero value: .hero-sub below 600px */
  --lh-hero-sub: 1.65;            /* v3.2 hero value: .hero-sub line-height */
  --hero-sub-c: #c9d8de;          /* v3.2 hero value: .hero-sub colour */
  --hero-sub-gap: var(--s-10);             /* service row to button, 40px */
  --t-hero-btn: 13.5px;           /* v3.2 hero value: .cta-btn font-size; v3.5: every .btn */
  --hero-btn-track: 0.07em;       /* v3.2 hero value: .cta-btn letter-spacing; v3.5: every .btn */
  --hero-btn-line: rgba(255, 255, 255, 0.45);       /* v3.2 hero value: #home .cta-btn.ghost border; v3.5: every ghost on dark */
  --hero-btn-line-hover: rgba(255, 255, 255, 0.8);  /* v3.2 hero value: hover border; v3.5: every ghost on dark */
  --hero-btn-wash-hover: rgba(255, 255, 255, 0.1);  /* v3.2 hero value: hover background; v3.5: every ghost on dark */
  --hero-btn-w-phone: min(300px, calc(100vw - 60px)); /* v3.2 hero value: button width below 600px */

  /* Shadows, tinted toward the brand hue. Only two things float: the
     skip link and the product frame (v3.5: the bar and the drop-down
     take hairlines; the card shadows are retired) */
  --shadow-float: 0 1px 2px rgba(20, 50, 62, 0.06), 0 10px 28px rgba(20, 50, 62, 0.09);
  --shadow-frame: 0 2px 6px rgba(0, 23, 31, 0.25), 0 30px 70px rgba(0, 23, 31, 0.35);
}

/* ---------------------------------------------------------------
   2. Base (tokens.css base, plus page-level scroll behaviour)
   --------------------------------------------------------------- */
html {
  -webkit-text-size-adjust: 100%;
  /* Anchor jumps land clear of the fixed nav bar */
  scroll-padding-top: var(--nav-h);
}
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--t-16);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}
/* One display weight (v3.5): 400 everywhere; only .hero h1 keeps 500 */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: var(--lh-snug);
  margin: 0;
  text-wrap: balance;
}
p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--brand-teal); outline-offset: 3px; }
/* Light teal ring on every dark surface */
.band-dark :focus-visible, .on-dark :focus-visible, .nav :focus-visible { outline-color: var(--teal-light); }
.nav.is-scrolled :focus-visible, .nav.nav--solid :focus-visible { outline-color: var(--brand-teal); }

.container {
  width: 100%;
  max-width: var(--w-content);
  margin-inline: auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
  box-sizing: border-box;
}
/* Flat ground (v3.5): no gradient wash */
.band-dark { background: var(--dark-0); color: var(--on-dark); }
.section { padding-block: var(--section-pad); }

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

/* Skip link: first focusable element, visible only on keyboard focus */
.skip-link {
  position: absolute; left: var(--s-3); top: var(--s-3); z-index: 100;
  transform: translateY(calc(-100% - var(--s-6)));
  background: var(--paper); color: var(--brand-deep);
  font: 600 var(--t-14)/var(--lh-snug) var(--font-body);
  padding: var(--s-2) var(--s-4); border-radius: var(--r-s);
  text-decoration: none;
}
/* The shadow only while shown: parked above the viewport, its blur
   would bleed a smudge onto the top-left of the white bar */
.skip-link:focus { transform: none; box-shadow: var(--shadow-float); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; animation-delay: 0s !important; }
}

/* ---------------------------------------------------------------
   3. Primitives
   --------------------------------------------------------------- */

/* Buttons (v3.5): one family, in the form of the v3.2 hero button.
   13.5px uppercase tracked 0.07em, radius --r-s. Primary in the page's
   own teal scale (v3.6 update 1): --brand-deep with white text on white
   surfaces (hover --dark-2), --teal-light with --dark-0 text on dark
   surfaces (hover --paper). Ghost with a hairline (--line-strong on
   white, --hero-btn-line on dark). While disabled (in flight) the
   primary keeps its look under the progress cursor. 14px 28px is the
   family's own padding (the v3.2 hero height); the nav button is the
   same .btn at 10px 18px. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  font: 600 var(--t-hero-btn)/normal var(--font-body);
  letter-spacing: var(--hero-btn-track); text-transform: uppercase;
  padding: 14px 28px;
  border: 1px solid transparent; border-radius: var(--r-s);
  text-decoration: none; white-space: nowrap; cursor: pointer; touch-action: manipulation;
  transition: background-color 160ms ease, border-color 160ms ease, color 160ms ease;
}
.btn-primary { background: var(--brand-deep); color: var(--on-dark); }
.btn-primary:hover { background: var(--dark-2); }
.btn-primary:disabled { cursor: progress; }
.band-dark .btn-primary, .on-dark .btn-primary, .review-band .btn-primary { background: var(--teal-light); color: var(--dark-0); }
.band-dark .btn-primary:hover, .on-dark .btn-primary:hover, .review-band .btn-primary:hover { background: var(--paper); color: var(--dark-0); }
.btn-ghost { color: var(--brand-deep); border-color: var(--line-strong); background: transparent; }
.btn-ghost:hover { border-color: var(--brand-deep); background: var(--teal-wash); }
.band-dark .btn-ghost, .on-dark .btn-ghost { color: var(--on-dark); border-color: var(--hero-btn-line); }
.band-dark .btn-ghost:hover, .on-dark .btn-ghost:hover { border-color: var(--hero-btn-line-hover); background: var(--hero-btn-wash-hover); }

/* Text link: underline at 3px offset, no arrow */
.link {
  font: 600 var(--t-16)/var(--lh-snug) var(--font-body);
  color: var(--brand-deep);
  text-decoration: underline; text-decoration-color: var(--line-strong);
  text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.link:hover { text-decoration-color: currentColor; }
.band-dark .link { color: var(--teal-light); text-decoration-color: var(--line-dark); }
.band-dark .link:hover { text-decoration-color: currentColor; }

/* Section header A (02): centred, one colour; title at --t-32 so it
   outranks every heading in its section (24 and below, v3.6), lead at
   18. --s-10 to the content (v3.6, from --s-16), --s-8 on phones */
.sh { text-align: center; margin: 0 auto var(--s-10); max-width: var(--w-narrow); }
.sh-title { font-size: var(--t-32); line-height: var(--lh-tight); letter-spacing: -0.01em; color: var(--ink); }
.sh-lead { font-size: var(--t-18); color: var(--ink-soft); max-width: 60ch; margin: var(--s-3) auto 0; text-wrap: balance; }
.band-dark .sh-title { color: var(--on-dark); }
.band-dark .sh-lead { color: var(--on-dark-soft); }
/* Longer lead (the confidential review): same size, prose width */
.sh-lead-l { max-width: var(--w-prose); }
@media (max-width: 760px) {
  .sh { margin-bottom: var(--s-8); }
}

/* ---------------------------------------------------------------
   4. Nav: the v4.0 bar, in v3.3 tokens
   Fixed, --nav-h tall. Transparent over the hero (white mark, white
   wordmark and links, ghost button); js/site.js adds .is-scrolled once
   the page has scrolled past the hero: white bar, colour mark, ink text,
   primary button. Pages without a hero carry .nav--solid in the markup:
   the same white state from the first paint, no JS needed.
   Below 900px a burger opens a drop-down panel (.is-open).
   Underline: the current page link, or the scrollspy link (.is-active)
   once js/site.js runs the spy (.spy-on).
   Labels and the button use the label tokens (v3.5). The scrolled
   and solid bar take a hairline, not a shadow (v3.5).
   --------------------------------------------------------------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  height: var(--nav-h); box-sizing: border-box;
  color: var(--on-dark); background: transparent;
  /* transparent over the hero, --line on the white bar; inside --nav-h */
  border-bottom: 1px solid transparent;
  transition: background-color 0.35s ease, border-color 0.35s ease;
}
.nav-bar {
  height: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-6);
  max-width: var(--w-content); margin-inline: auto; box-sizing: border-box;
  padding-inline: var(--gutter);
}
.brand { display: inline-flex; align-items: center; gap: 10px; flex: none; text-decoration: none; color: inherit; }
/* Two marks stacked: white over the hero, colour on the white bar */
.brand-mark { position: relative; width: 34px; height: 34px; flex: none; }
.brand-mark img { position: absolute; inset: 0; width: 100%; height: 100%; transition: opacity 0.35s ease; }
.brand-mark .mark-ink { opacity: 0; }
/* Wordmark as the official logotype: one colour, bold, uppercase */
.brand-word {
  font: 700 var(--t-16)/1 var(--font-body); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--on-dark); transition: color 0.35s ease;
}

.nav-menu { display: flex; align-items: center; gap: 28px; }
.nav-links { display: flex; align-items: center; gap: 26px; }
.nav-links a {
  position: relative; display: block; padding-block: var(--s-2);
  font: 600 var(--t-label)/var(--lh-snug) var(--font-body); letter-spacing: var(--track-label); text-transform: uppercase;
  text-decoration: none; color: rgba(255, 255, 255, 0.86);
  transition: color 0.35s ease;
}
.nav-links a:hover, .nav-links a.is-active, .nav:not(.spy-on) .nav-links a[aria-current="page"] { color: var(--on-dark); }
.nav-links a.is-active::after,
.nav:not(.spy-on) .nav-links a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 2px;
  height: 2px; border-radius: 1px; background: var(--teal-light);
}
/* The button: the house .btn at the bar size, in the label type so it
   sits in line with the links. Ghost on the transparent bar (the ghost
   on dark), the primary (--brand-deep) on the white bar */
.nav-cta {
  font-size: var(--t-label); letter-spacing: var(--track-label); padding: 10px 18px;
  color: var(--on-dark); border-color: var(--hero-btn-line); background: transparent;
  transition: background-color 0.35s ease, border-color 0.35s ease, color 0.35s ease;
}
.nav-cta:hover { border-color: var(--hero-btn-line-hover); background: var(--hero-btn-wash-hover); }

.nav-toggle {
  display: none; width: 44px; height: 44px; margin-right: -10px;
  align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: var(--r-s);
  background: transparent; color: inherit; cursor: pointer;
  transition: color 0.35s ease;
}
.nav-toggle svg { width: 24px; height: 24px; }
.nav-toggle .bar { transform-origin: 12px 12px; transition: transform 0.25s ease, opacity 0.2s ease; }
.nav.is-open .nav-toggle .bar-1 { transform: rotate(45deg) translateY(6px); }
.nav.is-open .nav-toggle .bar-2 { opacity: 0; }
.nav.is-open .nav-toggle .bar-3 { transform: rotate(-45deg) translateY(-6px); }

/* Scrolled past the hero, or a page without a hero (.nav--solid): white bar */
.nav.is-scrolled, .nav.nav--solid { background: var(--paper); border-bottom-color: var(--line); color: var(--ink); }
.nav.is-scrolled .mark-light, .nav.nav--solid .mark-light { opacity: 0; }
.nav.is-scrolled .mark-ink, .nav.nav--solid .mark-ink { opacity: 1; }
.nav.is-scrolled .brand-word, .nav.nav--solid .brand-word { color: var(--logo-blue); }
.nav.is-scrolled .nav-links a, .nav.nav--solid .nav-links a { color: var(--ink-soft); }
.nav.is-scrolled .nav-links a:hover,
.nav.is-scrolled .nav-links a.is-active,
.nav.is-scrolled:not(.spy-on) .nav-links a[aria-current="page"],
.nav.nav--solid .nav-links a:hover,
.nav.nav--solid .nav-links a.is-active,
.nav.nav--solid:not(.spy-on) .nav-links a[aria-current="page"] { color: var(--ink); }
.nav.is-scrolled .nav-links a::after, .nav.nav--solid .nav-links a::after,
.nav.is-scrolled:not(.spy-on) .nav-links a[aria-current="page"]::after,
.nav.nav--solid:not(.spy-on) .nav-links a[aria-current="page"]::after { background: var(--brand-teal); }
.nav.is-scrolled .nav-cta, .nav.nav--solid .nav-cta { background: var(--brand-deep); border-color: transparent; color: var(--on-dark); }
.nav.is-scrolled .nav-cta:hover, .nav.nav--solid .nav-cta:hover { background: var(--dark-2); }

@media (max-width: 900px) {
  .nav-toggle { display: inline-flex; }
  .nav-menu {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: 6px var(--gutter) 22px;
    background: var(--dark-0); border-bottom: 1px solid var(--line-dark);
    visibility: hidden; opacity: 0; transform: translateY(-8px);
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s linear 0.25s;
  }
  .nav.is-open .nav-menu {
    visibility: visible; opacity: 1; transform: none;
    transition: opacity 0.25s ease, transform 0.25s ease, visibility 0s;
  }
  .nav.is-open { background: var(--dark-0); }
  .nav.is-scrolled.is-open, .nav.is-scrolled .nav-menu,
  .nav.nav--solid.is-open, .nav.nav--solid .nav-menu { background: var(--paper); }
  .nav.is-scrolled .nav-menu, .nav.nav--solid .nav-menu { border-bottom-color: var(--line); }
  .nav-links { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-links li { border-bottom: 1px solid rgba(255, 255, 255, 0.08); }
  .nav.is-scrolled .nav-links li, .nav.nav--solid .nav-links li { border-bottom-color: var(--line); }
  .nav-links a { padding-block: 15px; }
  .nav-links a.is-active::after,
  .nav:not(.spy-on) .nav-links a[aria-current="page"]::after { right: auto; width: 24px; bottom: 8px; }
  .nav-cta { margin-top: 18px; padding: 14px 18px; }
}
@media (max-width: 760px) {
  :root { --nav-h: 64px; }
}

/* ---------------------------------------------------------------
   5. Hero: v3.2 video loop under a flat tint, recognition bar at foot
   --------------------------------------------------------------- */
.hero {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  /* the full viewport: the fixed bar sits over the top --nav-h */
  min-height: 100vh;
  min-height: 100svh;
  padding-top: var(--nav-h); box-sizing: border-box;
  background: var(--dark-0); color: var(--on-dark);
}
.hero-media, .hero-video, .hero-cover, .hero-tint { position: absolute; inset: 0; }
.hero-video { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
/* Loading backdrop: the poster, shown until the loop is playing, then
   faded out by js/site.js. Under the tint, so text contrast never depends on it. */
.hero-cover {
  background: var(--dark-0) url("../images/landing-background.webp") center / cover no-repeat;
  opacity: 1; transition: opacity 1.2s ease; pointer-events: none;
}
.hero-cover.is-clear { opacity: 0; }
/* The v3.2 tint: --dark-0 at 80% over the footage */
.hero-tint { background: color-mix(in srgb, var(--dark-0) 80%, transparent); }

.hero-inner {
  position: relative; z-index: 1;
  margin: auto; width: 100%; max-width: var(--w-content); box-sizing: border-box;
  padding: var(--s-24) var(--gutter) var(--s-16);
  text-align: center;
}
/* The page's only eyebrow (the v4.0 hero eyebrow). One of the two v3.2
   exceptions to the label tokens (the other is the hero button's
   13.5px / 0.07em, now the house .btn). v3.2 had none: size
   and tracking stay, the colour is the v3.2 palette's --teal-light and
   the gap below is the hero rhythm's first step (update 1). */
.hero-eyebrow {
  font: 600 var(--t-16)/1.4 var(--font-body); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--on-dark); margin-bottom: var(--hero-brand-gap); /* white since update 5 (was --teal-light) */
}
/* Headline: the v3.2 .hero-title (update 4, 2026-10-18). Two sentences on
   two lines. Colours swapped 2026-10-18 (update 5): the first line is the
   only teal in the hero, the second line and everything else white.
   Weight 500 is the v3.2 value: the one display setting not at 400.
   Gaps: the hero rhythm tokens (update 1), 20 / 32 / 40 down the stack. */
.hero h1 {
  font: 500 var(--t-display)/var(--lh-hero-title) var(--font-display);
  letter-spacing: -0.01em; color: var(--teal-light); text-wrap: balance;
  margin: var(--hero-title-gap-top) 0 var(--hero-title-gap-bottom);
}
/* Second line upright and white (owner, 2026-10-18). */
.hero h1 em { font-style: normal; color: var(--on-dark); }
/* Service list under the headline (owner, 2026-10-16): one wrapping row,
   items never break, teal dot between items. Type and colour are the
   v3.2 .hero-sub's (update 4), the gap to the button the hero rhythm's
   (update 1); rows sit at the
   paragraph's line-height, no extra gap. Not the v3.2 660px max-width:
   the second row is 683px at 17px, so the cap would wrap its last item
   onto a third line that starts with a dot. The forced break sets the
   width instead. */
.hero-services {
  display: flex; flex-wrap: wrap; justify-content: center; row-gap: 0;
  margin: 0 auto var(--hero-sub-gap);
  font: 400 var(--t-hero-sub)/var(--lh-hero-sub) var(--font-body); color: var(--on-dark); /* white since update 5 (was --hero-sub-c) */
}
.hero-services li { white-space: nowrap; }
.hero-services li + li::before { content: "\00B7"; color: var(--teal-light); margin: 0 var(--s-3); font-weight: 700; }
/* .row-break forces the second line so no dot ever ends a line */
.hero-services .row-break { flex-basis: 100%; height: 0; }
.hero-services .row-break::before, .hero-services .row-break + li::before { content: none; margin: 0; }
@media (max-width: 759px) {
  .hero-services li { flex-basis: 100%; }
  .hero-services li + li::before { content: none; margin: 0; }
}
@media (max-width: 600px) {
  .hero-services { font-size: var(--t-hero-sub-phone); }
  .hero { --hero-brand-gap: var(--s-4); --hero-title-gap-bottom: var(--s-6); --hero-sub-gap: var(--s-8); }
}
.hero-ctas { display: flex; gap: var(--s-3); justify-content: center; flex-wrap: wrap; }
/* "Learn more": the house .btn .btn-ghost on dark (v3.5; the v3.2 hero
   ghost became the family). Below 600px it keeps the v3.2 phone width. */
@media (max-width: 600px) {
  .hero .btn { width: var(--hero-btn-w-phone); box-sizing: border-box; }
}

/* Recognition bar: one hairline frame, no wash, no glow (06b). Each
   .award is self-contained: delete one element and the bar stays centred.
   Update 6 (2026-10-18): the bar is about a quarter larger (chip, type,
   padding and gap); below 560px it keeps the compact sizes. */
.recog { position: relative; z-index: 1; padding: 0 var(--gutter) var(--s-12); }
.recog-bar {
  display: flex; align-items: stretch; justify-content: center;
  width: fit-content; max-width: 100%; margin-inline: auto; box-sizing: border-box;
  border: 1px solid var(--line-dark); border-radius: var(--r-m);
  text-align: left;
}
.award { display: flex; align-items: center; gap: var(--s-5); padding: var(--s-5) var(--s-8); min-width: 0; }
.award + .award { border-left: 1px solid var(--line-dark); }
.award .chip {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: calc(var(--s-32) + var(--s-16)); height: var(--s-16);
  background: var(--paper); border-radius: var(--r-s);
  padding: var(--s-1) var(--s-2); box-sizing: border-box;
}
.award .chip img { max-width: 100%; max-height: 100%; width: auto; height: auto; }
.award .meta { display: grid; line-height: var(--lh-snug); }
.award .kind { font-size: var(--t-14); font-weight: 600; color: var(--on-dark-mute); }
/* "Winner" is Fraunces italic in --on-dark (brief, section 2) */
.award .kind.win { font: italic 400 var(--t-16)/var(--lh-snug) var(--font-display); color: var(--on-dark); }
.award .name { font-size: var(--t-16); font-weight: 600; color: var(--on-dark); }
.award .org { font-size: var(--t-14); color: var(--on-dark-mute); }

@media (max-width: 760px) {
  .recog-bar { flex-direction: column; width: 100%; max-width: 420px; }
  .award + .award { border-left: 0; border-top: 1px solid var(--line-dark); }
}
@media (max-width: 560px) {
  .hero-inner { padding-top: var(--s-16); padding-bottom: var(--s-12); }
  .award { gap: var(--s-4); padding: var(--s-3) var(--s-4); }
  .award .chip { width: calc(var(--s-24) + var(--s-6)); height: var(--s-12); }
  .award .kind, .award .org { font-size: var(--t-12); }
  .award .kind.win, .award .name { font-size: var(--t-14); }
}

/* ---------------------------------------------------------------
   6a. Services (ex What we do for your fund, ex What funds use us for): Uses B, by audience (owner's pick,
   2026-10-18, lifted from Claude/Sections). Five audiences and
   eighteen service lines since v3.5 update 3. Without JS the five
   audiences stack with their services below. site.js module 7 adds
   .is-tabs (desktop: vertical tablist 3/12, panel 9/12 (v3.6, from 5
   and 7) set as a two-column grid of services; since v3.5
   update 4 the panel area is as tall as the open panel, never shorter
   than the tablist, and its height animates on a switch) or .is-acc (below
   760px: accordion, one open at a time). Rules (12a): the frame's top
   and bottom hairlines (.rule-x on .ub-frame), the vertical divider
   (.rule-y on .ub-panels, added by site.js) and the accordion's row
   hairlines (.rule-x on .ub-item) draw in; the hairline between two
   uses in a panel (between rows in the desktop grid) is static.
   Type (v3.6): tabs 20, service headings 24, descriptions 16, links 14.
   --------------------------------------------------------------- */
.uses .ub-frame {
  --rule-c: var(--line-strong); /* the rules draw-in (section 12a) */
  border-top: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong);
}
.uses .ub-head { font: inherit; margin: 0; }
.uses .ub-tab {
  position: relative; display: block; width: 100%; text-align: left;
  font: 400 var(--t-20)/var(--lh-snug) var(--font-display); color: var(--ink);
  background: none; border: 0; margin: 0; cursor: default;
  padding: var(--s-3) var(--s-6);
}
.uses .ub-tab::before {
  content: ""; position: absolute; left: 0; top: var(--s-3); bottom: var(--s-3);
  width: 2px; background: var(--brand-teal);
  transform: scaleY(0); transition: transform 200ms ease;
}
.uses .ub-tab:focus-visible { outline-offset: -2px; }
.uses .ub-panel { padding: 0 var(--s-6) var(--s-6); }
.uses .ub-item + .ub-item { border-top: 1px solid var(--line); }
.uses .ub-use + .ub-use { border-top: 1px solid var(--line); margin-top: var(--s-8); padding-top: var(--s-8); }
.uses .ub-what { font: 400 var(--t-24)/var(--lh-snug) var(--font-display); color: var(--ink); text-wrap: balance; }
.uses .ub-lead { font-size: var(--t-16); color: var(--ink-soft); max-width: var(--w-prose); margin-top: var(--s-2); text-wrap: pretty; }
.uses .ub-more { margin-top: var(--s-3); }
.uses .ub-more .link { font-size: var(--t-14); }

/* Enhanced, both modes: the tabs are real controls */
.uses .ub-frame.is-tabs .ub-tab, .uses .ub-frame.is-acc .ub-tab {
  cursor: pointer; color: var(--ink-mute); transition: color 200ms ease;
}
.uses .ub-frame.is-tabs .ub-tab:hover, .uses .ub-frame.is-acc .ub-tab:hover,
.uses .ub-frame .ub-tab[aria-selected="true"], .uses .ub-frame .ub-tab[aria-expanded="true"] { color: var(--ink); }
.uses .ub-tab[aria-selected="true"]::before, .uses .ub-tab[aria-expanded="true"]::before { transform: scaleY(1); }

/* Desktop: tablist left, panels right. Only the open panel is in flow
   (v3.5 update 4), so the panel area, and with it the frame and its
   hairlines, is as tall as the open panel; the grid row keeps it at
   least as tall as the tablist. The inactive panels sit out of flow at
   the top of the area while they fade out. On a switch site.js module
   7 fixes the area's height, swaps the panel and transitions the height
   to the new panel's (.is-sizing, 320ms), then clears it, so resize and
   reflow stay natural. During the transition the area clips its
   content (clip-path, 2px spare on the left for the drawn divider,
   which sits at -1px), so neither the taller incoming panel nor the
   outgoing one spills over the bottom hairline. Instant under reduced
   motion (site.js skips the transition). */
.uses .ub-frame.is-tabs { display: grid; grid-template-columns: 3fr 9fr; }
/* Natural height (not stretched), so site.js can read it as the floor */
.uses .ub-tabs { padding-block: var(--s-6); align-self: start; }
.uses .ub-panels { display: grid; position: relative; border-left: 1px solid var(--line-strong); }
.uses .ub-panels.is-sizing {
  transition: height 320ms cubic-bezier(0.2, 0.7, 0.2, 1);
  clip-path: inset(0 0 0 -2px);
}
.uses .is-tabs .ub-panel {
  position: absolute; top: 0; left: 0; right: 0;
  padding: var(--s-6) var(--s-8);
  opacity: 0; visibility: hidden; transform: none;
  transition: opacity 100ms ease, visibility 0s linear 100ms;
}
.uses .is-tabs .ub-panel.is-active {
  position: static; grid-area: 1 / 1; align-self: start;
  opacity: 1; visibility: visible;
  animation: ub-rise 240ms cubic-bezier(0.2, 0.7, 0.2, 1) 80ms both;
  transition: none;
}
.uses .is-tabs .ub-panel.is-instant { animation: none; }
/* The open panel's services in two columns (v3.6): the hairline runs
   above each item from the second row on, never between the columns;
   the row gap and the item's top padding put it midway */
.uses .is-tabs .ub-panel {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--s-8); row-gap: var(--s-6); align-content: start;
}
.uses .is-tabs .ub-use + .ub-use { border-top: 0; margin-top: 0; padding-top: 0; }
.uses .is-tabs .ub-use:nth-child(n+3) { border-top: 1px solid var(--line); padding-top: var(--s-6); }
/* The links of a row share one line: each item fills its row and the
   link takes the slack above it */
.uses .is-tabs .ub-use { display: flex; flex-direction: column; }
.uses .is-tabs .ub-more { margin-top: auto; padding-top: var(--s-3); }
@keyframes ub-rise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* Phone: accordion, one open at a time */
/* --s-2 on top (v3.6): with the tab's padding at --s-3 the first
   heading sat tight under the open tab */
.uses .is-acc .ub-panel { padding: var(--s-2) var(--s-6) var(--s-8); }
.uses .is-acc .ub-panel:not([hidden]) { animation: ub-rise 240ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.uses .is-acc .ub-item + .ub-item { border-top-color: var(--line-strong); }
@media (prefers-reduced-motion: reduce) {
  .uses .is-tabs .ub-panel, .uses .is-tabs .ub-panel.is-active, .uses .is-acc .ub-panel:not([hidden]) {
    animation: none; transition: none;
  }
}

/* ---------------------------------------------------------------
   6b. How it works (section id "services"): the ledger, on the dark
   band, two lists (You bring, We run; owner, update 5, 2026-10-18,
   removed You focus on), one line per row. The map (6c) draws it at 821px and up. Columns are grid items of equal
   height, so the hairlines run the full height of the longest column.
   --------------------------------------------------------------- */
.ledger { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto 1fr; }
.ledger-col {
  display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0;
  padding-inline: var(--s-12);
  border-left: 1px solid var(--line-dark);
}
.ledger-col:first-child { border-left: 0; padding-left: 0; }
.ledger-col:last-child { padding-right: 0; }
.ledger-col h3 { font-size: var(--t-24); align-self: end; } /* v3.6: 24, below 32 so --lh-snug, no tracking */
/* If a group name wraps to two lines, the shorter names sit on its
   last line (align-self: end), so the two lists start level */
.ledger-col ul { margin-top: var(--s-8); align-self: start; border-top: 1px solid var(--line-dark); }
.ledger-col li { padding-block: var(--s-3); border-bottom: 1px solid var(--line-dark); }
.ledger-col li:last-child { border-bottom: 0; }
.svc-name { font-size: var(--t-16); font-weight: 500; line-height: var(--lh-snug); color: var(--on-dark); }
/* Closing line under the ledger: one line, the second sentence is the link */
.ledger-foot { text-align: center; margin-top: var(--s-12); font-size: var(--t-16); color: var(--on-dark-soft); text-wrap: balance; }
.ledger-foot .link { font-size: inherit; }
@media (max-width: 960px) {
  .ledger-col { padding-inline: var(--s-8); }
}
@media (max-width: 820px) {
  /* Shorter band on phones: compact padding, groups stacked */
  .services-band { padding-block: var(--section-pad-compact); }
  .services-band .sh { margin-bottom: var(--s-8); }
  .ledger { grid-template-columns: 1fr; grid-template-rows: none; border-bottom: 1px solid var(--line-dark); }
  .ledger-col, .ledger-col:first-child, .ledger-col:last-child {
    display: block; grid-row: auto; border-left: 0; padding: var(--s-6) 0;
    border-top: 1px solid var(--line-dark);
  }
  .ledger-col ul { margin-top: var(--s-4); }
  .ledger-foot { margin-top: var(--s-8); }
}

/* ---------------------------------------------------------------
   6c. How it works: the stack map (ported from the motion lab, map-text
   variant, brief Claude/DESIGN_v3.4-motion-2026-10-17.md, reworded by
   Claude/DESIGN_v3.4-motion-2026-10-18.md and, to the owner's three
   lists, by Claude/DESIGN_v3.4-update-2026-10-18b.md, to two columns
   by Claude/DESIGN_v3.4-update-2026-10-18c.md, and a fourth We run
   name by Claude/DESIGN_v3.4-update-2026-10-18d.md). js/site.js builds
   the SVG into figure.stack-map: column labels (You bring, We run),
   three Fraunces nodes on the left centred on four on the right, six
   hairline wires, ports and one
   travelling dot per wire (6s cycle, phases spread by negative
   delays). The viewBox is set from the measured names, so the SVG is
   drawn at 1:1 (its width attribute) and centred, never scaled up;
   max-width shrinks it in a narrower container.
   The map replaces the ledger on screen: once it is drawn (821px and
   up) the ledger is visually hidden but stays the accessible text, so
   screen readers get the two lists; the figure is aria-hidden.
   Empty without JS, so it takes no space and the ledger shows; hidden
   below 820px, where the ledger shows too. The dots pause while the
   figure is off screen (.is-idle).
   --------------------------------------------------------------- */
.stack-map { margin: 0 auto var(--s-12); max-width: 1100px; }
.stack-map:empty { display: none; }
/* With the map drawn the band takes the compact band padding (as it
   already does below 820px): 568px at 1440 with the two-column map
   (v3.6: 20px names at pitch 56, 814 x 321), 566px for the no-JS
   ledger at the standard padding (v3.5: 695 and 635).
   The ledger is visually hidden (the .visually-hidden pattern), so the
   closing line follows the map. */
@media (min-width: 821px) {
  .services-band:has(.stack-map:not(:empty)) { padding-block: var(--section-pad-compact); }
  .services-band:has(.stack-map:not(:empty)) .ledger {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}
.stack-map svg { display: block; margin-inline: auto; max-width: 100%; height: auto; overflow: visible; }
.stack-map .sm-col {
  font: 600 var(--t-label)/1 var(--font-body);
  letter-spacing: var(--track-label); text-transform: uppercase;
  fill: var(--on-dark-mute);
}
.stack-map .sm-node text { fill: var(--on-dark-soft); }
.stack-map .sm-node--core text { fill: var(--on-dark); }
.stack-map .sm-wire {
  fill: none; stroke: var(--line-dark); stroke-width: 1;
  vector-effect: non-scaling-stroke;
}
.stack-map .sm-port { fill: var(--teal-light); opacity: 0.45; }
.stack-map .sm-pulse {
  fill: none;
  stroke: var(--teal-light);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 0.01 99.99;
  stroke-dashoffset: 100;
  opacity: 0;
  filter: drop-shadow(0 0 var(--s-1) var(--teal-light));
  animation: sm-wire-pulse 6s linear infinite;
  animation-delay: var(--d, 0s);
}
.stack-map.is-idle .sm-pulse { animation-play-state: paused; }
@keyframes sm-wire-pulse {
  0% { stroke-dashoffset: 100; opacity: 0; }
  6% { opacity: 1; }
  40% { opacity: 1; }
  46% { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 0; opacity: 0; }
}
@media (max-width: 820px) {
  .stack-map { display: none; }
}

/* Entrance (the v4.0 reveal), only for the How it works header and the map:
   18px rise and fade, once, when each enters the viewport (js/site.js
   adds .is-visible); the map follows the header by 120ms. The html "js"
   class is set by js/site.js, so without JS both are simply visible. */
.js .services-band .sh,
.js .stack-map {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.7s cubic-bezier(0.2, 0.7, 0.3, 1),
    transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.js .stack-map { transition-delay: 120ms; }
.js .services-band .sh.is-visible,
.js .stack-map.is-visible { opacity: 1; transform: none; }

/* Reduced motion: a static diagram (no dots) and no entrance */
@media (prefers-reduced-motion: reduce) {
  .stack-map .sm-pulse { display: none; }
  .js .services-band .sh,
  .js .stack-map { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------------
   7. Window frame (05 A): the dark product frame with its title bar
   and three dots. No longer on the home page (update 5 removed Why
   funds choose us), kept for the sub-pages and the product frame
   component.
   --------------------------------------------------------------- */
.win { margin: 0; min-width: 0; }
.win-frame {
  background: var(--dark-0);
  border: 1px solid var(--dark-2);
  border-radius: var(--r-m);
  box-shadow: var(--shadow-frame);
  overflow: hidden;
}
.win-bar {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-2) var(--s-4);
  background: var(--dark-1);
  border-bottom: 1px solid var(--line-dark);
}
.win-dots { display: flex; gap: var(--s-2); flex: none; }
.win-dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--brand-deep); }
.win-label { font-size: var(--t-12); color: var(--on-dark-mute); letter-spacing: 0.02em; }
.win-body img { width: 100%; }
@media (max-width: 760px) {
  .win-bar { padding: var(--s-2) var(--s-3); }
}

/* ---------------------------------------------------------------
   8. Why AlgoTraders: Why5 B, the ledger (owner's pick, 2026-10-18;
   study Claude/Why5, brief Claude/WHY5.md; before it Why4 A, the same
   rows without the label column). White band, the house header, then
   four ruled rows of three columns on the first baseline: a tracked
   uppercase label (2/12, the map's column-label setting in
   --brand-deep), the heading in Fraunces at --t-24 (4/12, at most
   30ch) and its sentence at 16 (6/12, 46ch); column gap --s-10, rows
   --s-6 apart. Hairline --line-strong above the first row and below
   each; every row is .rule-x, so all five draw in (12a). Below 820px
   the three parts stack, below 600px the heading drops to 20. .fig is the
   shared figure face, used by the Case studies metrics (section 11).
   --------------------------------------------------------------- */
.fig { font-family: var(--font-display); font-weight: 400; line-height: var(--lh-tight); font-variant-numeric: lining-nums; color: var(--on-dark); }
.why .wa-row {
  --rule-c: var(--line-strong); /* the rules draw-in (section 12a) */
  display: grid; grid-template-columns: 2fr 4fr 6fr; column-gap: var(--s-10);
  align-items: first baseline;
  padding-block: var(--s-6);
  border-bottom: 1px solid var(--line-strong);
}
/* The top hairline sits on the first row, not the list, so it draws in too */
.why .wa-row:first-child { border-top: 1px solid var(--line-strong); }
/* The label column (Why5 B, 2026-10-18): the map's column-label setting
   (.sm-col) in --brand-deep on white */
.why .wa-label {
  font: 600 var(--t-label)/var(--lh-snug) var(--font-body);
  letter-spacing: var(--track-label); text-transform: uppercase; color: var(--brand-deep);
}
.why .wa-head {
  font: 400 var(--t-24)/var(--lh-snug) var(--font-display); color: var(--ink);
  text-wrap: balance; max-width: 30ch;
}
.why .wa-text {
  font-size: var(--t-16); line-height: var(--lh-body); color: var(--ink-soft);
  max-width: 46ch; text-wrap: pretty;
}
.why .wa-foot { text-align: center; margin-top: var(--s-8); }
@media (max-width: 820px) {
  .why .wa-row { grid-template-columns: 1fr; row-gap: var(--s-2); padding-block: var(--s-6); }
  .why .wa-text { margin-top: var(--s-1); }
}
@media (max-width: 600px) {
  .why .wa-head { font-size: var(--t-20); }
}

/* ---------------------------------------------------------------
   9. Get in touch (ex Start with a confidential review): the v3.2 "Request a call"
   form (update 2, 2026-10-18), ported to the v3.5 tokens and, since
   update 3 (same day, owner: the home must alternate), set on the dark
   review band (.review-band, flat --dark-1, below), so every rule here
   is written for dark; the form is used nowhere else. The house
   header, then the form at --w-narrow (760px, as v3.2), centred as a
   block, text left: two steps (.comp-step) each closed by a
   --line-dark hairline, an uppercase
   question row (.comp-q) with the live "0 / 50 min" counter, three
   placeholder-only inputs (visually hidden labels), a textarea, and
   the foot: note left, Send right. Send is disabled until the form is
   valid; hover or focus on its wrapper shows the "Before you can
   send:" tooltip, inverted on this band (white, --ink) (js/site.js
   module 4). Text tokens are --on-dark, --on-dark-soft, --on-dark-mute
   and --teal-light; errors use --alert-on-dark.
   --------------------------------------------------------------- */
/* Header to form: --s-8 at every width (v3.6, from --s-12) */
.review .sh { margin-bottom: var(--s-8); }
.form { max-width: var(--w-narrow); margin-inline: auto; position: relative; text-align: left; }
/* Honeypot: bots fill it, humans never see it */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form .comp-step { padding-block: var(--s-5); border-bottom: 1px solid var(--line-dark); }
.form .hp + .comp-step { padding-top: 0; }
.form .comp-q { display: flex; align-items: baseline; gap: var(--s-3); margin-bottom: var(--s-3); }
.form .comp-q .qt {
  font: 500 var(--t-14)/var(--lh-snug) var(--font-body);
  text-transform: uppercase; letter-spacing: var(--track-label); color: var(--teal-light);
}
.form .comp-q .qh { margin-left: auto; font-size: var(--t-12); color: var(--on-dark-mute); white-space: nowrap; }
.form .comp-q .qh.under { color: var(--alert-on-dark); }

.form .comp-fields { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: var(--s-3); }
.form .comp-input {
  display: block; width: 100%; box-sizing: border-box; margin: 0;
  padding: var(--s-3) 14px;
  border: 1px solid var(--on-dark-mute); border-radius: var(--r-s);
  background: var(--dark-0); color: var(--on-dark);
  font: 400 var(--t-14)/var(--lh-snug) var(--font-body);
  transition: border-color 160ms ease;
}
.form .comp-input::placeholder { color: var(--on-dark-mute); opacity: 1; }
.form .comp-input:focus { border-color: var(--teal-light); outline: 2px solid var(--teal-light); outline-offset: 2px; }
/* Browser autofill keeps the dark field instead of its pale wash */
.form .comp-input:-webkit-autofill {
  -webkit-text-fill-color: var(--on-dark);
  box-shadow: 0 0 0 100px var(--dark-0) inset; caret-color: var(--on-dark);
}
.form .comp-textarea { min-height: 90px; resize: vertical; line-height: var(--lh-body); }

.form .comp-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-4); margin-top: var(--s-6);
}
.form .comp-foot .note { font-size: var(--t-14); color: var(--on-dark-soft); max-width: 46ch; margin: 0; }
/* The tooltip anchors to the wrapper, which stays hoverable while the
   button is disabled */
.form .submit-wrap { position: relative; display: inline-block; }
/* Chrome drops mouse events on a disabled button (they never reach the
   wrapper), so the disabled button lets them through and the wrapper
   carries the cursor. Disabled before the form is valid it is a ghost
   (no opacity): transparent, --on-dark-mute hairline and text. In
   flight (aria-busy, "Sending...") it keeps the enabled look. */
.form .form-submit:disabled { pointer-events: none; }
.form .form-submit:disabled:not([aria-busy="true"]) { background: transparent; border-color: var(--on-dark-mute); color: var(--on-dark-mute); }
.form .submit-wrap:has(.form-submit:disabled) { cursor: not-allowed; }
.form .submit-wrap:has(.form-submit[aria-busy="true"]) { cursor: progress; }
/* "Before you can send:" tooltip, inverted on the dark band. The one
   shadow on the site: it floats. */
.form .submit-tip {
  position: absolute; right: 0; bottom: calc(100% + 11px); z-index: 5;
  width: max-content; max-width: 290px; padding: 11px 14px;
  border-radius: var(--r-m); background: var(--paper); color: var(--ink);
  font: 400 var(--t-14)/1.45 var(--font-body); text-align: left;
  box-shadow: 0 10px 28px rgba(0, 23, 31, 0.28);
}
.form .submit-tip[hidden] { display: none; }
.form .submit-tip::after {
  content: ""; position: absolute; top: 100%; right: 30px;
  border: 6px solid transparent; border-top-color: var(--paper);
}
.form .submit-tip .tip-head { display: block; margin-bottom: 6px; font-weight: 600; }
.form .submit-tip ul { margin: 0; padding-left: 17px; list-style: disc; }
.form .submit-tip li { margin: 3px 0; }

.form-error { flex: 1 1 100%; margin: 0; font-size: var(--t-14); color: var(--alert-on-dark); }
.form-error a { color: var(--alert-on-dark); text-decoration: underline; text-decoration-color: var(--alert-on-dark); text-underline-offset: 3px; }

/* Shown in place of the form after a successful send */
.form-success { text-align: center; padding-block: var(--s-8); border-top: 1px solid var(--line-dark); border-bottom: 1px solid var(--line-dark); }
.form-success h3 { font-size: var(--t-24); color: var(--on-dark); }
.form-success p { margin-top: var(--s-3); font-size: var(--t-18); color: var(--on-dark-soft); }

@media (max-width: 760px) {
  .form .comp-fields { grid-template-columns: 1fr; }
  /* 16px fields: iOS zooms into any focused field below 16px (v3.2) */
  .form .comp-input { font-size: var(--t-16); }
  .form .comp-foot { flex-direction: column-reverse; align-items: stretch; }
  .form .submit-wrap { display: block; }
  .form .form-submit { width: 100%; box-sizing: border-box; }
}

/* The review band on the alternate dark (home #contact, and the
   sub-pages' closing band, .cta-band, section 11): flat --dark-1 on
   purpose, not .band-dark (flat --dark-0 since v3.5), so it reads as a
   second, distinct dark band. Contacts below it is white. Text is
   --on-dark or --on-dark-soft, AA on --dark-1; the primary is the
   on-dark one (--teal-light, section 3). */
.review-band { background: var(--dark-1); color: var(--on-dark); color-scheme: dark; }
.review-band .sh-title { color: var(--on-dark); }
.review-band .sh-lead { color: var(--on-dark-soft); }

/* ---------------------------------------------------------------
   10. Contacts: the v3.2 band, restyled, with the legal lines. On
   white (update 1, 2026-10-18). It follows the dark review band on
   every page (again since update 3), so no hairline on top.
   Titles --ink, marks --brand-deep, hover --brand-teal; the focus ring
   is the default --brand-teal.
   --------------------------------------------------------------- */
.contacts { padding-block: var(--section-pad-compact); background: var(--paper); color: var(--ink); }
.contacts .sh { margin-bottom: var(--s-8); }
.contact-items { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-6) var(--s-16); }
.contact-item {
  display: inline-flex; align-items: center; gap: var(--s-4);
  padding: var(--s-2); color: var(--brand-deep); text-decoration: none;
  transition: color 160ms ease;
}
/* 40px marks (v3.5, from 56) beside the 20px titles (v3.6, from 24) */
.contact-item svg { width: 40px; height: 40px; flex: none; }
.contact-item .label { display: grid; text-align: left; }
.contact-item .title { font: 400 var(--t-20)/var(--lh-snug) var(--font-display); color: var(--ink); transition: color 160ms ease; }
.contact-item .sub { font-size: var(--t-14); }
a.contact-item:hover, a.contact-item:hover .title { color: var(--brand-teal); }
.contact-item.is-pending, .contact-item.is-pending .title { color: var(--ink-mute); }
.legal {
  margin-top: var(--s-12); padding-top: var(--s-8);
  border-top: 1px solid var(--line);
  display: grid; gap: var(--s-2);
  text-align: center; font-size: var(--t-14); color: var(--ink-mute);
}
.legal a { color: inherit; text-underline-offset: 3px; }
.legal a:hover { color: var(--ink); }
@media (max-width: 600px) {
  .contact-items { flex-direction: column; align-items: center; gap: var(--s-4); }
  .contact-item { width: calc(var(--s-32) * 2); }
}


/* ---------------------------------------------------------------
   11. Sub-pages (Case studies, Team): page header, tinted bands, the
   case study layout, the closing review band
   --------------------------------------------------------------- */
/* Dark page header under the solid bar */
.page-head {
  padding-top: calc(var(--nav-h) + var(--section-pad));
  padding-bottom: var(--section-pad);
  text-align: center;
}
/* Page titles at --t-40 over the 32 section titles (v3.6) */
.page-head h1 { font-size: var(--t-40); line-height: var(--lh-tight); letter-spacing: -0.01em; color: var(--on-dark); }
.page-lead {
  font-size: var(--t-18); color: var(--on-dark-soft);
  max-width: 60ch; margin: var(--s-6) auto 0; text-wrap: balance;
}
/* The lightest tint the tokens give, for alternating bands */
.band-tint { background: var(--teal-wash); }
/* Two white bands in a row: a hairline marks the seam */
.section.seam { border-top: 1px solid var(--line); }

/* Case studies page: jump links under the page header */
.cs-jump { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-3) var(--s-8); margin-top: var(--s-8); }
.cs-jump a {
  font: 600 var(--t-16)/var(--lh-snug) var(--font-body); color: var(--on-dark-soft);
  text-decoration: underline; text-decoration-color: var(--line-dark);
  text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.cs-jump a:hover { color: var(--on-dark); text-decoration-color: currentColor; }

/* One study: title, lead, three columns split by hairlines, metrics row */
.study-title { font-size: var(--t-32); line-height: var(--lh-tight); letter-spacing: -0.01em; color: var(--ink); }
.study-lead { font-size: var(--t-18); color: var(--ink-soft); max-width: var(--w-prose); margin-top: var(--s-4); }
.study-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: var(--s-12); }
.study-cols > div { padding-inline: var(--s-8); border-left: 1px solid var(--line-strong); }
.study-cols > div:first-child { border-left: 0; padding-left: 0; }
.study-cols > div:last-child { padding-right: 0; }
.study-cols h3 { font-size: var(--t-24); color: var(--ink); }
.study-cols p, .study-cols ul { font-size: var(--t-16); color: var(--ink); margin-top: var(--s-3); }
.study-cols p + p { margin-top: var(--s-3); }
.study-cols ul { list-style: disc; padding-left: var(--s-4); }
.study-cols li::marker { color: var(--brand-teal); }
.study-cols li + li { margin-top: var(--s-2); }
@media (max-width: 820px) {
  .study-cols { grid-template-columns: 1fr; margin-top: var(--s-8); }
  .study-cols > div, .study-cols > div:first-child, .study-cols > div:last-child { padding: var(--s-6) 0; border-left: 0; }
  .study-cols > div:first-child { padding-top: 0; }
  .study-cols > div + div { border-top: 1px solid var(--line-strong); }
}
/* Metrics: the Why figures component on light */
.metrics {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: var(--s-12);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.metrics > div { padding: var(--s-8); border-left: 1px solid var(--line); }
.metrics > div:first-child { border-left: 0; padding-left: 0; }
.metrics .fig { font-size: var(--t-32); letter-spacing: -0.01em; color: var(--ink); }
.metrics p { font-size: var(--t-16); color: var(--ink-soft); margin-top: var(--s-3); max-width: 26ch; }
@media (max-width: 860px) {
  .metrics > div { padding: var(--s-6) var(--s-4); }
  .metrics > div:first-child { padding-left: 0; }
  .metrics .fig { font-size: var(--t-24); line-height: var(--lh-snug); letter-spacing: 0; }
}
@media (max-width: 559px) {
  .metrics { grid-template-columns: 1fr; margin-top: var(--s-8); }
  .metrics > div, .metrics > div:first-child { padding: var(--s-4) 0; border-left: 0; }
  .metrics > div + div { border-top: 1px solid var(--line); }
}

/* Closing review band on the sub-pages: header A, one line, the button,
   on the review band's --dark-1 (.review-band, section 9; update 1) */
.cta-band .sh { margin-bottom: var(--s-8); }
.cta-band .sh-lead { margin-top: var(--s-3); }
.cta-band .cta-row { text-align: center; }

/* Team page: three open cards, no boxes */
.team-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-12); }
.member { display: flex; flex-direction: column; align-items: center; text-align: center; }
.member-photo {
  width: 160px; height: 160px; border-radius: 50%; overflow: hidden;
  background: var(--teal-wash); flex: none;
}
.member-photo img { width: 100%; height: 100%; object-fit: cover; }
.member h3 { font-size: var(--t-24); color: var(--ink); margin-top: var(--s-6); }
.member-role { color: var(--ink-soft); margin-top: var(--s-1); }
.member-bio { font-size: var(--t-16); color: var(--ink); margin-top: var(--s-4); max-width: 44ch; }
.member-press { margin-top: var(--s-4); }
.member-press .link, .member-in .link { font-size: var(--t-14); }
.member-tags { font-size: var(--t-14); color: var(--ink-soft); margin-top: var(--s-4); }
.member-in { margin-top: var(--s-3); }
@media (max-width: 820px) {
  .team-grid { grid-template-columns: 1fr; gap: var(--s-16); max-width: 520px; margin-inline: auto; }
}

/* Join us: a simple white band with a text link */
.join { text-align: center; }
.join .sh { margin-bottom: var(--s-6); }
.join p { font-size: var(--t-18); color: var(--ink-soft); max-width: 60ch; margin: 0 auto var(--s-6); }

/* Programmatic focus targets (skip link, in-page jumps) take focus without a ring */
[tabindex="-1"]:focus { outline: none; }

/* ---------------------------------------------------------------
   12. Motion: rules and parallax (owner's picks from motion lab 2,
   brief Claude/DESIGN_v3.4-motion-2026-10-18.md). Both are off under
   reduced motion and without JS (the html "js" class).
   --------------------------------------------------------------- */

/* 12a. Rules: the hairlines of a ruled component draw in once when it
   enters the viewport (js/site.js module 8 adds .rules-in to the
   .rules root). Generic hooks, so the effect can be retargeted:
   .rule-x redraws the top border (::before) and, unless it is also
   .rule-y, the bottom border (::after), from the left; .rule-y redraws
   the left border (::after) from the top. Each pseudo-element inherits
   its edge from the host (border-top: inherit and so on), so an edge
   the host has no border on at that width stays 0 wide and draws
   nothing. The host's own edge turns transparent; --rule-c (set by the
   component) gives the colour. --rule-i (set by site.js: 0 for the
   root, then one step per sibling) staggers them 80ms apart. Without
   JS or under reduced motion the static borders stay. */
@media (prefers-reduced-motion: no-preference) {
  .js .rule-x, .js .rule-y { position: relative; }
  /* !important: the components set their borders per width with
     selectors of any weight (.uses .is-acc .ub-item + .ub-item); the host's edge must
     stay transparent at every width while the pseudo-element draws it */
  .js .rule-x { border-top-color: transparent !important; }
  .js .rule-x:not(.rule-y) { border-bottom-color: transparent !important; }
  .js .rule-y { border-left-color: transparent !important; }
  .js .rule-x::before,
  .js .rule-x:not(.rule-y)::after,
  .js .rule-y::after {
    content: ""; position: absolute; pointer-events: none;
    transition: transform 600ms cubic-bezier(0.2, 0.7, 0.2, 1) calc(var(--rule-i, 0) * 80ms);
  }
  .js .rule-x::before {
    top: -1px; left: 0; right: 0;
    border-top: inherit; border-top-color: var(--rule-c, var(--line));
    transform: scaleX(0); transform-origin: left center;
  }
  .js .rule-x:not(.rule-y)::after {
    bottom: -1px; left: 0; right: 0;
    border-bottom: inherit; border-bottom-color: var(--rule-c, var(--line));
    transform: scaleX(0); transform-origin: left center;
  }
  .js .rule-y::after {
    top: 0; bottom: 0; left: -1px;
    border-left: inherit; border-left-color: var(--rule-c, var(--line));
    transform: scaleY(0); transform-origin: center top;
  }
  .js .rules-in.rule-x::before,
  .js .rules-in.rule-x::after,
  .js .rules-in .rule-x::before,
  .js .rules-in .rule-x::after,
  .js .rules-in .rule-y::after { transform: none; }
}

/* 12b. Parallax: from 821px up, the hero footage and its poster move at
   half the scroll speed and a --dark-0 layer (.hero-dusk, added by
   site.js module 9 inside .hero-media, over the tint) darkens it as the
   hero leaves the viewport. site.js writes the transform and opacity
   inline from one rAF loop; below 821px and under reduced motion it
   clears them, so the hero is as before. */
.hero-dusk { position: absolute; inset: 0; background: var(--dark-0); opacity: 0; pointer-events: none; }
@media (min-width: 821px) and (prefers-reduced-motion: no-preference) {
  .js .hero-media { will-change: transform; }
}
