/* --- ./foundation/reset.css --- */
*,*::before,*::after{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0}img,svg,video,canvas{max-width:100%;height:auto}a{color:inherit}button,input,textarea,select{font:inherit}:focus-visible{outline:2px solid var(--focus);outline-offset:3px}


/* --- ./shell/page.css --- */
html {
  -ms-overflow-style: none;
}

/* -----------------------------------------------------------------------------
   VIEW TRANSITIONS - one full-frame crossfade for page navigation and theme
   flips, so gradients, text, buttons, and the background all change at
   EXACTLY the same pace (the old per-property transitions left gradients
   snapping while solids faded - that was the choppy desync).
   -------------------------------------------------------------------------- */
@view-transition { navigation: auto; }
/* Standard browser crossfade (both directions). The one gotcha: the incoming
   page must be fully painted when it is snapshotted, or the crossfade fades to
   blank. On a view-transition navigation we reveal the incoming content
   immediately (see html.vt-nav below); first loads still play the load-in. */
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: .32s;
  animation-timing-function: ease;
}
.vt-theme::view-transition-old(root),
.vt-theme::view-transition-new(root) {
  animation-duration: .5s;
  animation-timing-function: ease;
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none; }
}
/* On a cross-document navigation the crossfade IS the entrance: show the incoming
   page instantly so its snapshot is complete and neither side flashes blank. */
html.vt-nav .site { opacity: 1 !important; transition: none !important; }
html.vt-nav .page-body > section { opacity: 1 !important; transform: none !important; transition: none !important; animation: none !important; }
html.vt-nav.js [data-pz] { opacity: 1 !important; transform: none !important; transition: none !important; animation: none !important; }
/* Main window scrollbar: themed + visible (light purple in dark, dark in light),
   no end arrows. */
html::-webkit-scrollbar,
body::-webkit-scrollbar { width: 6px; height: 6px; }
html::-webkit-scrollbar-button,
body::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track { background: transparent; }
html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb { background: rgba(156, 140, 255, .5); border-radius: 999px; }
html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover { background: rgba(156, 140, 255, .8); }


body {
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);        /* base site typeface (Helvetica Neue / Inter) */
  -webkit-font-smoothing: antialiased;
}

.site {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  background: transparent;   /* see .site-bg (grid + glow field) behind the content */
  color: var(--text);
}

/* No site-level fade: the native @view-transition crossfade is the page
   transition. Section + hero load-ins below still play on first load. */

/* Leaving: a quick fade that actually completes within the ~180ms before
   navigation, so it reads as a clean hand-off instead of a cut-off animation. */
.js.page-leaving .site {
  opacity: 0;
  transition: opacity .42s ease;
}

/* Section entrance -----------------------------------------------------------
   Sections are VISIBLE BY DEFAULT. The first-load entrance is an opt-in,
   run-once animation gated on html.enter (a static class set in <head>). This
   is deliberate: the old code hid every section (opacity:0) until JS flipped
   data-ready, so a cross-document view-transition could snapshot the incoming
   page mid-hide and crossfade to a blank frame - the "new page fades, then the
   content comes back" glitch. With visibility as the default, a snapshot (or a
   no-JS load) can never catch an empty page. On a view-transition navigation
   the pagereveal handler removes .enter (and adds .vt-nav) before the snapshot,
   so the native crossfade is the only entrance. */
@media (prefers-reduced-motion: no-preference) {
  html.enter.js .page-body > section {
    animation: sectionIn .6s ease both;
  }
  html.enter.js .page-body > section:nth-child(2) { animation-delay: .03s; }
  html.enter.js .page-body > section:nth-child(3) { animation-delay: .06s; }
  html.enter.js .page-body > section:nth-child(n+4) { animation-delay: .08s; }
}

@keyframes sectionIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.js.theme-transition,
.js.theme-transition body,
.js.theme-transition .site,
.js.theme-transition .site-header,
.js.theme-transition .drawer,
.js.theme-transition .scrim,
.js.theme-transition .site-bg,
.js.theme-transition .site-bg-grid,
.js.theme-transition .site-bg-glow,
.js.theme-transition .panel,
.js.theme-transition .cta-shine,
.js.theme-transition .btn,
.js.theme-transition .res-bar,
.js.theme-transition .ap-row,
.js.theme-transition .tm-card,
.js.theme-transition .tm-over,
.js.theme-transition .legal,
.js.theme-transition .glow {
  transition-duration: .32s !important;
  transition-timing-function: ease !important;
}

.js.theme-transition *,
.js.theme-transition *::before,
.js.theme-transition *::after {
  /* Recolor-only: transitioning filter/opacity/transform on every element made
     the theme flip stutter. Just the colour-bearing properties, and quick. */
  transition-property: background, background-color, border-color, box-shadow, color, fill, stroke !important;
  transition-duration: .32s !important;
  transition-timing-function: ease !important;
}

/* The blanket recolor above omits `transform`, which would freeze the theme
   toggle's sun/moon mid-swap. Let the icon keep its own springy spin timing
   (matches the .ti rule in frame.css) so it rotates in as the page recolors. */
.js.theme-transition .ti,
.js.theme-transition .ti svg {
  transition-property: transform, opacity !important;
  transition-duration: .42s !important;
  transition-timing-function: cubic-bezier(.5, 1.4, .4, 1) !important;
}

.js .site[data-ready="true"] .theme-btn .ti {
  animation: themeLoadSpin .72s cubic-bezier(.22, .8, .22, 1) both;
}

@keyframes themeLoadSpin {
  from { transform: rotate(-180deg) scale(.86); opacity: .55; }
  to { transform: rotate(0deg) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .js .site {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .js.page-leaving .site {
    opacity: 1;
    transform: none;
  }
  .js .page-body > section {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .js.theme-transition *,
  .js.theme-transition *::before,
  .js.theme-transition *::after {
    transition: none !important;
  }
  .js .site[data-ready="true"] .theme-btn .ti {
    animation: none;
  }
}

.page-body {
  position: relative;
  z-index: 1;
}

.site-bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Ambient colour across the WHOLE viewport, not just the top corners -
     glass panels need something behind them to frost, or they read as
     opaque slabs. Clouds at mid and lower positions give every pane a
     visible bloom through its backdrop blur. */
  background:
    radial-gradient(circle at 12% 12%, var(--cloud-1), transparent 34rem),
    radial-gradient(circle at 86% 8%, var(--cloud-2), transparent 28rem),
    radial-gradient(circle at 78% 46%, var(--cloud-2), transparent 30rem),
    radial-gradient(circle at 12% 70%, var(--cloud-3), transparent 32rem),
    radial-gradient(circle at 55% 92%, var(--cloud-2), transparent 28rem),
    linear-gradient(180deg, var(--bg), var(--bg-2) 48%, var(--elev) 100%);
}

.site-bg-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  /* 62px cells, NO fade mask - exactly the live site. The old bottom-fade mask
     erased the grid behind every panel in the lower half of the viewport, so
     their backdrop blur had nothing to frost and the glass read as opaque. */
  background-size: 62px 62px;
  opacity: var(--grid-op);
}

.site-bg-glow {
  position: absolute;
  inset: auto -10% 0 -10%;
  height: 44vh;
  background: linear-gradient(90deg, var(--cloud-2), var(--cloud-3));
  filter: blur(40px);
}

/* -----------------------------------------------------------------------------
   THEMED SCROLLBARS  (webkit-only so it stays a clean custom bar with no arrows)
   Thumb is light purple in dark mode and dark indigo in light mode, driven by
   the theme tokens. Add the class to any scroll area: <div class="themed-scroll">.
   Optional widths: .scroll-thin (8px) | .scroll-wide (12px).
   -------------------------------------------------------------------------- */
.themed-scroll::-webkit-scrollbar { width: 6px; height: 6px; }
.themed-scroll::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
.themed-scroll::-webkit-scrollbar-track { background: transparent; box-shadow: none; }
.themed-scroll::-webkit-scrollbar-corner { background: transparent; }
.themed-scroll::-webkit-scrollbar-thumb {
  background: var(--indigo-lift);
  border-radius: 999px;
  box-shadow: none;
}
.themed-scroll::-webkit-scrollbar-thumb:hover { background: var(--indigo-bright); background-clip: content-box; }
[data-theme="light"] .themed-scroll::-webkit-scrollbar-thumb { background: var(--indigo); }
[data-theme="light"] .themed-scroll::-webkit-scrollbar-thumb:hover { background: var(--indigo-bright); }
.themed-scroll.scroll-thin::-webkit-scrollbar { width: 8px; height: 8px; }
.themed-scroll.scroll-wide::-webkit-scrollbar { width: 12px; height: 12px; }


/* Skip-to-content link: visually hidden until keyboard focus (WCAG bypass block). */
.skip-link {
  position: fixed;
  top: 10px; left: 10px;
  z-index: 1000;
  padding: 10px 16px;
  border-radius: 8px;
  background: var(--indigo);
  color: #fff;
  font: 600 14px/1 var(--font-sans);
  text-decoration: none;
  transform: translateY(-150%);
  opacity: 0;
  transition: transform .18s ease, opacity .18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  opacity: 1;
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}


/* --- ./foundation/tokens.css --- */
/* =============================================================================
   SmartSettle AI - Global Design Tokens
   -----------------------------------------------------------------------------
   THE single source of truth for the whole site's colour, type, spacing, motion
   and layout values. Edit a value here once and it updates everywhere.

   • Colours are defined twice: dark defaults on `:root, [data-theme="dark"]`,
     then overridden for `[data-theme="light"]`. The theme toggle flips
     `data-theme` on <html> and #ssSite (see scripts/site.js).
   • Values below are the authored global defaults. Keep component files consuming
     these tokens instead of creating local one-off values.
   • Consume tokens with var(--name). Never hard-code a colour in a component.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   1. Theme-independent foundation (same in light & dark)
   Also scoped to [data-theme] so toggling the theme keeps layout constants stable
   on the themed #ssSite wrapper.
   -------------------------------------------------------------------------- */
:root, [data-theme] {
  /* Type families ---------------------------------------------------------- */
  --font-sans: 'Helvetica Neue', Helvetica, 'Inter', Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  /* Type scale (fluid) - real values in use across the site ----------------- */
  --fs-eyebrow:   18px;                       /* mono uppercase kicker label     */
  --fs-tag:       11px;                        /* smaller mono tag (ds-tag)       */
  --fs-small:     16px;                        /* small-t / captions / panel body */
  --fs-body:      19px;                         /* default body copy               */
  --fs-lead:      clamp(18px, 2vw, 21px);      /* hero subheads / section intros  */
  --fs-h4:        21px;                          /* card / panel heading            */
  --fs-h3:        25px;                          /* subsection heading              */
  --fs-sec-title: clamp(28px, 3.1vw, 40px);    /* section title (sec-head)        */
  --fs-h2:        clamp(33px, 4.4vw, 54px);    /* major section heading           */
  --fs-h1:        clamp(46px, 6vw, 78px);      /* page title / hero headline      */
  --fs-display:   clamp(44px, 7.6vw, 104px);   /* oversized hero display          */

  --lh-tight: 1.05;
  --lh-heading: 1.15;
  --lh-body: 1.6;

  /* Spacing scale (8px base) ----------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;

  /* Layout metrics --------------------------------------------------------- */
  --header-h: 92px;                          /* fixed header height (taller)   */
  --section-pad: clamp(48px, 6vw, 76px);     /* vertical section rhythm        */
  --group-gap: clamp(40px, 5vw, 60px);       /* space above a group heading    */
  --group-gap-below: 18px;                   /* space between group heading and its items */
  /* Page side gutter. Fluid: holds the wide 140px margins on desktop (where the
     content is already capped at --container) and compresses smoothly to a small
     margin on tablet/phone so nothing gets crushed into a thin column. */
  --gutter: clamp(24px, 11vw, 140px);        /* body / footer side gutter        */
  --gutter-header: clamp(18px, 6vw, 104px);  /* header runs a touch wider so the long nav has room */
  --container: 1300px;                       /* max content width              */
  --section: clamp(56px, 8vw, 104px);        /* legacy section padding token   */

  /* Radius ----------------------------------------------------------------- */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 20px;
  --radius-pill: 999px;
  --radius: 8px;                             /* legacy alias                    */

  /* Elevation / motion ----------------------------------------------------- */
  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --ease-smooth: cubic-bezier(.3, .85, .3, 1);
  --ease-reveal: cubic-bezier(.16, .78, .18, 1);
  --dur-fast: .18s;
  --dur-base: .3s;
  --dur-slow: .6s;
  --motion-window: .95s var(--ease-reveal);
  --motion-hover: .95s var(--ease-reveal);
  --motion-sheen: .9s cubic-bezier(.3, .7, .25, 1);
  --window-hover-transform: scale(1.025);
  --window-hover-shadow: inset 0 1px 0 rgba(255,255,255,.35), inset 0 0 0 1px rgba(255,255,255,.05), var(--panel-glow);

  /* Z-index scale ---------------------------------------------------------- */
  --z-bg: 0;
  --z-body: 1;
  --z-rail: 10;
  --z-header: 100000;
  --z-scrim: 50;
  --z-drawer: 60;

  /* Breakpoints (reference - for JS / container queries; @media can't read
     custom properties). Standard set the rebuild migrates toward.           */
  --bp-sm: 640px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-xl: 1200px;

  /* Focus ring (used by reset.css) ---------------------------------------- */
  --focus: #8db7ff;
}

/* -----------------------------------------------------------------------------
   2. Colour tokens - DARK (default)
   -------------------------------------------------------------------------- */
:root,
[data-theme="dark"] {
  color-scheme: dark;

  /* Surfaces / backgrounds */
  --bg:        #07060B;
  --bg-2:      #0B0913;
  --elev:      #100E18;
  --panel:     rgba(255,255,255,.045);
  --panel-2:   rgba(255,255,255,.07);
  --hover:     rgba(255,255,255,.08);
  /* Lighter white veil than the old .085 - panes read as glass, not slabs. */
  --glass:     linear-gradient(160deg, rgba(140,124,255,.06), rgba(255,255,255,.015));   /* subtle glass tint (window texture, not milky) */
  --glass-hi:  rgba(255,255,255,.16);
  --glass-sheen: rgba(255,255,255,.22);

  /* Brand indigo.
     --indigo is a FILL colour: button backgrounds, bars, gradient stops. It is
     declared once here and is deliberately the same value in both themes, which
     is why it must never be used as a text colour on a dark surface: #5333EC on
     --bg #07060B measures 2.94:1, below the 4.5:1 floor for body text and below
     even the 3:1 floor for large text.
     For text, use --indigo-lift, which has a real pair: #9C8CFF on dark (7.32:1)
     and #6B53F0 on light (4.65:1). */
  --indigo:        #5333EC;
  --indigo-2:      #6A4DF5;
  --indigo-lift:   #9C8CFF;
  --indigo-bright: #7C60FF;
  --eyebrow:       #9C8CFF;   /* eyebrow label - lighter purple, readable on dark */
  --signal:        #9C8CFF;
  --grad-mid:      #9C8CFF;
  --grad-hi:       #D2C6FF;
  --icon-hover:    #7C60FF;
  --icon-rest:     #CCC7D6;
  --on-accent:     #FFFFFF;

  /* Text */
  --text:  #F4F2F8;
  --muted: #B4AFC0;
  --dim:   #8B8797;

  /* Borders / lines */
  --brd:        rgba(255,255,255,.10);
  --brd-strong: rgba(255,255,255,.18);
  --ring-pulse-glow: rgba(150,132,255,1);
  --brd-hover:  rgba(138,120,255,.6);
  --line:       rgba(255,255,255,.10);

  /* Chrome */
  --header-bg: rgba(8,7,13,.62);
  --footer-bg: #0B0913;
  --mon-frame: #FFFFFF;   /* product-monitor bezel - white pops on the dark page */

  /* Background field: grid + glow clouds + spotlight */
  --grid:      rgba(255,255,255,.5);
  --grid-op:   .07;
  --grid-lit:  rgba(156,140,255,.5);
  --cloud-1:   rgba(118,96,255,.26);
  --cloud-2:   rgba(91,69,240,.18);
  --cloud-3:   rgba(91,69,240,.12);
  --panel-spot: rgba(156,140,255,.22);
  --glow-blend: screen;

  /* Shadows / glows */
  --shadow:     0 30px 80px rgba(0,0,0,.5);
  --panel-glow: 0 20px 50px rgba(91,69,240,.28);
  --glow-2:     rgba(91,69,240,.5);          /* indigo glow behind primary buttons / CTAs */

  /* Status */
  --ok:        #34D399;  --ok-bg:     rgba(52,211,153,.13);
  --warn:      #FBBF55;  --warn-bg:   rgba(251,191,85,.13);
  --danger:    #FB7185;  --danger-bg: rgba(251,113,133,.13);
  --info-bg:   rgba(156,140,255,.14);

  /* Form fields - whiter lift on hover / once filled */
  --field-glow-brd: rgba(255,255,255,.40);
  --field-glow:     rgba(255,255,255,.12);
}

/* -----------------------------------------------------------------------------
   3. Colour tokens - LIGHT (overrides)
   -------------------------------------------------------------------------- */
[data-theme="light"] {
  color-scheme: light;

  --bg:        #F3F3F7;
  --bg-2:      #EAEAF1;
  --elev:      #FFFFFF;
  --panel:     rgba(255,255,255,.55);
  --panel-2:   rgba(255,255,255,.7);
  --hover:     rgba(83,51,236,.08);
  --glass:     linear-gradient(160deg, rgba(83,51,236,.05), rgba(255,255,255,.42));   /* subtle glass tint */
  --glass-hi:  rgba(255,255,255,.9);
  --glass-sheen: rgba(83,51,236,.18);

  --indigo-2:      #5B45F0;
  --indigo-lift:   #6B53F0;
  --indigo-bright: #5333EC;
  --focus:         #5333EC;
  --eyebrow:       #5333EC;   /* eyebrow label - brand purple on light */
  --signal:        #5333EC;
  --grad-mid:      #5333EC;
  --grad-hi:       #7A63F5;
  --icon-hover:    #5333EC;
  --icon-rest:     #54515D;

  --text:  #16151C;
  --muted: #37343F;   /* darker than before for readable body text on light */
  --dim:   #625E6B;

  --brd:        rgba(22,21,28,.10);
  --brd-strong: rgba(22,21,28,.16);
  --ring-pulse-glow: rgba(91,69,240,.85);
  --brd-hover:  rgba(83,51,236,.5);
  --line:       rgba(22,21,28,.10);

  --header-bg: rgba(243,243,247,.66);
  --footer-bg: #F3F3F7;   /* matches the header's near-white, not the grayer --bg-2 */
  --mon-frame: #16151C;   /* product-monitor bezel - near-black pops on the light page */

  --grid:      rgba(22,21,28,.5);
  --grid-op:   .07;
  --grid-lit:  rgba(83,51,236,.32);
  --cloud-1:   rgba(91,69,240,.14);
  --cloud-2:   rgba(91,69,240,.08);
  --cloud-3:   rgba(91,69,240,.05);
  --panel-spot: rgba(83,51,236,.10);
  --glow-blend: normal;

  --shadow:     0 24px 60px rgba(40,30,90,.14);
  --panel-glow: 0 22px 46px rgba(83,51,236,.16);
  --glow-2:     rgba(83,51,236,.32);         /* indigo glow behind primary buttons / CTAs */

  --ok:        #0E9C6E;  --ok-bg:     rgba(14,156,110,.10);
  --warn:      #B8791A;  --warn-bg:   rgba(184,121,26,.12);
  --danger:    #D8455C;  --danger-bg: rgba(216,69,92,.10);
  --info-bg:   rgba(83,51,236,.08);

  /* Form fields - indigo lift on hover / once filled. Strong enough to
     actually register on the white light-mode panels (the old near-black
     .26 border + .08 glow read as "hover does nothing"). */
  --field-glow-brd: rgba(83,51,236,.55);
  --field-glow:     rgba(83,51,236,.18);
}


/* --- ./foundation/fonts.css --- */
/* =============================================================================
   SmartSettle AI - Self-hosted web fonts
   -----------------------------------------------------------------------------
   @font-face declarations for IBM Plex Mono (--font-mono) and Inter (the web
   fallback inside --font-sans). Files live in src/fonts/ and are copied
   into public/ by the build, so paths are relative from styles/foundation/.
   Mirrors the live Style Guide exactly.
   ========================================================================== */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/f8c22ec1804bd696.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/7635422bd10ddbbc.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/62632b6375305e70.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/6bc0f226a5b7884a.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/08949f728dc52d52.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/3febe5c7f22e4b07.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/1d89462e86cb8e87.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/781633d95de88040.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/6bb06407c97584b0.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/01d285447409c8a5.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/83109cdd4f8665b4.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/2b05a8695c7f9f4a.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/51b74d53e106ba8a.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/32057cf50dd14bdb.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/0d1f0b8d0722224e.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 500;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 800;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/ca157063339ac4ad.woff2") format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/71d5ee93cc1e9f1d.woff2") format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/6e9e020a25f9b56d.woff2") format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/1be3448e292fbf05.woff2") format('woff2');
  unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* vietnamese */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/5c66f9e07e90c6d4.woff2") format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/34b9c504cab7a73e.woff2") format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 900;
  font-display: block;
  src: url("/fonts/3100e775e8616cd2.woff2") format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* --- ./foundation/typography.css --- */
/* =============================================================================
   SmartSettle AI - Typography
   -----------------------------------------------------------------------------
   Every text style on the site, documented. Values come from the live Style
   Guide (resources/smartsettle-base) so these render exactly as they do today.
   Sizes are driven by the type-scale tokens in tokens.css - edit a size once
   there and it flows through here.

   HOW TO USE: put the class on any element, e.g. <h2 class="h2">…</h2>,
   <div class="eyebrow">…</div>, <p class="lead">…</p>.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   EYEBROW - small mono uppercase kicker that sits ABOVE a heading.
   Used to label a section ("ABOUT US", "OUR MISSION"). Indigo, wide tracking.
   -------------------------------------------------------------------------- */
.eyebrow {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--eyebrow);            /* brand purple on light, lighter purple on dark */
  margin: 0 0 16px;                 /* breathing room before the heading */
}

/* -----------------------------------------------------------------------------
   HEADINGS - display hierarchy. H1 = page title / hero headline; H2 = major
   section heading; H3 = subsection; H4 = card / panel heading.
   -------------------------------------------------------------------------- */
.h1 {
  font-weight: 800;
  font-size: var(--fs-h1);
  line-height: 1.0;
  letter-spacing: -.035em;
  color: var(--text);
  margin: 0;
}
.h2 {
  font-weight: 800;
  font-size: var(--fs-h2);
  line-height: 1.03;
  letter-spacing: -.03em;
  color: var(--text);
  margin: 0;
}
.h3 {
  font-weight: 700;
  font-size: var(--fs-h3);
  line-height: 1.18;
  letter-spacing: -.02em;
  color: var(--text);
  margin: 0;
}
.h4 {
  font-weight: 700;
  font-size: var(--fs-h4);
  line-height: 1.3;
  letter-spacing: -.01em;
  color: var(--text);
  margin: 0;
}

/* -----------------------------------------------------------------------------
   SECTION HEAD - wrapper (.sec-head) + its title (.sec-title) + intro
   (.sec-intro). Use at the top of a content section; add .center to centre it.
   -------------------------------------------------------------------------- */
.sec-head { max-width: 940px; margin-bottom: 44px; }
.sec-head:only-child { margin-bottom: 0; }
.sec-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.sec-title {
  font-weight: 800;
  font-size: var(--fs-sec-title);
  line-height: 1.1;
  letter-spacing: -.02em;
  color: var(--text);
  margin: 14px 0 0;
  text-wrap: balance;
}
.sec-intro {
  margin-top: 16px;
  font-size: clamp(20px, 2.1vw, 23px);
  line-height: 1.62;
  color: var(--muted);
  max-width: 760px;
}
.sec-head.center .sec-intro { margin-left: auto; margin-right: auto; }
/* Sub-text (lead) below a heading gets a clear, generous gap. */
.sec-head .lead { margin-top: 30px; }
/* Inline mono caption row - e.g. "● Featured · June 2026" above a card title.
   Pairs with .live-dot for the pulsing status marker. */
.sec-caption {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
}

/* -----------------------------------------------------------------------------
   BODY COPY
   .lead   - hero subheads & section intros: larger, lighter, easy entry.
   .body-t - the workhorse paragraph style.
   .small-t- captions, small print, panel body text.
   -------------------------------------------------------------------------- */
.lead {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--muted);
  margin: 0;
  font-weight: 400;
}
.body-t {
  font-size: var(--fs-body);
  line-height: 1.74;
  color: var(--muted);
  margin: 0;
}
.small-t {
  font-size: var(--fs-small);
  line-height: 1.7;
  color: var(--muted);
  margin: 0;
}

/* -----------------------------------------------------------------------------
   MONO LABELS - uppercase micro-labels.
   .data-label - in-body data/section marker (slightly larger, full contrast).
   -------------------------------------------------------------------------- */
.data-label {
  font-family: var(--font-mono);
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text);
}

/* -----------------------------------------------------------------------------
   TEXT GRADIENT - animated indigo sweep across headline text or a stat number.
   Add .text-grad alongside .h1 / .stat-num for the shimmering accent.
   -------------------------------------------------------------------------- */
.text-grad {
  background: linear-gradient(90deg,
    var(--text) 0%, var(--text) 19%, var(--grad-mid) 25%, var(--text) 31%,
    var(--text) 69%, var(--grad-mid) 75%, var(--text) 81%, var(--text) 100%);
  background-size: 200% 100%;
  background-repeat: repeat;
  will-change: auto;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gradFlow 13s linear infinite;   /* slow indigo sweep across the text */
  /* Extend the clipped box so descenders (g, y, p) aren't cut off. */
  padding-bottom: 0.16em;
}
@media (prefers-reduced-motion: reduce) { .text-grad { animation: none; } }

/* -----------------------------------------------------------------------------
   INLINE LINK - indigo text link with an underline that wipes in on hover.
   -------------------------------------------------------------------------- */
.link-i {
  position: relative;
  color: var(--indigo-bright);
  text-decoration: none;
  font-weight: 600;
  background-image: linear-gradient(currentColor, currentColor);
  background-position: 0 100%;
  background-repeat: no-repeat;
  background-size: 0 1px;
  transition: background-size .24s cubic-bezier(.2, .8, .2, 1), color .18s ease;
}
.link-i::after {
  content: none;
}
.link-i:hover { background-size: 100% 1px; }

/* -----------------------------------------------------------------------------
   PROSE - rich text blocks. Paragraphs + bulleted lists with indigo dash
   markers centred to the first line. Wrap body content in <div class="prose">.
   -------------------------------------------------------------------------- */
.prose p { font-size: var(--fs-body); line-height: 1.74; color: var(--muted); margin: 0 0 16px; }
.prose p:last-child { margin-bottom: 0; }
.prose strong { color: var(--text); font-weight: 700; }
/* Bullet lists (.prose ul / li) live in components/bullets.css - the reusable
   bullet system (plain bullets + feature rows). Edit them there. */


/* --- ./components/controls.css --- */
/* =============================================================================
   Components - Buttons, Chips & Tags
   ========================================================================== */

/* -----------------------------------------------------------------------------
   BUTTON - pill-shaped action. Base .btn + a variant:
     .btn-primary   solid indigo (main call to action)
     .btn-secondary outlined / subtle
     .btn-ghost     text-style with an arrow (.arr) that nudges on hover
     .btn-sm        smaller size
   Lifts slightly on hover (shared with the .magnify helper). Text-heavy
   controls do not scale, because transform-scaling text can look blurry while
   the browser composites it.
   -------------------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  cursor: pointer;
  border-radius: 999px;
  padding: 15px 24px 13px;
  font-family: inherit; font-size: 14px; font-weight: 700; line-height: 1;
  border: 1px solid transparent; text-decoration: none; white-space: nowrap;
  isolation: isolate; overflow: hidden;
  transition: transform var(--motion-window), box-shadow .34s ease, background .34s ease, border-color .34s ease, color .24s ease;
  --btn-sheen-soft: rgba(255,255,255,.12);
  --btn-sheen-core: rgba(255,255,255,.28);
}
.magnify, .btn {
  transition: transform var(--motion-window), box-shadow .34s ease, background .34s ease, border-color .34s ease, color .24s ease;
}
.magnify:hover, .btn:hover { transform: var(--window-hover-transform); }
.btn:active { transform: translateY(0); }
.btn:focus-visible { outline: 2px solid var(--indigo-lift); outline-offset: 2px; }

/* Variant fills (dark defaults; light overrides live further down).
     .btn-primary   solid brand indigo with an indigo glow
     .btn-secondary translucent glass with a visible border */
.btn-primary {
  color: var(--on-accent);
  background: var(--indigo);
  box-shadow: 0 4px 18px -6px var(--glow-2);
}
.btn-primary:hover {
  background: var(--indigo-2);
  box-shadow: 0 10px 26px -6px var(--glow-2);
}
.btn-secondary {
  color: var(--text);
  background: var(--glass);
  border-color: var(--brd-strong);
}
.btn-secondary:hover { border-color: var(--brd-hover); }

.btn-primary::after,
.btn-secondary::after {
  content: "";
  position: absolute;
  top: -40%;
  bottom: -40%;
  left: -56%;
  width: 30%;
  border-radius: inherit;
  pointer-events: none;
  z-index: 2;
  background:
    radial-gradient(ellipse at center, var(--btn-sheen-core) 0%, var(--btn-sheen-soft) 34%, transparent 68%),
    linear-gradient(115deg, transparent 0%, transparent 30%, var(--btn-sheen-soft) 46%, var(--btn-sheen-core) 50%, var(--btn-sheen-soft) 54%, transparent 70%, transparent 100%);
  filter: blur(4px);
  transform: translate3d(0, 0, 0) skewX(-14deg);
  opacity: 0;
  transition: transform .62s cubic-bezier(.4,.8,.3,1), opacity .28s ease;
}
.btn-primary:hover::after,
.btn-secondary:hover::after {
  transform: translate3d(540%, 0, 0) skewX(-14deg);
  opacity: .72;
}
.btn:disabled,
.btn.is-disabled {
  cursor: not-allowed;
  opacity: .48;
  transform: none;
  box-shadow: none;
  pointer-events: none;
}

/* Icon buttons are chromeless - no border/fill/sheen. They behave like the
   header .icon-link: muted at rest, magnify and turn accent-purple on hover,
   whatever variant class they also carry (.btn-secondary / .btn-ghost). */
.btn-icon {
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  box-shadow: none;
}
.btn-icon::after { content: none; }        /* suppress the variant sheen sweep */
.btn-icon svg { width: 17px; height: 17px; }
.btn-icon:hover {
  background: transparent;
  border-color: transparent;
  color: var(--icon-hover);
  transform: scale(1.18);
  box-shadow: none;
}
.btn-icon:active { transform: scale(1.06); }

@keyframes arrowNudge {
  0% { transform: translateX(0); }
  50% { transform: translateX(4px); }
  100% { transform: translateX(0); }
}
.btn-ghost .arr { width: 16px; height: 16px; transition: transform var(--motion-window); }


/* Size & padding variants - authored AFTER the base .btn so they win. (The base
   .btn is imported after the V3 dump, which would otherwise override these and
   leave the header's small "Request Demo" button at full size.)
     .btn-sm    → the compact header button
     .btn-ghost → text-style button padding */
.btn-sm { padding: 9px 16px; font-size: 13px; }
.btn-ghost { color: var(--muted); padding: 13px 10px; }
.btn-ghost:hover { color: var(--text); }

[data-theme="light"] .btn-secondary {
  background: var(--glass);
  border-color: color-mix(in srgb, var(--indigo) 28%, var(--line));
  color: var(--text);
}
[data-theme="light"] .btn-secondary {
  --btn-sheen-soft: rgba(83,51,236,.18);
  --btn-sheen-core: rgba(83,51,236,.4);
}
[data-theme="light"] .btn-primary {
  --btn-sheen-soft: rgba(255,255,255,.12);
  --btn-sheen-core: rgba(255,255,255,.32);
}
[data-theme="light"] .btn-secondary:hover {
  background: color-mix(in srgb, var(--indigo) 12%, transparent);
  border-color: color-mix(in srgb, var(--indigo) 42%, var(--line));
}
[data-theme="light"] .btn-ghost {
  color: var(--indigo);
  border-color: transparent;
  background: transparent;
}
[data-theme="light"] .btn-ghost:hover {
  color: var(--indigo-2);
  background: transparent;
}

/* Icon buttons stay chromeless in EVERY theme - theme-scoped so they beat the
   light-theme .btn-secondary border/fill overrides above (equal specificity,
   declared later). They read like the header .icon-link: muted → purple+magnify. */
[data-theme] .btn-icon {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--muted);
}
[data-theme] .btn-icon:hover {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  color: var(--icon-hover);
  transform: scale(1.18);
}

/* Segmented control - compact two/three-option picker used for review engines
   and small mode switches. Inactive choices are plain muted text; active choices
   use the normal button variants so they feel like the rest of the site. */
.seg {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: center;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: transparent;
}
.seg .btn {
  min-height: 26px;
  padding: 5px 9px;
  font-size: 12px;
  border: 0;
  box-shadow: none;
}
.seg .btn:not(.active) {
  background: transparent;
  color: var(--dim);
  font-weight: 650;
}
.seg .btn:not(.active):hover {
  color: var(--text);
  background: transparent;
}
.seg .btn:not(.active),
.seg .btn:not(.active):hover,
.seg .btn:not(.active):active {
  transform: none;
  box-shadow: none;
}

.drawer .btn { margin-top: 20px; justify-content: center; }

/* Mobile hamburger - chromeless (no border/box), just the bars; magnifies and
   turns purple on hover like the other header icon buttons. The bars morph to
   an X when the drawer is open. */
.menu-toggle {
  border: 0;
  background: transparent;
  color: var(--muted);
  transition: transform .28s var(--ease-out), color .24s ease;
}
.menu-toggle span {
  background: currentColor;
  transform-origin: center;
  /* snappy morph to the X */
  transition: transform .35s cubic-bezier(.5, 1.3, .4, 1), opacity .25s ease, background .24s ease;
}
.menu-toggle:hover { color: var(--icon-hover); transform: scale(1.12); }

/* Header icon buttons (theme toggle, etc.) - magnify on hover; they already
   turn purple via .icon-link:hover in the base styles.
   ONE scale, no bounce: the V3 dump also scales the button's INNER element
   (.icon-link:hover > * { scale(1.2) }) on a different clock with an overshoot
   bezier, which made the icon grow and then visibly shift as the two animations
   settled. Neutralise the inner scale and ease the outer one smoothly. */
.icon-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: transform var(--motion-window), color .24s ease, filter .24s ease;
  will-change: auto;
}
.icon-link:hover { transform: scale(1.18); color: var(--icon-hover); }
.icon-link:hover > * { transform: none; }

/* Mobile drawer - tighten spacing so the whole menu fits, hide the scrollbar,
   and give the Request Demo button clean, uncut spacing at the bottom. */
.drawer {
  padding: calc(var(--header-h) + 10px) 14px 18px;
  gap: 12px;
  transition: transform var(--motion-window), box-shadow .34s ease;
}
/* Links scroll here; the drawer itself doesn't, so the pinned CTA never moves. */
.drawer-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 2px;
  scrollbar-width: none;              /* Firefox */
  -ms-overflow-style: none;           /* old Edge */
}
.drawer-scroll::-webkit-scrollbar { display: none; }   /* Chrome/Safari */
.drawer-cta { flex: 0 0 auto; }
.scrim { transition: opacity .24s ease, visibility .24s ease, backdrop-filter .24s ease; }
.drawer-search {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  padding: 10px 12px;
  border: 1px solid var(--brd-strong);
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--panel) 88%, transparent);
}
.drawer-search svg { width: 17px; height: 17px; color: var(--indigo-lift); }
.drawer-search input {
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
}
.drawer-search input::placeholder { color: var(--dim); }
.drawer a {
  display: block;
  padding: 11px 12px;
  border-radius: 12px;
  font-size: 16px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  transition: background .18s ease, color .18s ease;
}
.drawer a:hover { background: var(--hover); }
/* Section labels - small mono uppercase kickers (PLATFORM / EXPLORE / COMPANY),
   matching the live drawer. */
.drawer-sec {
  margin: 16px 0 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--dim);
}
.drawer .btn { margin-top: 14px; flex: 0 0 auto; }
.drawer .btn-primary { color: var(--on-accent); }   /* keep white text on the indigo button */
/* The generic drawer-link hover (.drawer a:hover { background:var(--hover) }) is
   more specific than .btn-primary:hover, washing the button out to unreadable
   white-on-pale. Restate the button's real hover at higher specificity so it
   behaves exactly like the wide-mode Request Demo button. */
.drawer a.btn-primary:hover { background: var(--indigo-2); color: var(--on-accent); }

/* -----------------------------------------------------------------------------
   CHIP - small rounded tag. Add .chip-mono for the uppercase mono variant, or a
   .live-dot inside for a status pip (.anim animates it).
   -------------------------------------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--brd); background: var(--panel);
  color: var(--muted); font-size: 14px;
}

/* Live status dot - teal pip with a soft glow; .anim gives it a pulse. */
.live-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--signal); box-shadow: 0 0 10px var(--signal);
}
.live-dot.anim { animation: ssPulse 2s infinite, dotGlow 2.6s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .live-dot.anim { animation: none; } }

/* Recording light. A past event whose recording is available is not the same
   offer as an event you have to turn up to, so it should not read as the same
   thing at a glance. Red rather than purple, but the SAME soft pulse and halo
   as every other live dot on the site, so it looks like it belongs here rather
   than like a warning that something is wrong.

   This is done by re-pointing --signal on the dot itself. The base .live-dot
   rules and the dotGlow keyframes both already read var(--signal) for the fill
   and the halo, so changing that one value turns the whole thing red and the
   timing, easing and glow stay exactly as they are on the purple dots. Nothing
   here overrides `animation`, which is what keeps the two in step.

   The red is a fixed value rather than a theme token on purpose: a recording
   light has to mean the same thing on both themes. Checked against both
   backgrounds. */
.live-dot.is-rec {
  --signal: #FF3B4E;
}
/* Reduced motion is handled by the .live-dot.anim rule above, which already
   drops the animation. The dot stays visible and simply sits still. */

/* In the events list the label is mono and inline, so the dot needs to sit on
   the text baseline rather than float. */
.ev-kind .live-dot {
  display: inline-block;
  margin-right: 7px;
  vertical-align: middle;
  position: relative;
  top: -1px;
}


/* --- ./components/panels.css --- */
/* =============================================================================
   Components - Panels, Cards & CTA
   -----------------------------------------------------------------------------
   Glass surfaces used to group content. Authored from the live design; the CTA
   sheen is clipped to its rounded border (fixes the shimmer spilling past the
   edge on the bottom call-to-action windows).
   ========================================================================== */

/* -----------------------------------------------------------------------------
   PANEL - the standard glass card. Frosted background, thin border, hover lift.
   On hover: a soft spotlight (::before, follows the cursor via scripts/effects.js)
   and a diagonal sheen sweep (::after). Both are clipped by overflow:hidden.
   Usage: <div class="panel"> … </div>  (put an .accent-line at the top for a tab)
   -------------------------------------------------------------------------- */
.panel {
  position: relative;
  background: var(--glass);      /* the ONE glass token - same recipe as the live site, theme-aware */
  border: 1px solid var(--brd);
  border-radius: 20px;
  padding: 28px;
  overflow: hidden;                 /* clips spotlight + sheen to the rounded box */
  /* 10px (not 14) keeps the backdrop recognizable - heavier blur mushed the
     grid/glow into a flat tone and the pane read as opaque. */
  /* windows are see-through: no frosted backdrop */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: border-color .34s ease, transform var(--motion-window), box-shadow .34s ease;
  --window-sheen-soft: rgba(255,255,255,.08);
  --window-sheen-core: rgba(255,255,255,.18);
}
.panel::before {                    /* cursor spotlight */
  content: "";
  position: absolute; inset: 0;
  opacity: 0; transition: opacity .35s ease; pointer-events: none;
  background: radial-gradient(420px circle at var(--px, 50%) var(--py, 50%), var(--panel-spot), transparent 60%);
}
.panel::after {                     /* diagonal sheen sweep - moved via background-position
                                       so it stays pinned inside the rounded box. A translate
                                       leaks past the corners here because backdrop-filter
                                       breaks the rounded overflow clip. */
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -42%;
  width: 24%;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, var(--window-sheen-core) 0%, var(--window-sheen-soft) 34%, transparent 68%),
    linear-gradient(115deg, transparent 0%, transparent 32%, var(--window-sheen-soft) 46%, var(--window-sheen-core) 50%, var(--window-sheen-soft) 54%, transparent 68%, transparent 100%);
  filter: blur(7px);
  transform: translate3d(0, 0, 0) skewX(-14deg);
  opacity: 0;
  transition: transform .9s cubic-bezier(.4,.75,.3,1), opacity .34s ease;
}
.panel:hover {
  border-color: var(--brd-hover);
  transform: var(--window-hover-transform);
  box-shadow: var(--window-hover-shadow);
}
.panel:hover::after { transform: translate3d(580%, 0, 0) skewX(-14deg); opacity: .72; }
.panel:hover::before { opacity: 1; }
.panel > * { position: relative; z-index: 1; }

/* Accent tab - a short indigo bar, usually at the top of a panel. */
.accent-line {
  width: 44px; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--indigo-lift), var(--grad-hi), transparent);
  background-size: 220% 100%;
  background-position: 100% 0;
  transition: width var(--motion-hover), background-position var(--motion-hover);
}
.panel:hover .accent-line {
  width: 62px;
  background-position: 0 0;
}

/* Dashed empty-state box (placeholders / "drop content here"). */
.box {
  border: 1px dashed var(--brd-strong);
  border-radius: 16px;
  padding: 40px 52px;
  text-align: center;
  color: var(--dim);
}

/* -----------------------------------------------------------------------------
   CTA-SHINE - the large call-to-action window (page-bottom "Request a demo"
   blocks). Glass panel with an animated conic border trace (.cta-orbit) and a
   sheen on hover.
   FIX: the sheen (::after) now sweeps via background-position while staying
   pinned inside its rounded box, so it never spills past the border. (Previously
   it used translateX and, with no overflow clip, leaked off the bottom edge.)
   -------------------------------------------------------------------------- */
.cta-shine {
  position: relative;
  isolation: isolate;
  overflow: hidden;                 /* clip the sheen inside the rounded corners (same as .panel) */
  border: 1px solid var(--brd-hover);
  border-radius: 24px;
  padding: clamp(40px, 4.6vw, 60px) clamp(26px, 3.6vw, 42px);
  background: var(--glass);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: box-shadow .34s ease, border-color .34s ease, transform var(--motion-window);
  will-change: auto;
  --window-sheen-soft: rgba(255,255,255,.08);
  --window-sheen-core: rgba(255,255,255,.18);
  --streak-head: #FFFFFF; --streak-core: #F2EEFF;
  --streak-tail: var(--indigo-bright); --streak-glow: var(--indigo-bright);
}
.cta-window {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;   /* even spacing between logo, heading, subline, buttons */
}
/* CTA wordmark uses the hi-res logo-*-hd.png (derived from the 3585x580 master),
   so it stays crisp at any size and can magnify with the window on hover. */
.cta-window .cta-logo { height: 48px; width: auto; margin: 0 0 2px; }
.cta-shine:hover { border-color: var(--brd-hover); transform: scale(1.045); }
.cta-shine .ds-row .btn,
.cta-shine .center-row .btn { min-width: 148px; }
.cta-window > :not(.cta-orbit) { margin-top: 0; margin-bottom: 0; }
.cta-window .lead,
.cta-window .h2 {
  transform-origin: center;
  transition: transform var(--motion-window), color .34s ease;
}
.cta-window:hover .h2 { transform: scale(1.026); }
.cta-window:hover .lead { transform: scale(1.018); color: var(--text); }
.cta-window .center-row { margin-top: 0; }
.cta-window .center-row.is-spaced { margin-top: 0; }
.cta-shine::before {
  content: none;
  display: none;
}
.cta-shine::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -42%;
  width: 24%;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, var(--window-sheen-core) 0%, var(--window-sheen-soft) 34%, transparent 68%),
    linear-gradient(115deg, transparent 0%, transparent 32%, var(--window-sheen-soft) 46%, var(--window-sheen-core) 50%, var(--window-sheen-soft) 54%, transparent 68%, transparent 100%);
  filter: blur(7px);
  transform: translate3d(0, 0, 0) skewX(-14deg);
  opacity: 0;
  transition: transform .95s cubic-bezier(.4,.75,.3,1), opacity .34s ease;
}
.cta-shine:hover::after { transform: translate3d(580%, 0, 0) skewX(-14deg); opacity: .72; }
.cta-shine > * { position: relative; z-index: 1; }
[data-theme="light"] .cta-shine {
  --streak-head: #4A1FDB; --streak-core: #6B4BEF;
  --streak-tail: #9C86F5; --streak-glow: #7A63F5;
}
[data-theme="light"] .panel,
[data-theme="light"] .cta-shine {
  --window-sheen-soft: rgba(83,51,236,.12);
  --window-sheen-core: rgba(83,51,236,.3);
}

/* Animated conic-gradient border trace that orbits the CTA.
   The @property registration is REQUIRED: without it --cta-trace is not
   animatable, the angle never advances, and the streak sits frozen. */
@property --cta-trace {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
.cta-orbit {
  position: absolute; inset: -1px; border-radius: inherit; pointer-events: none; z-index: 2; padding: 1.6px;
  background: conic-gradient(from var(--cta-trace),
    transparent 0deg, transparent 188deg,
    color-mix(in srgb, var(--streak-tail) 26%, transparent) 268deg,
    color-mix(in srgb, var(--streak-tail) 70%, transparent) 320deg,
    var(--streak-tail) 342deg, var(--streak-core) 353deg, var(--streak-head) 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--streak-glow) 75%, transparent));
  animation: ctaTrace 16s linear infinite;
  opacity: .74;
  transition: opacity .28s ease, filter .28s ease;
}
.cta-shine:hover .cta-orbit {
  opacity: 1;
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--streak-glow) 78%, transparent));
}
@media (prefers-reduced-motion: reduce) { .cta-orbit { animation: none; } }

/* -----------------------------------------------------------------------------
   FEATURED ARTICLE (.tl-feat) - the Thought Leadership hero card. A two-column
   glass panel (headline + author on the left, excerpt + read-link on the right)
   wrapped in one link, with the CTA orbit tracing its border.
   Structure: <a class="panel tl-feat" href="…"><span class="cta-orbit"></span>
              <div class="tl-feat-main">…</div><div class="tl-feat-aside">…</div></a>
   -------------------------------------------------------------------------- */
.tl-feat {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: 1fr 1fr;
  padding: 0 !important;
  overflow: hidden;
  text-decoration: none;
  background: var(--glass);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: transform .32s cubic-bezier(.34, 1.45, .5, 1), box-shadow .35s ease, border-color .3s ease;
  --streak-head: #FFFFFF; --streak-core: #F2EEFF;
  --streak-tail: var(--indigo-bright); --streak-glow: var(--indigo-bright);
}
.tl-feat:hover { transform: translateY(-4px) scale(1.022); }
.tl-feat .cta-orbit { inset: 0; }
[data-theme="light"] .tl-feat {
  --streak-head: #4A1FDB; --streak-core: #6B4BEF;
  --streak-tail: #9C86F5; --streak-glow: #7A63F5;
}
.tl-feat-main {
  padding: clamp(24px, 2.6vw, 34px);
  position: relative;
  z-index: 1;
}
.tl-feat-main .h2 { margin-top: 20px; max-width: 15ch; }
.tl-feat-aside {
  padding: clamp(24px, 2.6vw, 34px) clamp(24px, 2.6vw, 32px);
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 14px;
}
@media (max-width: 760px) { .tl-feat { grid-template-columns: 1fr; } }

/* Author strip inside the featured card: photo + name/role. */
.tl-feat-author {
  margin-top: 22px;
  display: flex;
  align-items: center;
  /* Gap tracks the circle: a 60px avatar next to a 13px gap reads cramped. */
  gap: 16px;
}
.tl-feat-author b {
  display: block;
  font-size: 19.5px;
  line-height: 1.25;
  color: var(--text);
  font-weight: 700;
}
.tl-feat-author span {
  font-size: 13px;
  color: var(--dim);
}
/* Superseded by .ava in objects/article.css, which wraps the image so it can be
   framed and padded rather than only cropped. */

/* "Read the article →" mono link; arrow nudges + label underlines on hover. */
.tl-fwd {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--indigo-bright);
  text-decoration: none;
  align-self: flex-start;
}
.tl-fwd svg { width: 15px; height: 15px; transition: transform .28s cubic-bezier(.5, 1.4, .5, 1); }
.panel:hover .tl-fwd svg { transform: translateX(5px); }
.tl-fwd span { position: relative; }
.tl-fwd span::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .25s cubic-bezier(.5, .5, .2, 1);
}
.panel:hover .tl-fwd span::after { transform: scaleX(1); }

/* A published article shown full width above the upcoming grid. Reuses the
   .tl-feat card so it keeps the photo, the forward link and no underline. */
.tl-more-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 28px;
  padding: 28px;
  text-decoration: none;
}
.tl-more-card .h4 { margin-top: 8px; }
.tl-more-card .small-t { margin-top: 8px; }
/* Right column: the forward link, then the author row formatted exactly
   like the featured card above it (.tl-feat-author + .tl-ava). */
.tl-more-side { display: flex; flex-direction: column; align-items: stretch; gap: 14px; }
.tl-more-side .tl-fwd { align-self: flex-end; }
.tl-more-side .tl-fwd { white-space: nowrap; }
.tl-more-side .tl-feat-author { margin-top: 0; }
@media (max-width: 760px) { .tl-more-card { grid-template-columns: 1fr; } }

/* Upcoming-articles grid: simple panel cards, three-up on wide screens. */
.tl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 18px;
}
.tl-grid .panel { padding: 28px; display: block; }
/* Card eyebrow. One size everywhere a card carries a date, so the featured
   card, the wide card and the upcoming grid all read as the same label. */
.tl-card-date {
  font-size: 13px;
  letter-spacing: .12em;
  color: var(--indigo-lift);
}
/* Nothing is published yet behind these, so they are muted rather than accent. */
.tl-card-date.is-upcoming { color: var(--muted); }
/* The featured cards carry the live NEW / FEATURED stamp, so it reads larger
   than a plain card date. */
.sec-caption.tl-card-date, .fi-cap.tl-card-date { font-size: 15px; }
.tl-grid .h4 { margin-top: 12px; }
.tl-grid .small-t { margin-top: 10px; }

/* CTA logo must render crisp ON TOP of the glass window, never behind it. */
.cta-window .cta-logo { position: relative; z-index: 2; filter: none; -webkit-filter: none; image-rendering: auto; }



/* --- ./components/feedback.css --- */
/* =============================================================================
   Components - Alerts, Toasts & Banners
   Status messaging. Colour comes from the status tokens (ok / warn / danger /
   info) so light & dark stay in sync.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   ALERT - a boxed message with an icon, title and body. Add a status class:
     .alert.info  .alert.success  .alert.warning  .alert.error
   Structure: <div class="alert success"><div class="ai">svg</div>
              <div><h6>Title</h6><p>Body</p></div><button class="ax">×</button></div>
   -------------------------------------------------------------------------- */
.alert {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 15px 16px; border-radius: 15px;
  border: 1px solid var(--brd); background: var(--glass);
  backdrop-filter: blur(12px); box-shadow: inset 0 1px 0 var(--glass-hi);
}
.alert .ai {
  width: 30px; height: 30px; border-radius: 9px;
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.alert .ai svg { width: 16px; height: 16px; }
.alert h6 { margin: 0; font-size: 14px; font-weight: 700; color: var(--text); }
.alert p { margin: 3px 0 0; font-size: 13px; line-height: 1.5; color: var(--muted); }

.alert.info    { border-color: rgba(123,103,240,.4); }
.alert.info .ai    { background: var(--info-bg);   color: var(--indigo-lift); }
.alert.success { border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.alert.success .ai { background: var(--ok-bg);     color: var(--ok); }
.alert.warning { border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
.alert.warning .ai { background: var(--warn-bg);   color: var(--warn); }
.alert.error   { border-color: color-mix(in srgb, var(--danger) 45%, transparent); }
.alert.error .ai   { background: var(--danger-bg); color: var(--danger); }

/* -----------------------------------------------------------------------------
   BANNER - full-width notice bar (e.g. scheduled maintenance).
   -------------------------------------------------------------------------- */
.banner {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  padding: 11px 18px; border-radius: 13px;
  background: linear-gradient(90deg, var(--info-bg), transparent 70%);
  border: 1px solid rgba(123,103,240,.32);
  font-size: 13.5px; color: var(--text);
}
.banner b { font-weight: 700; }
.banner span { color: var(--muted); }


/* --- ./components/blocks.css --- */
/* =============================================================================
   Components - Content Blocks
   Stats, numbered feature rows, pillars and dividers.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   GROUP LABEL - mono uppercase heading above a group of rows/cards (e.g.
   "Company", "Legal" on Resources). Spacing comes from the global tokens
   --group-gap / --group-gap-below so every group heading breathes the same.
   Every group label gets the same top gap. When a label is the first thing in
   a section, the section's own rhythm (--section-pad) already spaces it, so it
   skips its top margin instead of stacking the two gaps.
   -------------------------------------------------------------------------- */
.res-group-label {
  margin: var(--group-gap) 0 var(--group-gap-below);
  font-family: var(--font-mono);
  font-size: 18px;
  line-height: 1.1;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--eyebrow);
}
.section > .res-group-label:first-child { margin-top: 0; }

/* -----------------------------------------------------------------------------
   STAT - a big metric number. Pair with a .small-t caption beneath. Add
   .text-grad for the animated indigo sweep (e.g. "−63%").
   -------------------------------------------------------------------------- */
.stat-num {
  font-weight: 800; font-size: 46px; letter-spacing: -.03em;
  color: var(--text); line-height: 1;
}

/* -----------------------------------------------------------------------------
   FEATURE ROW (.ap-row) - numbered list of capabilities. A mono number (.ap-n)
   + heading + copy, with an indigo accent bar that grows in on hover.
   Structure: <div class="ap-row"><div class="ap-n">01</div>
              <div><h3>…</h3><p>…</p></div></div>
   -------------------------------------------------------------------------- */
.ap-row,
.res-bar {
  position: relative;
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr);
  gap: 22px;
  padding: 28px 6px 28px 18px;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
  color: inherit;
  transition: background .34s ease, color .34s ease;
}
.ap-row::before,
.res-bar::before {
  content: "";
  position: absolute;
  left: 0;
  top: 20px;
  bottom: 20px;
  width: 4px;
  border-radius: 4px;
  background: var(--indigo-bright);
  box-shadow: 0 0 12px var(--indigo-bright);
  transform: scaleY(0);
  transform-origin: center;
  opacity: 0;
  transition: transform var(--motion-hover), opacity .34s ease;
}
.ap-row:hover,
.res-bar:hover {
  background: transparent;
}
.ap-row:hover::before,
.res-bar:hover::before { transform: scaleY(1); opacity: 1; }
.ap-n,
.res-n {
  display: inline-block;
  font-family: var(--font-mono); font-size: 20px; color: var(--indigo-bright);
  font-weight: 800;
  transform-origin: left center; transition: transform var(--motion-hover), color .34s ease;
}
.ap-row:hover .ap-n,
.res-bar:hover .res-n { transform: scale(1.85); color: var(--indigo-lift); }
.ap-row h3,
.res-bar h3,
.res-bar h4 {
  display: block;
  margin: 0;
  transition: transform var(--motion-hover), color .34s ease;
  transform-origin: left center;
}
.ap-row:hover h3,
.res-bar:hover h3,
.res-bar:hover h4 { transform: scale(1.065); color: var(--text); }
.ap-row p,
.res-bar p { margin: 7px 0 0; transform-origin: left center; transition: transform var(--motion-hover), color .34s ease; }
.ap-row:hover p,
.res-bar:hover p {
  transform: scale(1.025);
  color: var(--muted);
}

/* -----------------------------------------------------------------------------
   PILLAR - column in a multi-part feature strip (dividers between columns).
   -------------------------------------------------------------------------- */
.pillar { padding: 30px 28px 28px 0; border-bottom: 1px solid var(--line); }
.pillar + .pillar { border-left: 1px solid var(--line); padding-left: 28px; }
.pillar h3 { margin: 0 0 9px; }
.pillar p { margin: 0; }
@media (max-width: 760px) { .pillars { grid-template-columns: 1fr; } .pillar + .pillar { border-left: 0; padding-left: 0; } }

/* -----------------------------------------------------------------------------
   DIVIDER - thin horizontal rule between sections.
   Always carries symmetric breathing room above AND below so it's never jammed
   against the content on either side, wherever it's dropped in. (A divider used
   as the FIRST child of a .section gets its top margin zeroed in frame.css - the
   section's own top padding already handles the space above it there.)
   -------------------------------------------------------------------------- */
.divider { height: 1px; background: var(--line); border: 0; margin: var(--divider-gap, 44px) 0; }

/* -----------------------------------------------------------------------------
   METRIC GLANCE (.glance) - compact KPI/stat groups, including the metric callouts
   used in advisor/event sections. The number lifts and shimmers on hover while
   the caption slides slightly to keep the interaction quiet but noticeable.
   -------------------------------------------------------------------------- */
.glance {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: clamp(26px, 4vw, 52px);
}
.glance-cell { padding: 0; }
/* Glance cells hosted inside glass panels (Onboarding "at a glance"). */
.panel.glance-cell { padding: 28px; }
.panel .accent-line + .glance-num { margin-top: 16px; }
.glance-num {
  display: inline-block;
  transform-origin: left center;
  font-weight: 800;
  font-size: clamp(30px, 3.4vw, 44px);
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--text);
  transition: transform var(--motion-hover), color .34s ease, text-shadow .34s ease;
}
.glance-cell:hover .glance-num {
  transform: scale(1.045);
  color: var(--indigo-lift);
  animation: none;
  text-shadow: none;
}
.glance-num .u { color: var(--indigo-bright); }
.glance-cell:hover .glance-num .u {
  color: var(--indigo-lift);
  animation: none;
  text-shadow: none;
}
.glance-cell p {
  transform-origin: left center;
  transition: color .34s ease, transform var(--motion-hover);
}
.glance-cell:hover p {
  color: var(--muted);
  transform: scale(1.03);
}
/* -----------------------------------------------------------------------------
   STYLE GUIDE SCAFFOLD - global documentation layout helpers. These keep the
   guide itself on the same grid, spacing, and object language as the site.
   -------------------------------------------------------------------------- */
.ds-grid { display: grid; gap: 26px; }
.ds-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.ds-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.ds-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.style-object {
  position: relative;
  display: grid;
  grid-template-columns: minmax(180px, .55fr) minmax(0, 1fr);
  gap: clamp(18px, 4vw, 42px);
  align-items: start;
  padding: 28px 0;
  border-top: 1px solid var(--line);
}
.style-object:first-child { border-top: 0; padding-top: 0; }
.style-object.is-wide .style-object-sample { grid-column: 1 / -1; }
.style-object-name {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  font-weight: 750;
  color: var(--text);
}
.style-object-use {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}
.style-object-code {
  display: inline-block;
  margin-top: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.45;
  color: var(--dim);
}
.new-style-marker {
  position: absolute;
  left: clamp(-58px, -4.4vw, -42px);
  top: 24px;
  width: 30px;
  height: 30px;
  border: 1px solid color-mix(in srgb, var(--indigo-bright) 52%, var(--line));
  border-radius: 8px;
  background: linear-gradient(145deg, var(--indigo-bright), var(--indigo));
  box-shadow: 0 8px 22px rgba(83, 51, 236, .34);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: opacity .22s ease, transform var(--motion-window), filter .22s ease;
}
.new-style-marker:hover,
.new-style-marker:focus-visible {
  transform: scale(1.12);
  filter: brightness(1.08);
}
.new-style-marker img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  display: block;
}
.style-object.is-acknowledged .new-style-marker { opacity: 0; pointer-events: none; }

/* ----------------------------------------------------------------------------- 
   RESOURCE ROWS (.res-bar) - large linked rows used on Resources and index pages.
   A mono number, text group, and arrow icon share one scan-friendly row.
   -------------------------------------------------------------------------- */
.res-list { display: grid; }
.res-bar {
  grid-template-columns: 68px minmax(0, 1fr) auto;
  text-decoration: none;
}
.res-go {
  color: var(--dim);
  display: flex;
  flex: 0 0 auto;
  align-self: center;
  transition: transform var(--motion-hover), color .34s ease;
}
.res-go svg {
  width: 30px;
  height: 30px;
  display: block;
  transform-origin: center;
  transition: transform var(--motion-hover);
}
.res-bar:hover .res-go {
  color: var(--indigo-bright);
}
.res-bar:hover .res-go svg { transform: none; }
.res-bar.cta h3,
.res-bar.cta h4 { color: var(--indigo-lift); }
.res-bar.cta .res-n,
.res-bar.cta .res-go { color: var(--indigo-bright); }
[data-theme="light"] .ap-n,
[data-theme="light"] .res-n,
[data-theme="light"] .res-bar.cta h3,
[data-theme="light"] .res-bar.cta h4,
[data-theme="light"] .res-bar.cta .res-n,
[data-theme="light"] .res-bar.cta .res-go {
  color: var(--indigo);
}

/* ----------------------------------------------------------------------------- 
   LEGAL ARTICLE (.legal) - long-form Terms/Privacy copy with calm hierarchy.
   -------------------------------------------------------------------------- */
.legal { max-width: 760px; }
.legal-meta {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 36px;
}
.legal h2 {
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--text);
  margin: 44px 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.legal h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 8px; }
.legal p {
  font-size: 16px;
  line-height: 1.72;
  color: var(--muted);
  margin: 14px 0 0;
}
.legal p.caps {
  font-size: 13.5px;
  line-height: 1.65;
  letter-spacing: .01em;
  color: var(--dim);
}
.legal strong { color: var(--text); font-weight: 600; }

/* h3 = a question inside an FAQ block. Sits clearly below h2 (no rule above it,
   smaller, tighter) so the section hierarchy still reads at a glance. */
.legal h3 {
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -.005em;
  color: var(--text);
  margin: 28px 0 0;
}
/* Lists share the exact type of .legal p so a bulleted clause and a prose
   clause sit on the same rhythm. Marker picks up the link indigo. */
.legal ul {
  margin: 12px 0 0;
  padding-left: 20px;
  list-style: disc;
}
.legal li {
  font-size: 16px;
  line-height: 1.72;
  color: var(--muted);
  margin: 6px 0 0;
}
.legal li::marker { color: var(--indigo-lift); }
.legal li strong { color: var(--text); font-weight: 600; }
.legal a {
  position: relative;
  color: var(--indigo-lift);
  text-decoration: none;
}
.legal a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--motion-hover);
}
.legal a:hover::after { transform: scaleX(1); }
.legal address {
  font-style: normal;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.7;
  margin-top: 14px;
}

/* ----------------------------------------------------------------------------- 
   VERTICAL MARQUEE (.vmarquee) - stacked institution names used for pedigree.
   -------------------------------------------------------------------------- */
.vmarquee {
  position: relative;
  height: clamp(320px, 34vw, 430px);
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  -webkit-mask-image: linear-gradient(transparent, #000 18%, #000 82%, transparent);
  mask-image: linear-gradient(transparent, #000 18%, #000 82%, transparent);
}
.marquee-stack {
  display: grid;
  gap: var(--copy-stack-gap, 24px);
  align-content: start;
  justify-items: center;
  text-align: center;
}
.marquee-stack .eyebrow { margin-bottom: 0; }
.marquee-stack .vmarquee { width: 100%; }
.marquee-stack .vmarquee-name { text-align: center; }
.vmarquee-track {
  display: flex;
  flex-direction: column;
  will-change: auto;
  animation: vmarqueeMove 17s linear infinite;
}
.vmarquee-group {
  display: flex;
  flex-direction: column;
  gap: 26px;
  padding-bottom: 26px;
}
.vmarquee-name {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -.018em;
  line-height: 1;
  color: var(--muted);
}
@keyframes vmarqueeMove {
  from { transform: translateY(0); }
  to { transform: translateY(-50%); }
}
@media (prefers-reduced-motion: reduce) { .vmarquee-track { animation: none; } }

/* ----------------------------------------------------------------------------- 
   TEAM CTA (.team-cta) - compact indigo text+arrow link used after team copy.
   -------------------------------------------------------------------------- */
.team-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 0;
  min-height: 43px;
  padding: 15px 24px 13px;
  border-radius: 999px;
  background: var(--indigo);
  color: var(--on-accent);
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  white-space: nowrap;
  box-shadow: 0 4px 18px -6px var(--indigo-bright);
  transition: transform var(--motion-window), background .34s ease, box-shadow .34s ease;
}
.team-cta:hover { background: var(--indigo-2); transform: scale(1.04); }
.team-cta svg {
  width: 18px;
  height: 18px;
  transition: transform .72s cubic-bezier(.18, .95, .22, 1.18);
}
.team-cta:hover svg { animation: arrowNudge 2s ease-in-out infinite; }
.team-cta.is-spaced { margin-top: 30px; }

.center-stack {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.section-cta { margin-top: 56px; }
.center-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: center;
}
.center-row.is-spaced { margin-top: 24px; }
.split-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: clamp(32px, 6vw, 72px);
  align-items: center;
}
.split-grid.is-hero-marquee {
  grid-template-columns: minmax(0, 1.08fr) minmax(330px, .58fr);
  align-items: stretch;
  gap: clamp(34px, 7vw, 96px);
}
.split-grid.is-hero-marquee .sec-head { margin-bottom: 0; }
.split-grid.is-hero-marquee .vmarquee {
  align-self: stretch;
  margin-top: calc(var(--fs-eyebrow) * 1.1 + 16px);
  height: calc(100% - (var(--fs-eyebrow) * 1.1 + 16px));
  min-height: 0;
  justify-self: center;
  width: min(100%, 420px);
  display: flex;
  align-items: center;
}
/* The track is lifted out of flow so the endless name stack can't inflate the
   row height - the window then stretches to match the text column exactly. */
.split-grid.is-hero-marquee .vmarquee-track {
  position: absolute;
  inset: 0;
  width: 100%;
}
.split-grid.is-hero-marquee .vmarquee-name { text-align: center; }
.split-grid.is-hero-mark {
  grid-template-columns: minmax(0, 1fr) minmax(240px, .44fr);
  align-items: start;
  gap: clamp(34px, 7vw, 96px);
}
.split-grid.is-hero-mark .sec-head { margin-bottom: 0; }
/* Hero with a featured card riding shotgun (Thought Leadership) - same family
   as .is-hero-mark (About's metal logo) and .is-hero-marquee (Our Team's name
   list): text column left, the feature object right, starting below the
   eyebrow line and ENDING level with the text column (align-items: stretch +
   a compact type scale inside the card keep its content within that height). */
.split-grid.is-hero-feature {
  grid-template-columns: minmax(0, 1fr) minmax(380px, .9fr);
  align-items: stretch;
  gap: clamp(34px, 6vw, 80px);
}
.split-grid.is-hero-feature .sec-head { margin-bottom: 0; }
.split-grid.is-hero-feature .tl-feat {
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr;   /* excerpt block absorbs any spare height */
  margin-top: calc(var(--fs-eyebrow) * 1.1 + 16px);
  height: calc(100% - (var(--fs-eyebrow) * 1.1 + 16px));
  min-height: 0;
}
/* Compact scale so the card's content fits the header's height. */
.split-grid.is-hero-feature .tl-feat-main { padding-bottom: 0; }
.split-grid.is-hero-feature .tl-feat-main .h2 {
  font-size: clamp(22px, 1.9vw, 28px);
  margin-top: 14px;
  max-width: none;
}
.split-grid.is-hero-feature .tl-feat-author { margin-top: 16px; }
.split-grid.is-hero-feature .tl-feat-aside {
  padding-top: 16px;
  gap: 12px;
  min-height: 0;
}
.split-grid.is-hero-feature .tl-feat-aside .body-t {
  font-size: 15.5px;
  line-height: 1.6;
  /* Clamp the excerpt so a long standfirst can never overflow the card. */
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hero-mark-window {
  margin-top: calc(var(--fs-eyebrow) * 1.1 + 16px);
  height: clamp(168px, 16vw, 232px);
  display: grid;
  place-items: center;
  overflow: visible;
  justify-self: center;
  isolation: isolate;
}
.hero-mark-window img {
  width: min(100%, 360px);
  height: auto;
  display: block;
  object-fit: contain;
  filter:
    drop-shadow(0 18px 38px color-mix(in srgb, var(--indigo-bright) 26%, transparent))
    drop-shadow(0 0 58px color-mix(in srgb, var(--indigo-bright) 16%, transparent));
}
.split-grid.is-top { align-items: start; }
.copy-stack {
  --copy-stack-gap: 24px;
  display: grid;
  gap: var(--copy-stack-gap);
  align-content: start;
}
.copy-stack > * { margin-top: 0 !important; margin-bottom: 0 !important; }
.copy-stack .team-cta { margin-top: 0; justify-self: start; }
.split-grid.is-top:has(.marquee-stack) { align-items: stretch; }
.split-grid.is-top:has(.marquee-stack) .copy-stack { height: 100%; }
.split-grid.is-top:has(.marquee-stack) .marquee-stack {
  height: 100%;
  grid-template-rows: auto minmax(0, 1fr);
  align-content: stretch;
}
.split-grid.is-top:has(.marquee-stack) .marquee-stack .vmarquee { height: auto; min-height: 0; }
.split-grid.is-team-marquee {
  align-items: stretch;
}
.split-grid.is-team-marquee .copy-stack,
.split-grid.is-team-marquee .marquee-stack {
  height: 100% !important;
}
.split-grid.is-team-marquee .marquee-stack {
  grid-template-rows: auto minmax(0, 1fr) !important;
  align-content: stretch !important;
  align-self: stretch;
}
.split-grid.is-team-marquee .marquee-stack .vmarquee {
  height: auto !important;
  max-height: none;
  -webkit-mask-image: linear-gradient(transparent, #000 12%, #000 78%, transparent);
  mask-image: linear-gradient(transparent, #000 12%, #000 78%, transparent);
}
/* Same out-of-flow trick as the hero marquee: the window's bottom edge now
   lands level with the "Meet the team" button instead of running past it. */
.split-grid.is-team-marquee .marquee-stack .vmarquee-track {
  position: absolute;
  inset: 0;
}
.vmarquee.is-team-window {
  border-top: 0;
  border-bottom: 0;
}
@media (max-width: 860px) {
  .ds-3,
  .ds-2,
  .style-object,
  .split-grid.is-hero-marquee,
  .split-grid.is-team-marquee,
  .split-grid.is-hero-feature,
  .split-grid.is-hero-mark { grid-template-columns: 1fr; }
  .split-grid.is-hero-marquee .vmarquee,
  .split-grid.is-hero-feature .tl-feat,
  .hero-mark-window { margin-top: 0; }
  /* Stacked below the copy there's no column height to mirror. */
  .split-grid.is-hero-feature .tl-feat { height: auto; }
  /* Stacked below the copy there is no text column to mirror, so the marquee
     windows fall back to a fixed height (out-of-flow tracks have none). */
  .split-grid.is-hero-marquee .vmarquee,
  .split-grid.is-team-marquee .marquee-stack .vmarquee { height: clamp(240px, 56vw, 320px) !important; }
  .new-style-marker {
    position: static;
    margin-bottom: 12px;
  }
}

/* -----------------------------------------------------------------------------
   EVENT ROWS (.ev-list / .ev-row) - Events page listings. A centred date cell,
   the event text, and a right-side action share one row. Modifiers:
     .is-live   linked upcoming event (indigo border + Register button)
     .is-past   archive rows (date dims to match the muted copy)
   -------------------------------------------------------------------------- */
.ev-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 8px;
}
.ev-row {
  display: grid;
  /* 206px, not 150px: the widest kind label we carry is "Webinar recording",
     which needs 176px once the status dot and its gap are counted, plus the
     26px cell padding. At 150px it wrapped onto two lines with the dot stuck
     to the first one, which read as a rendering fault rather than a choice.
     The date cell is centred, so shorter labels just get more air around them.
     Measured in the browser, not guessed. If a longer kind is ever added,
     re-measure rather than assuming this still holds. */
  grid-template-columns: 206px 1fr auto;
  gap: 26px;
  align-items: center;
  padding: 24px 30px;
}
a.ev-row {
  text-decoration: none;
  border-color: var(--brd-hover);
}
.ev-date {
  text-align: center;
  border-right: 1px solid var(--line);
  padding-right: 26px;
  min-width: 104px;
}
.ev-when {
  font-weight: 800;
  font-size: 21px;
  color: var(--text);
  line-height: 1.05;
  white-space: nowrap;
}
.ev-row.is-past .ev-when { color: var(--muted); }
.ev-kind {
  font-size: 12.5px;
  color: var(--indigo-lift);
  margin-top: 7px;
}
.ev-row.is-past .ev-kind { color: var(--dim); }
.ev-row .h4 { margin: 0; }
.ev-row .small-t { margin-top: 8px; max-width: 560px; }
.ev-row .btn { white-space: nowrap; }
.ev-tag {
  font-size: 11px;
  color: var(--dim);
  white-space: nowrap;
}
@media (max-width: 700px) {
  .ev-row { grid-template-columns: 1fr; gap: 14px; }
  .ev-date {
    border-right: 0;
    border-bottom: 1px solid var(--line);
    padding: 0 0 12px;
    text-align: left;
  }
}

/* -----------------------------------------------------------------------------
   ONBOARDING TRACK (.ob-track / .ob-phase) - the five-step process timeline.
   A vertical rail connects numbered circular nodes; each phase carries a mono
   week kicker (.ob-wk), heading, sub, and checklist. The number lives ONLY in
   the node (no duplicated "Week 4" + "04"). Hovering a phase lights its node
   indigo and lifts the heading - the same interaction language as .ap-row.
   Structure: <div class="ob-track">
                <div class="ob-phase"><div class="ob-node">01</div>
                  <div><div class="ob-wk">Week 1</div><h3>…</h3>
                       <p class="ob-sub">…</p><ul class="ob-list">…</ul></div>
                </div> …
   -------------------------------------------------------------------------- */
.ob-track {
  position: relative;
  margin-top: 18px;
}
/* The connecting rail - runs behind the (solid) nodes, fading out at the end. */
.ob-track::before {
  content: "";
  position: absolute;
  left: 26px;
  top: 12px;
  bottom: 46px;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(
    color-mix(in srgb, var(--indigo-bright) 55%, transparent),
    color-mix(in srgb, var(--indigo-bright) 30%, transparent) 70%,
    transparent);
}
.ob-phase {
  position: relative;
  display: grid;
  grid-template-columns: 54px 1fr;
  gap: clamp(20px, 4vw, 44px);
  padding: 6px 0 46px;
}
.ob-phase:last-child { padding-bottom: 10px; }
.ob-node {
  position: relative;
  z-index: 1;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 700;
  color: var(--indigo-lift);
  background: var(--elev);
  border: 1px solid var(--brd-strong);
  transition: background .34s ease, color .34s ease, border-color .34s ease,
    box-shadow .34s ease, transform var(--motion-hover);
}
.ob-phase:hover .ob-node {
  background: var(--indigo);
  color: var(--on-accent);
  border-color: transparent;
  box-shadow: 0 0 24px color-mix(in srgb, var(--indigo-bright) 60%, transparent);
  transform: scale(1.08);
}
.ob-wk {
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--indigo-lift);
  margin-bottom: 8px;
}
.ob-phase h3 {
  margin: 0;
  font-size: clamp(20px, 2vw, 26px);
  letter-spacing: -.015em;
  transform-origin: left center;
  transition: transform var(--motion-hover);
}
.ob-phase:hover h3 { transform: scale(1.045); }
.ob-sub {
  margin: 8px 0 0;
  color: var(--muted);
  font-size: 16px;
  line-height: 1.6;
}
.ob-list {
  list-style: none;
  padding: 0;
  margin: 18px 0 0;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.ob-list li {
  position: relative;
  padding-left: 26px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.55;
}
.ob-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--indigo-bright);
  box-shadow: 0 0 10px var(--indigo-bright);
}
/* Footnote under the track ("timeline is driven by scope…"). */
.ob-note {
  margin-top: 26px;
  color: var(--dim);
  max-width: 60ch;
}
@media (max-width: 520px) {
  .ob-track::before { left: 21px; }
  .ob-phase { grid-template-columns: 44px 1fr; gap: 16px; }
  .ob-node { width: 44px; height: 44px; font-size: 14px; }
}

/* Desktop: lay the five phases HORIZONTALLY across the full width so the page
   is not a tall left rail with a blank right half. Nodes sit on one horizontal
   rail; week / heading / sub / checklist stack beneath each. Mobile keeps the
   vertical rail above. */
@media (min-width: 900px) {
  .ob-track {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: clamp(16px, 2vw, 30px);
    margin-top: 30px;
  }
  .ob-track::before {
    left: 5%;
    right: 5%;
    top: 27px;
    bottom: auto;
    width: auto;
    height: 2px;
    background: linear-gradient(90deg,
      transparent,
      color-mix(in srgb, var(--indigo-bright) 45%, transparent) 10%,
      color-mix(in srgb, var(--indigo-bright) 45%, transparent) 90%,
      transparent);
  }
  .ob-phase {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    grid-template-columns: none;
    gap: 14px;
    padding: 0;
  }
  .ob-phase:last-child { padding-bottom: 0; }
  .ob-wk { margin-bottom: 0; }
  .ob-phase h3 { font-size: clamp(18px, 1.4vw, 22px); }
  .ob-sub { margin-top: 0; font-size: 15px; }
  .ob-list { margin-top: 10px; gap: 8px; }
  .ob-list li { font-size: 14px; padding-left: 22px; line-height: 1.5; }
}

/* Glance cell that holds a short phrase instead of a number keeps it readable. */
.glance-num.gl-text { font-size: clamp(26px, 3vw, 40px); letter-spacing: -.01em; line-height: 1.05; }
.glance-num.gl-text .u { display: block; font-size: .5em; color: var(--muted); letter-spacing: 0; margin-top: 4px; }

/* Onboarding glance phrase: clean two-line format. */
.glance-num.gl-text { font-size: clamp(26px, 2.8vw, 38px); line-height: 1.12; letter-spacing: -.01em; }
.glance-num.gl-text .u { display: inline; font-size: 1em; color: inherit; margin: 0; }

/* Onboarding process: bigger, more readable step text. */
@media (min-width: 900px) {
  .ob-phase h3 { font-size: clamp(20px, 1.6vw, 25px); }
  .ob-sub { font-size: 17px; }
  .ob-list li { font-size: 16px; }
  .ob-wk { font-size: 13px; }
}


/* --- ./components/bullets.css --- */
/* =============================================================================
   Bullets - two reusable list styles, one shared marker
   ============================================================================= */

.f-row .f-ico {
  position: absolute;
  width: 4px;
  height: auto;
  border-radius: 4px;
  background: var(--indigo-bright);
  box-shadow: none;
  opacity: .82;
  transform: scaleY(.36);
  transform-origin: center;
  animation: none;
  will-change: auto;
  backface-visibility: hidden;
  transition: transform var(--motion-hover), opacity .34s ease, box-shadow .34s ease;
}

.prose li:hover::before,
.f-row:hover .f-ico {
  transform: scaleY(1);
  opacity: 1;
  box-shadow: 0 0 10px color-mix(in srgb, var(--indigo-bright) 48%, transparent);
}

/* Plain bullets ------------------------------------------------------------- */
.prose ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.prose li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 0;
  font-size: 17px;
  line-height: 1.62;
  color: var(--muted);
  transform-origin: left center;
  backface-visibility: hidden;
  transition: transform var(--motion-hover), color .34s ease;
}

.prose li::before {
  content: "";
  flex: 0 0 13px;
  width: 13px;
  height: 2px;
  border-radius: 2px;
  background: var(--indigo-bright);
  margin-top: calc(1.62em / 2 - 1px);
  opacity: .72;
  box-shadow: 0 0 0 transparent;
  animation: none;
  transform: none !important;
  transition: opacity .34s ease, box-shadow .34s ease;
}

.prose li:hover::before {
  height: 2px;
}

.prose li:hover {
  transform: scale(1.035);
  color: var(--text);
}

/* Feature rows -------------------------------------------------------------- */
.f-list { display: block; }

.f-row {
  position: relative;
  display: block;
  padding: 20px 6px 20px 30px;
  border-bottom: 1px solid var(--line);
  background: transparent;
  transition: color .34s ease;
}

.f-row:hover { background: transparent; }

.f-row .f-ico {
  left: 8px;
  top: 20px;
  bottom: 20px;
}

.f-row h4,
.f-row .h4 {
  margin: 0;
  transform-origin: left center;
  backface-visibility: hidden;
  transition: transform var(--motion-hover), color .34s ease;
}

.f-row:hover h4,
.f-row:hover .h4 {
  transform: scale(1.045);
  color: var(--text);
}

.f-row p,
.f-row .small-t {
  margin: 6px 0 0;
  transform-origin: left center;
  backface-visibility: hidden;
  transition: transform var(--motion-hover), color .34s ease;
}

.f-row:hover p,
.f-row:hover .small-t {
  transform: scale(1.012);
}

/* Two-column editorial feature grid (Platform Orchestration / Impact lists). */
.f-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 54px;
  border-top: 1px solid var(--line);
}
@media (max-width: 760px) { .f-2 { grid-template-columns: 1fr; } }
.f-2.is-spaced { margin-top: 34px; }

/* Numbered feature row: a mono index replaces the bar marker.
   Markup: <div class="f-row"><div class="f-num">01</div><div>…</div></div> */
.f-row:has(.f-num) {
  display: grid;
  grid-template-columns: 40px 1fr;
  gap: 18px;
  padding-left: 6px;
  align-items: start;
}
.f-num {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--indigo-bright);
  padding-top: 3px;
  transform-origin: left center;
  transition: transform var(--motion-hover);
}
.f-row:hover .f-num { transform: scale(1.28); }

/* Plain variant: numbered magnify rows with no dividers (home onboarding,
   platform AI orchestration). is-onecol stacks them in a single column. */
.f-2.is-plain { border-top: 0; }
.f-2.is-plain .f-row { border-bottom: 0; }
.f-2.is-onecol { grid-template-columns: 1fr; }

/* Bigger numbers and stronger magnify on hover (match the resources numbers). */
.f-num { font-size: 17px; }
.f-row:hover .f-num { transform: scale(1.4); }
.f-row:hover h4, .f-row:hover .h4 { transform: scale(1.08); }
.f-row:hover p, .f-row:hover .small-t { transform: scale(1.03); }


/* --- ./components/platform.css --- */
/* =============================================================================
   Platform modules - the marketing blocks shared by the Home, Platform, and
   Resolution Roundtable pages: hero logo stage, process flow, pillars,
   architecture stack, horizontal marquees, connected stepper, product
   monitors, and the network hub. All token-driven; nothing page-local.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   HERO LOGO STAGE (.hero-logo-stage) - the big metal wordmark over the hero.
   Static image only for now; the intro reveal video/animation is intentionally
   NOT ported yet (drop a .hero-logo-video in later when the animation lands).
   -------------------------------------------------------------------------- */
.hero-logo-stage {
  position: relative;
  z-index: 3;
  width: clamp(500px, 48vw, 760px);
  max-width: 100%;
  height: clamp(92px, 9.2vw, 145px);
  margin: 0 auto 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
}
.hero-logo-static {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 18px 42px rgba(91, 69, 240, .42));
}
/* On light backgrounds the big soft glow reads as blur - keep a tight shadow. */
[data-theme="light"] .hero-logo-static { filter: drop-shadow(0 8px 18px rgba(91, 69, 240, .16)); }

/* Oversized home headline under the logo. */
.hero-grand {
  font-size: clamp(46px, 7.2vw, 98px);
  line-height: .96;
  letter-spacing: -.045em;
  text-wrap: balance;
}

/* Hero sections that centre everything (home + platform overview). */
.section.is-hero-stage {
  min-height: 90vh;
  justify-content: center;
  position: relative;
  overflow: visible;
}
.section.is-hero-stage .eyebrow { justify-content: center; }
.hero-actions {
  margin-top: 32px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
}
.hero-flow {
  width: 100%;
  max-width: 980px;
  margin-top: 58px;
  text-align: left;
}

/* Hero rhythm: give the grey lead room under the gradient headline, and make
   the two hero actions equal width so Request Demo and Explore The Platform
   read as a matched pair. */
.section.is-hero-stage .hero-grand { margin-top: 8px; }
.section.is-hero-stage .lead { margin-top: 30px; }
.hero-actions .btn { min-width: 232px; }

/* Small inline brand mark (arch band, CTA windows). */
.mark-inline {
  vertical-align: middle;
  filter: drop-shadow(0 4px 12px rgba(91, 69, 240, .4));
}
.cta-shine .mark-inline { height: 46px; margin-bottom: 24px; }

/* -----------------------------------------------------------------------------
   STRIKETHROUGH EMPHASIS (.strike) - "Not another ~dashboard~" red strike.
   -------------------------------------------------------------------------- */
.strike { position: relative; color: var(--dim); white-space: nowrap; }
.strike::after {
  content: "";
  position: absolute;
  left: -3%;
  right: -3%;
  top: 54%;
  height: .085em;
  min-height: 3px;
  background: var(--danger);
  border-radius: 3px;
  transform: rotate(-3.5deg);
}

/* -----------------------------------------------------------------------------
   ARCHITECTURE STACK (.arch-band / .arch-cols) - the orchestration layer band
   above four engine columns, joined by a fading connector line.
   -------------------------------------------------------------------------- */
.arch-band {
  border: 1px solid var(--brd-hover);
  border-radius: 18px;
  background: var(--glass);
  backdrop-filter: blur(12px) saturate(140%);
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  box-shadow: var(--panel-glow), inset 0 1px 0 var(--glass-hi);
  padding: 26px 28px;
  text-align: center;
}
.arch-band .mark-inline { height: 30px; }
.arch-band .small-t { max-width: 560px; margin-left: auto; margin-right: auto; }
.arch-link { display: flex; align-items: center; gap: 10px; justify-content: center; }
.arch-link span { width: 2px; height: 18px; background: linear-gradient(var(--indigo-bright), transparent); }
.arch-cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--brd);
  border-radius: 18px;
  overflow: hidden;
  background: var(--panel);
}
.arch-col { padding: 24px; transition: background .28s ease; }
.arch-col + .arch-col { border-left: 1px solid var(--line); }
.arch-col:hover { background: var(--hover); }
.arch-col .f-ico { margin-bottom: 14px; }
/* Static square marker inside arch columns (the f-ico here is not a bullet). */
.arch-col .f-ico {
  position: static;
  width: 13px;
  height: 13px;
  border-radius: 3px;
  background: var(--indigo-bright);
  box-shadow: 0 0 10px var(--indigo-bright);
  opacity: 1;
  transform: none;
}
/* "Connects to…" marquee footer under the stack. */
.arch-connects { text-align: center; margin-top: 30px; }
.arch-connects .mq-label { margin-bottom: 16px; font-size: 11px; }
@media (max-width: 860px) {
  .arch-cols { grid-template-columns: 1fr 1fr; }
  .arch-col:nth-child(3) { border-left: 0; }
  .arch-col:nth-child(n+3) { border-top: 1px solid var(--line); }
}
@media (max-width: 520px) {
  .arch-cols { grid-template-columns: 1fr; }
  .arch-col + .arch-col { border-left: 0; border-top: 1px solid var(--line); }
}

/* -----------------------------------------------------------------------------
   HORIZONTAL MARQUEE (.marquee) - seamless auto-rolling ticker (two identical
   groups translate -50%). Variants: .mq-name mono tokens with indigo dots,
   .trust-item bordered cells, .plogo partner logo strip (.pmarquee mask).
   -------------------------------------------------------------------------- */
.marquee {
  position: relative;
  overflow: hidden;
  width: 100%;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee + .marquee { margin-top: 14px; }
/* Speed modifiers (base 42s): .is-fast trust strip, .is-slow logo roll. */
.marquee.is-fast { --mq: 34s; }
.marquee.is-slow { --mq: 72s; }
/* Centred dim caption above a marquee strip. */
.mq-label {
  display: block;
  text-align: center;
  font-size: 11.5px;
  color: var(--dim);
  margin-bottom: 22px;
}
.marquee-track {
  display: flex;
  width: max-content;
  will-change: transform;
  animation: marqueeMove var(--mq, 42s) linear infinite;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-group {
  display: flex;
  align-items: center;
  gap: var(--mq-gap, 30px);
  padding-right: var(--mq-gap, 30px);
  flex: 0 0 auto;
}
@keyframes marqueeMove { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.mq-name {
  display: inline-flex;
  align-items: center;
  gap: var(--mq-gap, 30px);
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: .03em;
  color: var(--muted);
  white-space: nowrap;
  font-weight: 500;
}
.mq-name::after { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--indigo-bright); opacity: .7; }
/* Trust strip: mono cells divided by hairlines, no dot gap. */
.trust-marquee { --mq-gap: 0px; }
.trust-marquee .marquee-group { gap: 0; padding-right: 0; }
.trust-item {
  font-family: var(--font-mono);
  font-size: clamp(15px, 1.7vw, 20px);
  letter-spacing: .05em;
  color: var(--muted);
  padding: 4px 36px;
  border-right: 1px solid var(--line);
  white-space: nowrap;
}
/* Partner-logo strip: theme-swapped logo pairs, slow roll, wide fade mask. */
.plogos { width: 100%; overflow: hidden; }
.plogos .marquee-group { --mq-gap: 40px; }
.plogo { height: 84px; width: auto; display: block; opacity: .82; transition: opacity .25s; }
.plogo-light { display: none; }
[data-theme="light"] .plogo-dark { display: none; }
[data-theme="light"] .plogo-light { display: block; }
.plogo-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(180px, 18vw, 250px);
}
.plogo-item:hover .plogo { opacity: 1; }
.pmarquee {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 11%, #000 89%, transparent);
}
.pmarquee:hover .marquee-track { animation-play-state: running; }

/* -----------------------------------------------------------------------------
   CONNECTED STEPPER (.stepper) - five nodes on a flowing line (How It Works).
   Nodes ping in sequence; the line's gradient drifts continuously.
   -------------------------------------------------------------------------- */
.stepper { position: relative; display: grid; grid-template-columns: repeat(5, 1fr); gap: 22px; }
.stepper::before {
  content: "";
  position: absolute;
  top: 19px;
  left: 2%;
  right: 18%;
  height: 2px;
  background: linear-gradient(90deg, var(--indigo-bright), var(--brd-strong), var(--indigo-bright));
  background-size: 200% 100%;
  opacity: .55;
  animation: lineFlow 6s linear infinite;
}
@keyframes lineFlow { 0% { background-position: 0% 0; } 100% { background-position: 200% 0; } }
.stp { position: relative; }
.stp-node {
  position: relative;
  z-index: 1;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--elev);
  border: 1px solid var(--brd-strong);
  color: var(--indigo-bright);
  font-family: var(--font-mono);
  font-weight: 600;
  box-shadow: 0 0 0 6px var(--bg);
}
.stp h4 { margin: 18px 0 0; }
.stp p { margin: 8px 0 0; }
@media (prefers-reduced-motion: no-preference) {
  .stp-node { animation: stpPing 3s ease-in-out infinite; }
  .stp:nth-child(1) .stp-node { animation-delay: 0s; }
  .stp:nth-child(2) .stp-node { animation-delay: .4s; }
  .stp:nth-child(3) .stp-node { animation-delay: .8s; }
  .stp:nth-child(4) .stp-node { animation-delay: 1.2s; }
  .stp:nth-child(5) .stp-node { animation-delay: 1.6s; }
  @keyframes stpPing {
    0%, 70%, 100% { box-shadow: 0 0 0 6px var(--bg), 0 0 0 0 transparent; }
    35% { box-shadow: 0 0 0 6px var(--bg), 0 0 16px 2px var(--indigo-lift); }
  }
}
@media (max-width: 760px) {
  .stepper { grid-template-columns: 1fr; gap: 0; }
  .stepper::before { display: none; }
  .stp {
    display: grid;
    grid-template-columns: 40px 1fr;
    gap: 16px;
    padding: 18px 0;
    border-top: 1px solid var(--line);
    align-items: start;
  }
  .stp h4 { margin: 8px 0 0; }
}

/* -----------------------------------------------------------------------------
   PRODUCT MONITORS (.dual / .mon) - two framed screens on a soft glow, with
   the feature grid (.pm-grid) beneath. Frame colour flips per theme
   (--mon-frame in tokens.css).
   -------------------------------------------------------------------------- */
.prod-wrap { margin-top: 30px; }
.dual {
  position: relative;
  display: flex;
  gap: 8px;
  align-items: flex-start;
  justify-content: center;
  max-width: 900px;
  margin: 0 auto;
}
.dual::before {
  content: "";
  position: absolute;
  inset: -14% -6% 0;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(58% 60% at 50% 38%, var(--cloud-1), transparent 70%);
  filter: blur(34px);
  pointer-events: none;
}
.mon {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.mon .mon-screen {
  position: relative;
  width: 100%;
  border: 6px solid var(--mon-frame);
  border-bottom: 15px solid var(--mon-frame);
  border-radius: 10px;
  background: var(--mon-frame);
  overflow: hidden;
  box-shadow: var(--shadow), inset 0 0 0 1px var(--brd-strong);
}
.mon .mon-screen::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -10px;
  transform: translateX(-50%);
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--indigo-bright);
  opacity: .6;
}
.mon .mon-screen img { width: 100%; display: block; }
.mon .mon-neck { width: 13%; height: 15px; background: linear-gradient(180deg, var(--brd-strong), var(--elev)); }
.mon .mon-base { width: 36%; height: 5px; border-radius: 3px; background: var(--brd-strong); }
/* Centred "AI at every layer" caption between the monitors and the grid. */
.prod-caption { margin-top: 48px; text-align: center; }
.prod-caption .eyebrow { color: var(--indigo-lift); justify-content: center; }
.prod-caption .small-t { margin: 10px auto 30px; max-width: 56ch; }
.pm-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 38px);
  margin-top: 10px;
}
@media (max-width: 740px) { .pm-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 460px) { .pm-grid { grid-template-columns: 1fr; } }
.pm-cell {
  position: relative;
  padding-top: 20px;
  border-top: 2px solid var(--line);
  transition: border-color .3s ease, transform .3s cubic-bezier(.22, .61, .36, 1);
}
.pm-cell:hover { transform: translateY(-4px); border-color: var(--indigo-bright); }
.pm-cell h4 { margin: 0; transition: color .3s ease; }
.pm-cell:hover h4 { color: var(--indigo-lift); }
.pm-cell p { margin: 8px 0 0; }

/* -----------------------------------------------------------------------------
   NETWORK HUB (.hub) - Roundtable orbit: SmartSettle core, dashed rings, packet
   lines to eight participant nodes. Falls back to a 2-up list under 720px.
   -------------------------------------------------------------------------- */
.hub {
  position: relative;
  width: 100%;
  max-width: 760px;
  margin: 18px auto 0;
  aspect-ratio: 1 / 1;
}
.hub-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.hub-lines line {
  stroke: color-mix(in srgb, var(--indigo-bright) 42%, var(--brd-strong));
  stroke-width: .12;
  stroke-dasharray: .5 1.1;
  animation: hubFlow 3.4s linear infinite;
}
.hub-lines .pkt { fill: var(--indigo-bright); r: .3px; filter: drop-shadow(0 0 1.2px var(--indigo-bright)); opacity: 1; }
.hub-lines .pkt-out { fill: #B7A6FF; }
@keyframes hubFlow { to { stroke-dashoffset: -16; } }
.hub-ring { position: absolute; border-radius: 50%; border: 1px dashed color-mix(in srgb, var(--indigo-bright) 34%, var(--brd-strong)); pointer-events: none; transform-origin: 50% 50%; }
.hub-ring.r1 { inset: 8%; opacity: .8; animation: hubSpin 46s linear infinite; }
.hub-ring.r2 { inset: 26%; border-style: solid; border-color: var(--line); animation: hubSpin 40s linear infinite; }
@keyframes hubSpin { to { transform: rotate(360deg); } }
/* Core medallion: glass disc + breathing halo behind the mark. */
.hub-core {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 34%;
  height: 34%;
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  background: radial-gradient(circle at 50% 38%, var(--info-bg), transparent 74%);
  border: 1px solid var(--brd-hover);
  box-shadow: 0 0 60px -18px var(--indigo-bright), inset 0 1px 0 var(--glass-hi);
  backdrop-filter: blur(6px) saturate(130%);
  -webkit-backdrop-filter: blur(6px) saturate(130%);
  animation: hubBreathe 4.5s ease-in-out infinite;
}
@keyframes hubBreathe {
  0%, 100% { box-shadow: 0 0 46px -20px var(--indigo-bright), inset 0 1px 0 var(--glass-hi); }
  50% { box-shadow: 0 0 74px -12px var(--indigo-bright), inset 0 1px 0 var(--glass-hi); }
}
.hub-core img { width: 44%; max-width: 74px; filter: drop-shadow(0 8px 22px rgba(91, 69, 240, .55)); }
.hub-core b { font-size: 14px; font-weight: 800; color: var(--text); margin-top: 10px; letter-spacing: -.01em; }
/* Participant chips: small glass cards, readable at a glance. */
.hub-node {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 152px;
  text-align: center;
  padding: 12px 12px 13px;
  border-radius: 14px;
  border: 1px solid var(--brd);
  background: var(--glass);
  backdrop-filter: blur(8px) saturate(135%);
  -webkit-backdrop-filter: blur(8px) saturate(135%);
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: border-color .3s ease, transform .3s cubic-bezier(.34, 1.45, .5, 1), box-shadow .3s ease;
}
.hub-node:hover {
  transform: translate(-50%, -50%) scale(1.07);
  border-color: var(--brd-hover);
  box-shadow: 0 10px 30px -12px var(--indigo-bright), inset 0 1px 0 var(--glass-hi);
  z-index: 3;
}
.hub-node::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin: 0 auto 8px;
  background: var(--indigo-bright);
  box-shadow: 0 0 12px var(--indigo-bright);
  animation: markerPulse 2.6s ease-in-out infinite;
}
@keyframes markerPulse {
  0%, 100% { opacity: .6; box-shadow: 0 0 0 transparent; }
  50% { opacity: 1; box-shadow: 0 0 13px var(--indigo-bright), 0 0 6px var(--indigo-bright); }
}
.hub-node b { display: block; font-size: 13.5px; font-weight: 700; color: var(--text); line-height: 1.25; }
.hub-node span { display: block; font-size: 11.5px; color: var(--muted); margin-top: 4px; line-height: 1.35; }
/* Node positions (clock order from 12): top, 1:30, 3, 4:30, 6, 7:30, 9, 10:30. */
.hub-node.p1 { left: 50%; top: 4.5%; }
.hub-node.p2 { left: 82.17%; top: 17.83%; }
.hub-node.p3 { left: 95.5%; top: 50%; }
.hub-node.p4 { left: 82.17%; top: 82.17%; }
.hub-node.p5 { left: 50%; top: 95.5%; }
.hub-node.p6 { left: 17.83%; top: 82.17%; }
.hub-node.p7 { left: 4.5%; top: 50%; }
.hub-node.p8 { left: 17.83%; top: 17.83%; }
.hub-fallback { display: none; }
@media (max-width: 720px) {
  /* Show the real hub visual (was hidden); the list fallback is no longer needed. */
  .hub-fallback { display: none; }
  .hub { margin-top: 8px; }
  .hub-node { width: 96px; padding: 7px 7px 8px; border-radius: 11px; }
  .hub-node b { font-size: 10.5px; line-height: 1.18; }
  .hub-node span { font-size: 9px; line-height: 1.25; margin-top: 2px; }
  .hub-node::before { width: 6px; height: 6px; margin-bottom: 5px; }
}
@media (max-width: 420px) {
  .hub-node { width: 82px; padding: 6px; }
  .hub-node b { font-size: 9.5px; }
  .hub-node span { font-size: 8px; }
}
/* Fallback rows share the aside accent bar. */
.ss-aside { border-left: 2px solid var(--indigo-bright); padding-left: 16px; }
.ss-aside b { font-size: 13px; color: var(--text); }

/* -----------------------------------------------------------------------------
   CALLOUT BAND (.callout-band) - a slim horizontal glass ribbon for secondary
   calls-to-action (e.g. Home's T+1 pointer). Icon | copy | button in one row,
   visually distinct from the big editorial insight cards.
   -------------------------------------------------------------------------- */
.callout-band {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: clamp(18px, 3vw, 34px);
  align-items: center;
  padding: clamp(20px, 2.4vw, 28px) clamp(22px, 2.6vw, 34px);
  border: 1px solid var(--brd-hover);
  border-radius: 18px;
  background: var(--glass);
  backdrop-filter: blur(10px) saturate(140%);
  -webkit-backdrop-filter: blur(10px) saturate(140%);
  box-shadow: var(--panel-glow), inset 0 1px 0 var(--glass-hi);
  text-decoration: none;
  transition: transform var(--motion-window), border-color .3s ease;
}
.callout-band:hover { transform: scale(1.012); }
.callout-band h3 {
  margin: 0;
  font-size: clamp(18px, 1.8vw, 24px);
  letter-spacing: -.015em;
  color: var(--text);
}
.callout-band p {
  margin: 6px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 62ch;
}
.callout-band .btn { white-space: nowrap; }
@media (max-width: 760px) {
  .callout-band { grid-template-columns: 1fr; text-align: left; }
  .callout-band .t1-clock { display: none; }
}

/* Mono clock badge used beside the "T+1 in Europe" eyebrow. */
.eyebrow.has-clock { display: inline-flex; align-items: center; gap: 12px; }
.t1-clock {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: 1px solid var(--brd-strong);
  color: var(--indigo-bright);
}
.t1-clock svg { animation: t1tick 6s steps(12) infinite; transform-origin: center; }
@keyframes t1tick { to { transform: rotate(360deg); } }

/* Platform page utility visuals */
.rc-wall {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 28px;
}
.rc-wall span {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 9px 15px;
  border: 1px solid var(--brd);
  border-radius: var(--radius-pill);
  background: var(--glass);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: border-color .3s ease, color .3s ease, transform var(--motion-window);
}
.rc-wall span:hover {
  color: var(--text);
  border-color: var(--brd-hover);
  transform: var(--window-hover-transform);
}
.rc-wall.is-systems span { min-width: 150px; justify-content: center; }
.timeline-rail {
  position: relative;
  padding: clamp(28px, 3vw, 44px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  align-items: center;
}
.timeline-rail .small-t { grid-column: 1 / -1; margin: 14px 0 0; text-align: center; }
.tl-stop {
  position: relative;
  z-index: 2;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  min-height: 82px;
  border: 1px solid var(--brd);
  border-radius: 18px;
  background: var(--panel);
  font-family: var(--font-mono);
  font-size: clamp(26px, 3vw, 40px);
  font-weight: 800;
  color: var(--muted);
}
.tl-stop.is-now { color: var(--ok); border-color: var(--ok); box-shadow: 0 0 32px -16px var(--ok); }
.tl-stop.is-risk { color: var(--warn); border-color: var(--warn); }
.tl-line {
  position: absolute;
  left: 12%;
  right: 12%;
  top: calc(50% - 24px);
  height: 2px;
  background: var(--brd);
  overflow: hidden;
}
.tl-line i {
  display: block;
  width: 42%;
  height: 100%;
  background: linear-gradient(90deg, transparent, var(--indigo-lift), transparent);
  animation: lineFlow 4.8s linear infinite;
}
@media (max-width: 760px) {
  .timeline-rail { grid-template-columns: 1fr; }
  .tl-line { display: none; }
}


.site-header .nav { gap: clamp(26px, 3vw, 44px); }


/* Platform overview hero no longer carries the metal logo or the flow diagram,
   so drop the 90vh empty stage and tighten the rhythm above the monitors. */
#overview.section.is-hero-stage { min-height: auto; justify-content: flex-start; padding-block: var(--section-pad); }
#overview .hero-grand { font-size: clamp(38px, 5.2vw, 72px); }

/* ---- Two side-by-side showcase cards (Roundtable + Europe T+1). ---- */
.two-card { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(18px, 2.4vw, 28px); }
@media (max-width: 820px) { .two-card { grid-template-columns: 1fr; } }
.showcase-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: clamp(28px, 3vw, 46px); text-decoration: none; }
.showcase-card .sc-title { font-size: clamp(22px, 2vw, 28px); margin: 4px 0; letter-spacing: -.02em; }
.showcase-card .small-t { max-width: 46ch; }
.showcase-card .sc-cta { margin-top: 16px; }
.showcase-card[href] { transition: transform var(--motion-window), border-color .34s ease; }
.showcase-card[href]:hover { transform: scale(1.015); border-color: var(--brd-hover); }

/* ---- Platform monitors: 2x2 zig-zag (monitor / text, text / monitor). ---- */
.mon-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 4.5vw, 72px); align-items: center; }
@media (max-width: 900px) { .mon-grid { grid-template-columns: 1fr; gap: 40px; } }
.mon-copy { display: flex; flex-direction: column; gap: clamp(26px, 3.5vw, 44px); align-items: center; text-align: center; }
.mon-block .lead { margin-top: 10px; }
.mon-block .small-t { margin-top: 8px; }

/* ---- Resolution Roundtable band: visual left, copy right-aligned right. ---- */
.rt-band { display: grid; grid-template-columns: 1fr 1fr; align-items: center; gap: clamp(24px, 4vw, 56px); padding: clamp(30px, 4vw, 56px); text-decoration: none; }
@media (max-width: 820px) { .rt-band { grid-template-columns: 1fr; } }
.rt-band-viz { display: flex; justify-content: center; }
.rt-band-viz img { max-width: 220px; width: 100%; height: auto; }
.rt-band-copy { display: flex; flex-direction: column; align-items: flex-end; text-align: right; gap: 10px; }
@media (max-width: 820px) { .rt-band-copy { align-items: flex-start; text-align: left; } }
.rt-band-copy .sec-intro { max-width: 46ch; }
.rt-band-copy .sc-cta { margin-top: 14px; }
.rt-band[href] { transition: transform var(--motion-window), border-color .34s ease; }
.rt-band[href]:hover { transform: scale(1.01); border-color: var(--brd-hover); }

/* ---- Monitor copy blocks: real headings (not spaced-out eyebrows), readable body. ---- */
.mon-copy { gap: clamp(28px, 3.5vw, 46px); }
.mon-h { font-size: clamp(20px, 1.9vw, 27px); font-weight: 600; letter-spacing: -.015em; line-height: 1.22; color: var(--text); margin: 0; }
.mon-block .lead { font-size: clamp(16px, 1.3vw, 19px); line-height: 1.55; margin-top: 10px; color: var(--muted); }
.mon-block .small-t { font-size: 16px; line-height: 1.66; margin-top: 10px; }
.mon-block .small-t + .small-t { margin-top: 8px; }

/* ---- Roundtable clock: no casing, bigger, smooth continuous spin. ---- */
.t1-clock { width: auto; height: auto; border: 0; }
.t1-clock svg { width: 30px; height: 30px; animation: t1tick 12s linear infinite; }

/* ---- Roundtable hub: bigger centered mark, dotted counter-spinning rings,
   and thin symmetrical diamonds between the parties. ---- */
.hub-core img { width: 62%; max-width: 130px; }
.hub-core b { display: none; }
.hub-ring.r3 { inset: 4.5%; border-style: dashed; border-color: color-mix(in srgb, var(--indigo-bright) 30%, var(--brd-strong)); opacity: .6; animation: hubSpin 58s linear infinite reverse; }
.hub-ring.r4 { inset: 1%; border-style: dashed; border-color: color-mix(in srgb, var(--indigo-bright) 22%, var(--brd-strong)); opacity: .45; animation: hubSpin 72s linear infinite; }
.hub-diamond { fill: none; stroke: color-mix(in srgb, var(--indigo-bright) 26%, var(--brd-strong)); stroke-width: .12; }

/* Roundtable geometry (full .hub only, NOT the homepage .hub-mini): dotted node
   ring enlarged to sit evenly between the inner dashed ring and the outer ring;
   the 8 nodes + both squares ride it; each card is anchored by its pulsing dot
   (16px from the card top) instead of its center, so the dot lands on the corner. */
.hub:not(.hub-mini) { --dot-anchor: 16px; }
.hub:not(.hub-mini) .hub-ring.r3 { inset: 4.5%; }
.hub:not(.hub-mini) .hub-node { transform: translate(-50%, calc(-1 * var(--dot-anchor))); }
.hub:not(.hub-mini) .hub-node:hover { transform: translate(-50%, calc(-1 * var(--dot-anchor))) scale(1.07); }
.hub:not(.hub-mini) .hub-node.p1 { left: 50%;    top: 4.5%; }
.hub:not(.hub-mini) .hub-node.p2 { left: 82.17%; top: 17.83%; }
.hub:not(.hub-mini) .hub-node.p3 { left: 95.5%;  top: 50%; }
.hub:not(.hub-mini) .hub-node.p4 { left: 82.17%; top: 82.17%; }
.hub:not(.hub-mini) .hub-node.p5 { left: 50%;    top: 95.5%; }
.hub:not(.hub-mini) .hub-node.p6 { left: 17.83%; top: 82.17%; }
.hub:not(.hub-mini) .hub-node.p7 { left: 4.5%;   top: 50%; }
.hub:not(.hub-mini) .hub-node.p8 { left: 17.83%; top: 17.83%; }
@media (max-width: 720px) { .hub:not(.hub-mini) { --dot-anchor: 10px; } }
@media (max-width: 420px) { .hub:not(.hub-mini) { --dot-anchor: 9px; } }

/* ============================================================
   Resolution Roundtable INTRO (roundtable .hub only; NEVER .hub-mini).
   Load: all grey + static, nothing drawn. S1: grey metal mark rises in.
   S2 = POWER ON, all in unison at one pace: mark morphs to purple; each ring
   is DRAWN by its OWN tracer particle sweeping its circumference (independent,
   each starting from a different point, tracing the ring in its trail); the two
   diamonds draw on as connections between the nodes; the straight dotted spokes
   grow out from the centre. S3 = settle: each ring hands off to its dashed
   spinning self, particles launch, spokes drift slowly + perpetually. */
@keyframes hubFlowRamp { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -4; } }
.hub-mark-metal { position: absolute; left: 50%; top: 50%; width: 62%; max-width: 130px; height: auto; transform: translate(-50%, -50%) scale(.82); opacity: 0; pointer-events: none; z-index: 2; filter: grayscale(1) drop-shadow(0 8px 20px rgba(0,0,0,.4)); transition: opacity 1.1s ease, transform 1.4s cubic-bezier(.22,.9,.3,1); }

/* SVG orbit-ring scaffold (roundtable only; replaces the CSS border rings). */
.hub-rings { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; z-index: 0; }
.hub-rings circle { fill: none; }
.rt-ring, .rt-spin, .rt-draw-wrap { transform-box: view-box; transform-origin: 50% 50%; }
.hub .rt-ring.rr0 { transform: rotate(60deg); }
.hub .rt-ring.rr1 { transform: rotate(8deg); }
.hub .rt-ring.rr2 { transform: rotate(140deg); }
.hub .rt-ring.rr3 { transform: rotate(235deg); }
.hub .rt-ring.rr4 { transform: rotate(320deg); }
.rt-draw  { stroke-width: .12; stroke-linecap: round; }
.rt-final { stroke-width: .12; stroke-dasharray: .42 .5; }
.rt-ring.rr0 .rt-final, .rt-ring.rr2 .rt-final { stroke-dasharray: none; stroke-width: .12; }
.hub-core img.hub-mark-vid { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 100%; max-width: 250px; height: auto; pointer-events: none; filter: drop-shadow(0 6px 18px rgba(91,69,240,.5)); }

/* ---- REST: grey, static, nothing drawn ---- */
.hub.rt-intro:not(.hub-mini) .hub-core { opacity: 0; border-color: transparent; background: none; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; animation: none; transition: opacity .9s ease; }
.hub.rt-intro:not(.hub-mini) .hub-core > img.hub-mark-purple { opacity: 0; transition: opacity 1.3s ease; }
/* Static soft glow on the network lines + rings (no pulse). */
.hub.rt-intro:not(.hub-mini) .hub-spokes,
.hub.rt-intro:not(.hub-mini) .hub-diamond,
.hub.rt-intro:not(.hub-mini) .rt-final { filter: drop-shadow(0 0 2px var(--ring-pulse-glow)); }
.hub.rt-intro:not(.hub-mini) .rt-final { opacity: 0; stroke: var(--brd-strong); transition: opacity .8s ease, stroke 1.3s ease; }
.hub.rt-intro:not(.hub-mini) .rt-draw { stroke: var(--brd-strong); stroke-dasharray: 1 1; stroke-dashoffset: 1; opacity: 1; transition: stroke-dashoffset 4.8s cubic-bezier(.4,.05,.3,1), stroke 1.9s ease, opacity 1.1s ease; }
.hub.rt-intro:not(.hub-mini) .rt-spin { animation: none; }
.hub.rt-intro:not(.hub-mini) .hub-diamond { stroke: var(--brd-strong); stroke-dasharray: 1 1; stroke-dashoffset: 1; opacity: 0; transition: stroke-dashoffset 4.8s cubic-bezier(.4,.05,.3,1), stroke 1.9s ease, opacity 1.2s ease; }
.hub.rt-intro:not(.hub-mini) .hub-lines line { stroke: var(--brd-strong); stroke-width: .15; stroke-dasharray: .014 .018; opacity: 0; transform: scale(0); transform-box: view-box; transform-origin: 50% 50%; animation: none; transition: transform 4s cubic-bezier(.4,.05,.3,1), opacity 1.8s ease, stroke 1.9s ease; }
.hub.rt-intro:not(.hub-mini) .hub-node { filter: grayscale(1); opacity: .55; transition: filter 1.3s ease, opacity 1.3s ease, transform .3s cubic-bezier(.34, 1.45, .5, 1), border-color .3s ease, box-shadow .3s ease; }
.hub.rt-intro:not(.hub-mini) .hub-node::before { background: var(--brd-strong); box-shadow: none; animation: none; transition: background 1.3s ease, box-shadow 1.3s ease; }
.hub.rt-intro:not(.hub-mini) .pkt { opacity: 0; r: .2px; transition: opacity 2.2s ease; }

/* ---- STAGE 1: grey metal mark rises from nothing ---- */
.hub.rt-intro.rt-s1:not(.hub-mini) .hub-core { opacity: 1 !important; }
.hub.rt-intro.rt-s1:not(.hub-mini) .hub-mark-metal { opacity: 1 !important; transform: translate(-50%, -50%) scale(1); }
.hub.rt-intro.rt-s1:not(.hub-mini) .rt-draw { stroke-dashoffset: 0; }
.hub.rt-intro.rt-s1:not(.hub-mini) .hub-diamond { stroke-dashoffset: 0; opacity: 1; }
.hub.rt-intro.rt-s1:not(.hub-mini) .hub-lines line { opacity: 1; transform: scale(1); }

/* ---- STAGE 2: POWER ON -- draw + trace + colour, all in unison ---- */
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-mark-metal { opacity: 0 !important; }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-core > img.hub-mark-purple { opacity: 1 !important; }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-core { border-color: transparent; background: none; box-shadow: none; animation: none; }
.hub.rt-intro.rt-s2:not(.hub-mini) .rr0 .rt-draw, .hub.rt-intro.rt-s2:not(.hub-mini) .rr0 .rt-final { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .rr1 .rt-draw, .hub.rt-intro.rt-s2:not(.hub-mini) .rr1 .rt-final { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .rr2 .rt-draw, .hub.rt-intro.rt-s2:not(.hub-mini) .rr2 .rt-final { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .rr3 .rt-draw, .hub.rt-intro.rt-s2:not(.hub-mini) .rr3 .rt-final { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .rr4 .rt-draw, .hub.rt-intro.rt-s2:not(.hub-mini) .rr4 .rt-final { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-diamond { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-lines line { stroke: color-mix(in srgb, var(--indigo-bright) 56%, var(--brd-strong)); }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-node { filter: none !important; opacity: 1 !important; }
.hub.rt-intro.rt-s2:not(.hub-mini) .hub-node::before { background: var(--indigo-bright); box-shadow: 0 0 12px var(--indigo-bright); animation: markerPulse 2.6s ease-in-out infinite; }

/* ---- STAGE 3: settle -- tracer hands off to the dashed spinning ring; particles + drift ---- */
.hub.rt-intro.rt-s3:not(.hub-mini) .rt-draw { opacity: 0; transition: opacity 1.1s ease .15s; }
.hub.rt-intro.rt-s3:not(.hub-mini) .rt-final { opacity: .85; transition: opacity 1s ease; }
.hub.rt-intro.rt-s3:not(.hub-mini) .hub-core { box-shadow: none; animation: none; }
.hub.rt-intro.rt-s3:not(.hub-mini) .rr1 .rt-spin { animation: hubSpin 46s linear infinite; }
.hub.rt-intro.rt-s3:not(.hub-mini) .rr2 .rt-spin { animation: hubSpin 40s linear infinite; }
.hub.rt-intro.rt-s3:not(.hub-mini) .rr3 .rt-spin { animation: hubSpin 58s linear infinite reverse; }
.hub.rt-intro.rt-s3:not(.hub-mini) .rr4 .rt-spin { animation: hubSpin 72s linear infinite; }
.hub.rt-intro.rt-s3:not(.hub-mini) .hub-lines line { animation: hubFlowRamp 40s ease-in 1, hubFlow 80s linear 40s infinite; }
.hub.rt-intro.rt-s3:not(.hub-mini) .pkt { opacity: 1 !important; }



/* ---- Difference: text left, bullets stacked right with icon separators. ---- */
.diff-split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
@media (max-width: 900px) { .diff-split { grid-template-columns: 1fr; gap: 30px; } }
.pill-sep { display: flex; align-items: center; padding: 20px 0; }

/* Roundtable band: square placeholder visual, no icon. */
.rt-band-viz { aspect-ratio: 1 / 1; max-width: 260px; width: 100%; margin-inline: auto; border: 1px solid var(--brd); border-radius: 16px; background: var(--glass); }
.rt-band-viz img { display: none; }

/* One consistent, readable body size for every monitor copy block. */
.mon-block .lead, .mon-block .small-t { font-size: clamp(20px, 2.1vw, 23px); line-height: 1.62; color: var(--muted); margin-top: 12px; }
.mon-h + .lead, .mon-h + .small-t, .mon-h + .mon-tt { margin-top: 12px; }
/* Today / Tomorrow: mono label on its own line, paragraph beneath, clear gap. */
.mon-tt { margin-top: 20px; }
.mon-tt:first-of-type { margin-top: 14px; }
.mon-tt-label { display: block; font-family: var(--font-mono); text-transform: uppercase; letter-spacing: .12em; font-size: 13px; color: var(--indigo-lift); margin-bottom: 6px; }
.mon-tt .small-t { margin-top: 0; }


/* Right-aligned monitor copy cell (AI orchestration beside the first monitor). */
.mon-copy-right { text-align: center; align-items: center; }

/* Uniform hero top spacing across platform, roundtable, europe (match aux pages). */
.hero-lead { padding-top: 88px; position: relative; }
/* The aurora clips its glow to the section box; that clip edge landed right below
   the header and read as a hard "wall". Extend the aurora up behind the fixed
   header so the clip line hides under it and the glow fades in naturally. */
.hero-lead .aurora { top: calc(-1 * var(--header-h) - 40px); -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent 100%); mask-image: linear-gradient(to bottom, #000 55%, transparent 100%); }
.t1p-hero.hero-lead { align-items: start; }

/* Logo is the light source: pulsing glow follows the mark shape; disc glow dialed down */
.hub:not(.hub-mini) .hub-core { box-shadow: inset 0 1px 0 var(--glass-hi), 0 0 42px -26px var(--indigo-bright); animation: none; }


/* --- ./components/roundtable.css --- */
/* Resolution Roundtable page. The bespoke hero instrument (rt-hero/rt-stage/
   rt-ring/etc.) and the old value-prop sections (rt-statement, rf-strip,
   sw-grid, rt-t1band, rt-showcase) were superseded by the shared platform.css
   modules (hub, tl-grid, f-2) now used on this page. Only the small overrides
   below are still live. */

/* Participant value cards need real left/right padding so text is not flush to
   the card edge. */
.tl-grid > .panel { padding: clamp(22px, 2.2vw, 30px); }

/* Network copy sits below the hub visual, centered, with breathing room. */
.rt-net-copy { margin-top: clamp(96px, 9vw, 132px); }


/* --- ./components/home.css --- */
/* =============================================================================
   Home modules - the editorial blocks unique to the home page: insight cards,
   module headers, event teasers, the onboarding split, and the team band.
   All token-driven and reusable on any page that wants a teaser module.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   MODULE HEADER (.mod-head) - eyebrow on the left, "All …" arrow link right.
   -------------------------------------------------------------------------- */
.mod-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 22px;
  flex-wrap: wrap;
}
.mod-head .eyebrow { margin: 0; }
.mod-more {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: color .2s;
}
.mod-more:hover { color: var(--text); }
.mod-more svg { transition: transform .3s cubic-bezier(.22, .61, .36, 1); }
.mod-more:hover svg { transform: translateX(4px); }

/* -----------------------------------------------------------------------------
   FEATURED INSIGHT (.feat-insight) - editorial two-column teaser card: title +
   dek + byline on the left, pull-quote and tags on the right. One big link.
   -------------------------------------------------------------------------- */
.feat-insight {
  display: grid;
  grid-template-columns: 1.06fr .94fr;
  overflow: hidden;
  text-decoration: none;
  align-items: stretch;
  padding: 0 !important;   /* columns carry their own padding */
}
@media (max-width: 820px) { .feat-insight { grid-template-columns: 1fr; } }
.fi-main {
  padding: clamp(28px, 3vw, 46px);
  display: flex;
  flex-direction: column;
}
.fi-cap {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--indigo-lift);
}
.fi-title {
  margin: 18px 0 0;
  font-weight: 800;
  font-size: clamp(26px, 3vw, 40px);
  line-height: 1.08;
  letter-spacing: -.025em;
  color: var(--text);
  max-width: 16ch;
  text-wrap: balance;
}
.fi-dek {
  margin: 16px 0 0;
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--muted);
  max-width: 46ch;
}
.fi-go {
  margin-top: auto;
  padding-top: 26px;
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--indigo-lift);
  text-decoration: none;
}
/* Hyperlink style + animation matched exactly to the thought-leadership .tl-fwd
   link: mono uppercase indigo, chevron nudges, underline GROWS FROM THE LEFT on
   hover (grows on the containing panel's hover for links inside a card). */
.hy { display: inline-flex; align-items: center; gap: 8px; font-family: var(--font-mono); font-size: 13.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--indigo-bright); text-decoration: none; }
.hy-t { position: relative; }
.hy-t::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: left center; transition: transform .25s cubic-bezier(.5, .5, .2, 1); }
.hy:hover .hy-t::after,
.rt-home:hover .hy-t::after,
.t1-panel:hover .hy-t::after,
.feat-insight:hover .hy-t::after { transform: scaleX(1); }
.hy-chev { width: 16px; height: 16px; transition: transform .28s cubic-bezier(.5, 1.4, .5, 1); }
/* .hy-chev bounce is JS-driven (effects.js arr-bounce, now also targets .hy-chev) */
/* Featured card: read-link sits on the right under the pull-quote. */
.fi-read { align-self: flex-start; margin-top: 28px; }

.fi-side {
  position: relative;
  padding: clamp(30px, 3.4vw, 48px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.fi-mark {
  font-family: Georgia, 'Times New Roman', serif;
  font-size: 72px;
  line-height: .4;
  color: var(--indigo-lift);
  opacity: .55;
  transition: opacity .35s ease, text-shadow .35s ease;
}
.fi-pull {
  margin: 18px 0 0;
  font-size: clamp(24px, 2.3vw, 32px);
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--text);
  text-wrap: balance;
}
.fi-pull span { color: var(--indigo-lift); transition: color .35s ease; }
.feat-insight:hover .fi-mark { opacity: .95; text-shadow: 0 0 18px rgba(129, 120, 255, .75), 0 0 44px rgba(129, 120, 255, .4); }
.feat-insight:hover .fi-pull span { animation: accentFlash .6s ease-out 1; }
@keyframes accentFlash {
  0%, 100% { color: var(--indigo-lift); text-shadow: none; }
  42% { color: var(--grad-hi); text-shadow: 0 0 13px color-mix(in srgb, var(--indigo-lift) 75%, transparent); }
}
.fi-tags { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 8px; }
.fi-tag {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  padding: 6px 12px;
  border: 1px solid var(--brd);
  border-radius: 999px;
  background: var(--panel);
}
/* Compact byline row inside the insight card. */
.byrow { display: flex; align-items: center; gap: 17px; margin-top: 24px; }
/* .byrow's headshot is a .ava now, see objects/article.css. */
.byrow b { display: block; font-size: 19.5px; line-height: 1.25; color: var(--text); font-weight: 700; }
.byrow span { display: block; font-size: 16px; color: var(--dim); line-height: 1.35; }

/* -----------------------------------------------------------------------------
   EVENT TEASERS (.evt-grid) - one featured event panel + a column of minis.
   -------------------------------------------------------------------------- */
.evt-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(26px, 4vw, 60px);
  align-items: stretch;
}
@media (max-width: 820px) { .evt-grid { grid-template-columns: 1fr; } }

/* A single event should not sit in a half-width column with empty space beside
   it, so the grid collapses to one track when there is only one card. */
.evt-grid:has(> :only-child) { grid-template-columns: 1fr; }

/* Going full width is not enough on its own: the card is a vertical stack, so
   a lone card leaves its content huddled in the top-left and the rest of the
   panel empty. On wide screens the stack becomes a banner row instead -
   status and date in a left column, title and blurb beside them, action on the
   far right - so the content spans the panel it sits in. Below the breakpoint
   the grid is already single-column and the original stack is the right shape,
   so none of this applies. */
@media (min-width: 821px) {
  /* One grid across the whole card so every element shares the same rows.
     `display: contents` dissolves the inner wrapper, which lets the button -
     a sibling of that wrapper in the markup - sit in the same grid as the text
     rather than being centred against the card as a whole.

     The status chip occupies row 1 on its own. Everything else sits in row 2,
     so the date, the name, the description and the action all centre on the
     same line as each other. Centring on the full block instead would put them
     midway between the chip and the date, which reads as misaligned. */
  .evt-grid:has(> :only-child) .evt-feat {
    display: grid;
    grid-template-columns: auto minmax(0, max-content) minmax(0, 1fr) auto;
    column-gap: clamp(22px, 3.4vw, 52px);
    row-gap: 6px;
    align-items: center;
    min-height: 0;
    padding: 30px 38px;
  }
  .evt-grid:has(> :only-child) .evt-feat > div { display: contents; }

  .evt-grid:has(> :only-child) .evt-tag     { grid-area: 1 / 1; }
  .evt-grid:has(> :only-child) .evt-when-xl { grid-area: 2 / 1; margin: 0; }
  .evt-grid:has(> :only-child) .evt-name    { grid-area: 2 / 2; margin: 0; }
  .evt-grid:has(> :only-child) .evt-loc     {
    grid-area: 2 / 3;
    margin: 0;
    max-width: none;
    font-size: 13.5px;
    line-height: 1.6;
  }
  .evt-grid:has(> :only-child) .evt-btn     { grid-area: 2 / 4; align-self: center; }
}
.evt-feat {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 26px;
  min-height: 236px;
  text-decoration: none;
}
.evt-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 15px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--indigo-lift);
}
.evt-when-xl {
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(20px, 2vw, 26px);
  letter-spacing: .04em;
  color: var(--indigo-lift);
}
/* Past card in the In market strip. An event that has already happened sits next
   to one you can still book, so it must not compete for the same attention: the
   purple eyebrow and date are the loudest thing on an upcoming card, and reading
   identically on a past one makes the strip look like two equal offers. Dropping
   both to the neutral grey keeps the card legible and clickable (the recording
   is still worth watching) while letting the upcoming event win the glance.
   Same treatment as the past rows on the events page, which use --dim.

   Only the TEXT goes grey. The recording pip keeps its red because .live-dot
   paints itself from var(--signal) rather than currentColor, so colour set here
   never reaches it, and nothing here touches `animation`, so it keeps pulsing. */
.evt-feat.is-past .evt-tag,
.evt-feat.is-past .evt-when-xl { color: var(--dim); }

.evt-name {
  margin: 10px 0 0;
  font-size: clamp(24px, 2.7vw, 34px);
  font-weight: 700;
  letter-spacing: -.02em;
  color: var(--text);
}
.evt-loc { margin: 8px 0 0; font-size: 14px; line-height: 1.55; color: var(--muted); max-width: 42ch; }
.evt-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  text-decoration: none;
}
.evt-cta svg { transition: transform .3s cubic-bezier(.22, .61, .36, 1); }
.evt-btn { min-width: 172px; justify-content: center; }

.evt-col { display: flex; flex-direction: column; gap: 18px; }
.evt-mini {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 20px;
  align-items: center;
  text-decoration: none;
  padding: 24px 28px;
  flex: 1;
}
a.evt-mini { border-color: var(--brd-hover); }
.evt-mini .ev-date-b { text-align: center; min-width: 84px; }
.evt-mini .ev-date-b b { display: block; font-weight: 800; font-size: 24px; letter-spacing: -.01em; color: var(--text); line-height: 1.05; white-space: nowrap; }
.evt-mini .ev-date-b span {
  display: block;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--indigo-lift);
  margin-top: 6px;
}
.evt-mini h4 { margin: 0; font-size: 20px; font-weight: 700; color: var(--text); }
.evt-mini p { margin: 8px 0 0; font-size: 16px; line-height: 1.6; color: var(--muted); }

/* -----------------------------------------------------------------------------
   SPLIT TEASER (.split2) - copy on the left, a panel on the right (Onboarding
   teaser). The mini step list (.ob-steps) lives inside the panel.
   -------------------------------------------------------------------------- */
.split2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(20px, 2.2vw, 38px);
  align-items: stretch;
}
@media (max-width: 820px) { .split2 { grid-template-columns: 1fr; gap: 30px; } }
.split2 .sec-title { margin-top: 14px; max-width: 19ch; letter-spacing: -.02em; }
.split2 .sec-intro { max-width: 40ch; }
.split2 .btn { margin-top: 28px; }
.split2 .panel {
  padding: clamp(20px, 2.2vw, 30px) clamp(26px, 3vw, 40px);
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.ob-steps { display: flex; flex-direction: column; flex: 1; justify-content: space-between; }
.ob-steps .obs {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 20px;
  padding: 22px 0;
  border-top: 1px solid var(--line);
  align-items: start;
}
.ob-steps .obs:first-child { border-top: 0; }
.ob-steps .obs i { font-family: var(--font-mono); font-size: 17px; color: var(--indigo-lift); font-style: normal; padding-top: 2px; }
.ob-steps .obs b { font-size: 23px; color: var(--text); font-weight: 700; letter-spacing: -.015em; }
.ob-steps .obs p { margin: 7px 0 0; font-size: 17px; color: var(--muted); line-height: 1.6; }

/* -----------------------------------------------------------------------------
   TEAM BAND (.team-band) - centred quote, overlapping avatars, pedigree strip.
   -------------------------------------------------------------------------- */
.team-band { text-align: center; }
.team-band .eyebrow { justify-content: center; }
.team-quote {
  font-size: clamp(26px, 3.5vw, 46px);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -.025em;
  color: var(--text);
  max-width: 26ch;
  margin: 16px auto 0;
  text-wrap: balance;
}
.team-quote span { color: var(--indigo-lift); }
.team-ava { display: flex; justify-content: center; margin-top: 24px; }
.team-ava img {
  width: 58px;
  height: 58px;
  border-radius: 50%;
  object-fit: cover;
  margin-left: -14px;
  border: 2px solid var(--bg);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .3);
}
.team-ava img:first-child { margin-left: 0; }
.pedigree { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 0; margin-top: 18px; }
.pedigree .pi {
  font-family: var(--font-mono);
  font-size: 15px;
  color: var(--text-2, var(--muted));
  padding: 3px 18px;
  border-right: 1px solid var(--line);
}
.pedigree .pi:last-child { border-right: 0; }
.team-band .btn { margin-top: 24px; }


/* -----------------------------------------------------------------------------
   ONBOARDING panel - roomier so the step list fills the window.
   -------------------------------------------------------------------------- */
.split2 > .panel { padding: clamp(30px, 3.2vw, 46px) clamp(28px, 3.4vw, 46px); display: flex; flex-direction: column; justify-content: stretch; }

/* -----------------------------------------------------------------------------
   T+1 EUROPE section (.t1-panel) - copy on the left, live countdown on the right.
   Countdown cells are transparent bordered windows to match the theme.
   -------------------------------------------------------------------------- */
.t1-panel {
  display: grid;
  grid-template-columns: 1.35fr .9fr;
  gap: clamp(24px, 3vw, 48px);
  align-items: center;
  padding: clamp(30px, 3.4vw, 48px);
  row-gap: 12px;
}
@media (max-width: 860px) { .t1-panel { grid-template-columns: 1fr; } }
.t1-copy .h2 { margin: 14px 0 0; max-width: 24ch; }
.t1-copy .lead { margin: 16px 0 0; max-width: 50ch; font-size: clamp(17px, 1.45vw, 20px); line-height: 1.65; }
.t1-actions { margin-top: 24px; }
/* London mark stands alone on the right. */
.t1-visual { display: flex; justify-content: center; align-items: center; }
.t1-mark { display: block; width: min(100%, 400px); height: auto; filter: drop-shadow(0 18px 44px rgba(0,0,0,.45)); }

/* Top row - eyebrow + live countdown, one line. Spacing below it comes from
   the panel's own grid row-gap, same as the gap between copy and visual. */
.t1-top {
  grid-column: 1 / -1;
}
.t1-top .eyebrow { display: inline-flex; align-items: center; gap: 9px; margin: 0; }
.t1-count-timer {
  color: var(--text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: normal;
  text-transform: none;
}


/* -----------------------------------------------------------------------------
   FLOW3 - hero pipeline. Three windows joined by arrows; no dividers.
   -------------------------------------------------------------------------- */
.flow3 { display: grid; grid-template-columns: 1fr auto 1fr auto 1fr; gap: 14px; align-items: stretch; margin-top: clamp(30px, 4vw, 48px); text-align: left; }
.f3 { padding: 24px 26px; display: flex; flex-direction: column; gap: 10px; }
.f3.is-core { border-color: var(--brd-strong); box-shadow: 0 0 34px -12px var(--glow-2), inset 0 1px 0 var(--glass-hi); }
.f3-k { font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--indigo-lift); }
.f3-t { margin: 0; font-size: clamp(17px, 1.5vw, 20px); font-weight: 700; letter-spacing: -.015em; color: var(--text); }
.f3-d { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--muted); }
.f3-link { display: flex; align-items: center; color: var(--indigo-lift); opacity: .8; }
.f3-link svg { animation: arrBounce 2.6s cubic-bezier(.45,0,.55,1) infinite; }
@media (max-width: 900px) { .flow3 { grid-template-columns: 1fr; } .f3-link { justify-content: center; transform: rotate(90deg); } }

/* -----------------------------------------------------------------------------
   PLATFORM EXPLORER (.px-panel) - interactive tabbed window, no dividers.
   -------------------------------------------------------------------------- */
.px-panel { padding: clamp(26px, 3vw, 40px) clamp(26px, 3.2vw, 44px); }
.px-tabs { display: flex; gap: 10px; flex-wrap: wrap; }
.px-views { display: grid; margin-top: clamp(24px, 2.6vw, 36px); }
.px-copy h3 { margin: 0; font-size: clamp(22px, 2.2vw, 30px); font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.px-copy p { margin: 12px 0 0; font-size: clamp(16px, 1.35vw, 18px); line-height: 1.65; color: var(--muted); max-width: 56ch; }
.px-stat { text-align: left; }
.px-stat b {
  display: block; font-weight: 800; font-size: clamp(52px, 6vw, 84px);
  letter-spacing: -.04em; line-height: 1; color: var(--text);
}
.px-stat span { display: block; margin-top: 10px; font-size: 15px; line-height: 1.55; color: var(--indigo-lift); max-width: 30ch; }

/* -----------------------------------------------------------------------------
   ARROW BOUNCE - arrows bounce while hovered; effects.js freezes the current
   offset on leave and transitions it home so it never snaps.
   -------------------------------------------------------------------------- */
@keyframes arrBounce { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(6px); } }
@keyframes arrBounceBack { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-6px); } }
.tl-back .arr-bouncing { animation-name: arrBounceBack; }
.arr-bouncing { animation: arrBounce 2.2s cubic-bezier(.45,0,.55,1) infinite; }
.arr-return { transition: transform .45s cubic-bezier(.22,.61,.36,1); }


/* =============================================================================
   PROOF BAR (.proof-grid) - three count-up windows under the hero, replaces
   the retired .flow3 pipeline. Network figures only, no user counts. No
   dividers, no icons.
   ========================================================================== */
.proof-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: clamp(30px, 4vw, 48px); text-align: left; }
.proof-cell { padding: 26px 30px; display: flex; flex-direction: column; gap: 8px; }
.proof-num { font-size: var(--fs-h2); font-weight: 800; line-height: 1; letter-spacing: -.03em; color: var(--text); font-variant-numeric: tabular-nums; }
.proof-lbl { font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
@media (max-width: 760px) { .proof-grid { grid-template-columns: 1fr; } }

/* =============================================================================
   EXCEPTION MONITOR DUO (.mon-duo) - two equal demo monitors, white --mon-frame
   bezel over a theme-aware screen, each carrying the S mark. LEFT: a never
   stopping exception ticker with column headers; filters type in and highlight
   matches while non-matches collapse, then backspace out and everything returns,
   all while it keeps scrolling. Communication alerts pop up now and then. RIGHT:
   one long dashboard with mixed chart types scrolling perpetually. NO dividers.
   ========================================================================== */
.mon-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; margin-top: clamp(28px, 3.4vw, 44px); }
@media (max-width: 900px) { .mon-duo { grid-template-columns: 1fr; } }
.mon-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }

.duo-mon { background: var(--mon-frame); border-radius: 20px; padding: 7px; box-shadow: var(--panel-glow); transition: transform var(--motion-window), box-shadow var(--motion-window); min-width: 0; }
.duo-mon:hover { transform: var(--window-hover-transform); box-shadow: var(--window-hover-shadow); }
.mon-screen { background: var(--bg-2); border-radius: 14px; overflow: hidden; position: relative; height: 430px; display: flex; flex-direction: column; }

.mon-head { display: flex; align-items: center; gap: 9px; padding: 13px 18px 11px; font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); white-space: nowrap; flex: 0 0 auto; }
.mon-head .mon-mark { width: 32px; height: 32px; max-width: 32px; object-fit: contain; flex: 0 0 auto; }
.mon-title { color: var(--muted); font-weight: 700; }
.mon-dots { margin-left: auto; display: inline-flex; gap: 6px; }
.mon-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--brd-strong); }
.mon-dots i:first-child { background: var(--ok); box-shadow: 0 0 7px var(--ok); }

/* LEFT: query bar, column headers, ticker feed, comms alert */
/* The query line reserves TWO lines of height whether or not it needs them.

   The longest query is 45 characters and on a 320px phone it had seven pixels
   of slack, so it was one wider font away from running off the side of the
   screen. Letting it wrap solves that, but a line appearing and disappearing
   every few seconds would shove the feed underneath it up and down forever.

   Reserving the space means the second line costs nothing when it arrives: it
   drops into room that was already there, and the bezel, the margins and the
   panel height never move. The feed below is flex: 1, so it absorbs the
   difference by itself.

   display is block rather than flex on purpose. As flex children the prompt,
   the text and the caret are three columns, so a wrapped caret would sit beside
   the block instead of after the last character. Inline, the caret follows the
   text across the wrap the way a real one does. */
.mon-query {
  display: block;
  padding: 8px 18px 9px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.38;
  color: var(--muted);
  flex: 0 0 auto;
  min-height: calc(1.38em + 17px);
}
/* Below 900px the two monitors stack and each one gets the full column, which
   is where the long queries start to wrap. Only reserve the second line here,
   so the wider layout does not carry 17px of empty space it never uses. */
@media (max-width: 900px) {
  .mon-query { min-height: calc(2 * 1.38em + 17px); }
}
.mon-caret-pre { color: var(--indigo-lift); font-weight: 700; margin-right: 7px; }
/* normal, not nowrap: the reserved second line above is what makes this safe. */
.mon-q { color: var(--text); white-space: normal; }
.mon-caret { width: 7px; height: 12px; background: var(--indigo-lift); display: inline-block; margin-left: 2px; vertical-align: -2px; animation: monCaret 1.05s steps(1) infinite; }
@keyframes monCaret { 0%, 50% { opacity: 1; } 51%, 100% { opacity: 0; } }

.mon-cols { display: grid; grid-template-columns: 50px 74px 50px 1fr auto; gap: 12px; padding: 6px 18px 8px; font-family: var(--font-mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); flex: 0 0 auto; }
.mon-cols-st { justify-self: end; }

.mon-feed { flex: 1; min-height: 0; overflow: hidden; position: relative; }
.mon-track { display: flex; flex-direction: column; will-change: transform; }

.mon-r { display: grid; grid-template-columns: 50px 74px 50px 1fr auto; gap: 12px; align-items: center; padding: 9px 18px; max-height: 44px; overflow: hidden; transition: max-height .45s var(--ease-reveal), opacity .4s ease, padding .45s var(--ease-reveal), background .4s ease; }
.mon-r.is-match { background: color-mix(in srgb, var(--indigo-lift) 20%, transparent); box-shadow: inset 3px 0 0 var(--indigo-lift); }
.mon-r.is-out { max-height: 0; opacity: 0; padding-top: 0; padding-bottom: 0; }
.mon-time, .mon-cp, .mon-mkt { font-family: var(--font-mono); font-size: 11px; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mon-cp { color: var(--muted); }
.mon-rc { justify-self: start; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .03em; color: var(--muted); padding: 4px 11px; border: 1px solid var(--brd-strong); border-radius: var(--radius-pill); white-space: nowrap; }
.mon-chip { justify-self: end; font-family: var(--font-mono); font-size: 9.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; padding: 4px 10px; border-radius: var(--radius-pill); border: 1px solid; white-space: nowrap; transition: color .45s ease, background .45s ease, border-color .45s ease; }
.st-pred    { color: var(--warn);        background: var(--warn-bg); border-color: var(--warn); }
.st-resolve { color: var(--indigo-lift); background: var(--info-bg); border-color: var(--indigo-lift); }
.st-settle  { color: var(--ok);          background: var(--ok-bg);   border-color: var(--ok); }

.mon-alert { position: absolute; left: 16px; right: 16px; bottom: 14px; display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-radius: 12px; background: var(--elev); border: 1px solid var(--indigo-lift); box-shadow: 0 10px 30px rgba(0,0,0,.4); color: var(--text); font-family: var(--font-mono); font-size: 11px; opacity: 0; transform: translateY(140%); transition: transform .5s var(--ease-reveal), opacity .4s ease; pointer-events: none; z-index: 3; }
.mon-alert svg { width: 15px; height: 15px; color: var(--indigo-lift); flex: 0 0 auto; }
.mon-alert.show { opacity: 1; transform: translateY(0); }

/* RIGHT: long dashboard, vertical marquee, mixed chart types */
.mon-dash { flex: 1; min-height: 0; overflow: hidden; position: relative; }
.mon-dash-track { display: flex; flex-direction: column; will-change: transform; animation: monScroll 58s linear infinite; }
@keyframes monScroll { from { transform: translateY(0); } to { transform: translateY(-50%); } }
.mon-dash:hover .mon-dash-track { animation-play-state: paused; }
.dash-unit { display: flex; flex-direction: column; gap: 20px; padding: 14px 18px 24px; }
.dash-kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.dash-kpi { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dash-k-l { font-family: var(--font-mono); font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dash-k-n { font-family: var(--font-mono); font-size: 21px; font-weight: 700; color: var(--text); line-height: 1; letter-spacing: -.02em; }
.dash-k-d { font-family: var(--font-mono); font-size: 9.5px; color: var(--dim); }
.dash-k-d.is-good { color: var(--ok); }
.dash-title { margin: 0 0 11px; font-family: var(--font-mono); font-size: 13px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.mon-dist { display: flex; flex-direction: column; gap: 10px; }
.mon-drow { display: grid; grid-template-columns: 116px 1fr; gap: 12px; align-items: center; }
.mon-drow span { font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); white-space: nowrap; }
.mon-dbar { display: block; height: 4px; border-radius: 2px; background: var(--brd); }
.mon-dbar b { display: block; height: 100%; border-radius: 2px; background: var(--indigo-lift); }
.mon-spark { display: block; width: 100%; }
.dash-spark { height: 60px; }
.mon-spark polyline { fill: none; stroke: var(--indigo-lift); stroke-width: 1.6; opacity: .7; }
/* donut */
.dash-donut { display: flex; align-items: center; gap: 20px; }
.donut { width: 92px; height: 92px; transform: rotate(-90deg); flex: 0 0 auto; }
.donut circle { fill: none; stroke-width: 13; }
.donut-track { stroke: var(--brd); }
.donut-seg.s-ok { stroke: var(--ok); } .donut-seg.s-ind { stroke: var(--indigo-lift); } .donut-seg.s-warn { stroke: var(--warn); }
.dash-legend { display: flex; flex-direction: column; gap: 8px; }
.dash-legend .lg { font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); position: relative; padding-left: 17px; white-space: nowrap; }
.dash-legend .lg::before { content: ""; position: absolute; left: 0; top: 3px; width: 9px; height: 9px; border-radius: 2px; }
.lg.s-ok::before { background: var(--ok); } .lg.s-ind::before { background: var(--indigo-lift); } .lg.s-warn::before { background: var(--warn); }
/* vertical bars */
.dash-vbars { display: flex; align-items: flex-end; gap: 8px; height: 74px; }
.dash-vbars i { flex: 1; min-width: 6px; background: var(--indigo-lift); border-radius: 3px 3px 0 0; opacity: .85; }
.dash-vbars i:last-child { background: var(--indigo-bright); opacity: 1; }
/* area chart */
.dash-area { display: block; width: 100%; height: 70px; }
.dash-area polygon { fill: var(--info-bg); }
.dash-area polyline { fill: none; stroke: var(--indigo-lift); stroke-width: 1.6; opacity: .85; }
/* penalty */
.dash-pen { display: flex; flex-direction: column; gap: 5px; }
.dash-pen span { font-family: var(--font-mono); font-size: 10.5px; color: var(--dim); }
.dash-pen b { font-family: var(--font-mono); font-size: 13px; color: var(--text); font-weight: 700; }

.mon-src { margin: 0; font-family: var(--font-mono); font-size: 12px; letter-spacing: .05em; color: var(--dim); line-height: 1.55; }

@media (max-width: 560px) {
  .mon-r, .mon-cols { grid-template-columns: 48px 1fr auto; }
  .mon-cp, .mon-mkt, .mon-cols span:nth-child(2), .mon-cols span:nth-child(3) { display: none; }
  .mon-drow { grid-template-columns: 92px 1fr; }
  .mon-screen { height: 396px; }
}
@media (prefers-reduced-motion: reduce) { .mon-dash-track { animation: none; } .mon-caret { animation: none; } .duo-mon { transition: none; } }
html.anim-off .mon-dash-track, html.anim-off .mon-caret { animation-play-state: paused; }

/* =============================================================================
   PUZZLE LOAD-IN (.pz) - above-the-fold hero + first-screen windows drop into
   place on load with a soft overshoot. JS (effects.js) adds .pz then .pz-in
   staggered, and sets the per-index direction vars. Reduced motion: no .pz.
   ========================================================================== */
.pz { opacity: 0; transform: translateY(16px); }
.pz-in { opacity: 1; transform: none; transition: opacity 1s ease, transform 1s ease; will-change: opacity, transform; }

/* =============================================================================
   T+1 LONDON MARK hover - the wrap scales up further on hover (smooth
   transition), the img floats slowly while hovered, and glides home from any
   point in the loop on leave (freeze + transition, handled in effects.js).
   ========================================================================== */
.t1-mark-wrap { display: inline-block; transition: transform .5s var(--ease-reveal); will-change: transform; }
.t1-mark-wrap.is-lift { transform: scale(1.13); }
@keyframes t1FloatY { 0%, 100% { transform: translateY(-2px); } 50% { transform: translateY(-13px); } }
.t1-mark.is-floating { animation: t1FloatY 2.8s ease-in-out infinite; }
.t1-mark.t1-return { transition: transform .6s cubic-bezier(.22, .61, .36, 1); }
@media (prefers-reduced-motion: reduce) { .t1-mark.is-floating { animation: none; } .t1-mark-wrap { transition: none; } }


/* Monitor unit: the screen sits on a stand, and the whole unit links to the
   platform page. Stand uses --mon-frame so it matches the bezel in both themes. */
.mon-unit { display: flex; flex-direction: column; align-items: center; text-decoration: none; color: inherit; }
.mon-unit .duo-mon { width: 100%; }
.mon-neck2 { width: 16%; height: 15px; background: var(--mon-frame); opacity: .92; }
.mon-base2 { width: 48%; height: 6px; border-radius: 3px; background: var(--mon-frame); opacity: .92; box-shadow: 0 8px 16px rgba(0,0,0,.28); }
.mon-src-l { color: var(--indigo-lift); text-transform: uppercase; letter-spacing: .12em; margin-right: 8px; }


/* Monitor header mark: white icon on dark, flipped to black on light theme
   (single white PNG, brightness(0) renders it solid black). */
[data-theme="light"] .mon-head .mon-mark { filter: brightness(0); }

body.index .section.is-hero-stage { min-height: 100vh; }

/* Team pages: the vertical company marquee was removed, so let the copy fill. */
.split-grid.is-hero-marquee, .split-grid.is-team-marquee { grid-template-columns: 1fr; }



/* Landing: keep a large gap between the alone hero and the body that reveals. */
body.index .container.section.is-hero-stage { margin-bottom: clamp(120px, 26vh, 300px); }

/* Home Resolution Roundtable box: mini hub left, copy right-aligned. */
.rt-home { display: grid; grid-template-columns: 220px 1fr; gap: clamp(24px, 4vw, 48px); align-items: center; padding: clamp(28px, 3.6vw, 46px); text-decoration: none; transition: transform var(--motion-window), border-color .3s ease; }
.rt-home:hover { transform: scale(1.012); border-color: var(--brd-hover); }
@media (max-width: 760px) { .rt-home { grid-template-columns: 1fr; } }
.rt-home-copy { text-align: right; }
.rt-home-copy .h2 { margin-bottom: 0; }
.rt-home-copy .lead { margin-top: 14px; }
.rt-home-copy .t1-actions { display: flex; justify-content: flex-end; margin-top: 16px; }
@media (max-width: 760px) { .rt-home-copy { text-align: left; } .rt-home-copy .t1-actions { justify-content: flex-start; } }
.hub-mini { width: 200px; max-width: 200px; aspect-ratio: 1 / 1; margin: 0 auto; }

/* Onboarding teaser: button near the text, bullets bigger and filling the height. */
.split2 > div:first-child { display: flex; flex-direction: column; align-items: flex-start; }
.split2 .btn { margin-top: 22px; }
.split2 .f-2.is-onecol { justify-content: space-between; }
.split2 .f-2.is-onecol .h4 { font-size: 20px; }
.split2 .f-2.is-onecol .small-t { font-size: 16px; }
.split2 .f-2.is-onecol .f-num { font-size: 18px; }

/* Trusted partnerships: bigger label and bigger logos. */
.data-label.mq-label { font-size: 15px; letter-spacing: .16em; }
.plogo { max-width: 260px; }
.plogo[src*="ssc-advent"] { height: 54px; }

/* Landing: near-normal gap between hero and body (hero is a full-viewport
   centered header; body reveals on scroll). */
body.index .container.section.is-hero-stage { margin-bottom: 0; }

/* Onboarding teaser: button sits right under the copy, columns top-aligned. */
.split2 > div:first-child { display: block; }
.split2 .btn { margin-top: 24px; }
.split2 .f-2.is-onecol { justify-content: flex-start; }

/* Mini hub magnifies on hover in the home Roundtable box. */
.hub-mini { transition: transform var(--motion-hover); }
.rt-home:hover .hub-mini { transform: scale(1.06); }

/* Kill the load flash: hide [data-pz] before the JS runs (js class is set in
   an early head script), reveal via .pz-in; reduced motion shows them. */
html.enter.js [data-pz] { opacity: 0; }
html.js [data-pz].pz-in { opacity: 1; }
@media (prefers-reduced-motion: reduce) { html.js [data-pz] { opacity: 1; } }

/* Home hero: fill exactly the viewport below the fixed header so the space
   above the logo equals the space below the buttons (true vertical center). */
body.index .container.section.is-hero-stage { min-height: calc(100vh - var(--header-h)); justify-content: safe center; padding-block: clamp(48px, 7vh, 130px); }

/* Bare buttons: no casing, label + arrow only. */
.btn.is-bare { border: 0; background: transparent; box-shadow: none; padding-left: 0; padding-right: 0; }
.btn.is-bare:hover { background: transparent; }
/* rt-home / t1-panel arrows now use the SAME hover bounce as every other arrow
   (effects.js adds .arr-bouncing at 2.2s). The old fast arrNudge loop bounced
   quicker and clipped at the panel edge, so it's removed for consistency. */

/* Home arrows adopt the thought-leadership feature-card purple, EXCEPT arrows
   inside buttons, which inherit the button's text colour (white on primary). */
body.index .arr { color: var(--indigo-lift); }
body.index .btn .arr { color: currentColor; }

/* Mini hub: node dots only, rings keep spinning, magnify more on hover. */
.hub-mini { width: 220px; max-width: 220px; }
.hub-mini .hub-node { width: auto; padding: 0; border: 0; background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.hub-mini .hub-node b, .hub-mini .hub-node span { display: none; }
.hub-mini .hub-node::before { margin: 0; width: 6px; height: 6px; }
.hub-mini .hub-core { width: 42%; height: 42%; }
/* The metallic mark inside the homepage Resolution Roundtable card. Scoped to
   .hub-mini so the full-size hub on /platform and the roundtable page are
   untouched. Base rule is 62% capped at 130px (platform.css). */
.hub-mini .hub-core img { width: 72%; max-width: 100px; }
.rt-home:hover .hub-mini { transform: scale(1.1); }

/* Featured insight caption + event date bigger; section links bigger. */
.fi-cap { font-size: 15px; letter-spacing: .04em; }
.evt-when-xl { font-size: clamp(30px, 3vw, 44px); }
.mod-head .btn-ghost { font-size: 16px; padding: 10px 18px; }


/* Whole-page reveal: sections rise and fade in smoothly and slowly. */
html.js .site .container.section.rv { opacity: 0; will-change: opacity; }
html.js .site .container.section.rv.rv-in { opacity: 1; transition: opacity .9s ease; }
@media (prefers-reduced-motion: reduce) { html.js .site .container.section.rv { opacity: 1; transform: none; } }

/* 'Explore the platform' button under the monitors, with clear separation
   before the Resolution Roundtable section. */
.mon-cta { display: flex; justify-content: center; margin-top: clamp(30px, 4vw, 48px); margin-bottom: 0; }


/* Onboarding teaser layout (home + platform).
   Button sits tight under the paragraph. The step column matches the left
   column height and space-between spreads the four steps from the TOP OF THE
   HEADING (padding clears the eyebrow) down to the BOTTOM OF THE BUTTON.
   A smaller column gap pulls the steps left. */
.split2 > div:first-child { display: block; }
.split2 .sec-intro { margin-bottom: 0; }
.split2 .btn { margin-top: 14px; }
.split2 .f-2.is-onecol {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-top: 38px;   /* clears the eyebrow so step 1 aligns with the heading top */
}
.split2 .f-2.is-onecol .f-row { padding: 0; border-bottom: 0; }

/* Home onboarding only: widen the left column and let the heading use more width
   so it wraps into fewer lines, shrinking the whole section. (Platform onboarding
   keeps its own balance.) */
/* Above the 820px collapse point ONLY. Without the query this rule sits after
   the `@media (max-width: 820px) { .split2 { grid-template-columns: 1fr } }`
   rule at the top of this file, wins on source order at any width, and holds
   the two columns side by side on a phone, which pushes the right column off
   the edge of the screen. */
@media (min-width: 821px) {
  body.index .split2 { grid-template-columns: 1.22fr .78fr; }
}
body.index .split2 .sec-title { max-width: 28ch; }


/* --- ./pages/platform-page.css --- */
/* Platform page. Unique visuals for /platform/, composed from tokens. */

/* Outreach demo window */
.odemo { display: grid; align-content: space-between; gap: 14px; padding: 24px; }
.odemo-head { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: var(--indigo-lift); }
.odemo-mail { border: 1px solid var(--brd); border-radius: 14px; padding: 16px 18px; background: var(--bg-2); display: grid; gap: 9px; font-family: var(--font-mono); font-size: 13.5px; color: var(--muted); }
.odemo-mail .to b { color: var(--text); font-weight: 400; }
.odemo-body { min-height: 44px; line-height: 1.55; color: var(--dim); }
.odemo-status { display: flex; gap: 10px; align-items: center; }
.odemo-step { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; border: 1px solid var(--brd); color: var(--dim); border-radius: 999px; padding: 5px 12px; transition: all .4s var(--ease-reveal); }
.odemo.s0 .odemo-step.d0, .odemo.s1 .odemo-step.d1, .odemo.s2 .odemo-step.d2 { color: var(--ok); border-color: var(--ok); background: var(--ok-bg); }
.odemo-sub { color: var(--dim); font-size: 14px; line-height: 1.55; }

/* Inventory and prediction rail */
.trail-svg { display: block; width: 100%; height: auto; overflow: visible; }
.trail-line { stroke: var(--brd-strong); stroke-width: 2; }
.trail-draw { stroke: var(--indigo-bright); stroke-width: 2.4; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.6s var(--ease-reveal); }
.io-in .trail-draw { stroke-dashoffset: 0; }
.trail-stop circle { fill: var(--elev); stroke: var(--brd-strong); stroke-width: 2.4; }
.trail-stop.hot circle { stroke: var(--indigo-bright); filter: drop-shadow(0 0 12px var(--indigo-bright)); }
.trail-pulse { fill: none; stroke: var(--indigo-bright); stroke-width: 2; opacity: 0; }
.io-in .trail-pulse { animation: trailPulse 2.6s ease-out infinite; }
@keyframes trailPulse { 0% { transform: scale(.4); opacity: .8; } 70% { transform: scale(2.1); opacity: 0; } 100% { opacity: 0; } }
html.anim-off .trail-pulse { animation-play-state: paused; }
.trail-t { fill: var(--text); font-size: 30px; font-weight: 700; text-anchor: middle; }
.trail-l { fill: var(--muted); font-family: var(--font-mono); font-size: 13.5px; letter-spacing: .1em; text-transform: uppercase; text-anchor: middle; }
.trail-zone { fill: var(--warn-bg); stroke: var(--warn); stroke-width: 1.2; stroke-dasharray: 5 6; opacity: .8; }
.trail-zl { fill: var(--warn); font-family: var(--font-mono); font-size: 13.5px; letter-spacing: .1em; text-transform: uppercase; text-anchor: middle; }
.trail-note { margin-top: 10px; text-align: center; color: var(--dim); font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .12em; text-transform: uppercase; }

/* Connections */
.conn-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; max-width: 980px; margin-inline: auto; }
.conn { display: grid; gap: 6px; padding: 20px 22px; text-align: left; }
.conn b { font-family: var(--font-mono); font-size: 15px; letter-spacing: .1em; text-transform: uppercase; color: var(--text); font-weight: 400; }
.conn span { color: var(--dim); font-size: 14.5px; }

/* Getting connected strip */
.gc-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; position: relative; max-width: 1100px; margin-inline: auto; }
.gc-stop { position: relative; padding: 26px 22px 6px; }
.gc-stop::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: var(--brd-strong); }
.gc-stop::after { content: ""; position: absolute; top: -4px; left: 0; width: 10px; height: 10px; border-radius: 50%; background: var(--indigo-bright); box-shadow: 0 0 12px var(--indigo-bright); }
.gc-line { position: absolute; top: 0; left: 0; height: 2px; width: 0; background: var(--indigo-bright); transition: width 1.8s var(--ease-reveal); z-index: 1; }
.io-in .gc-line { width: 100%; }
.gc-stop .num { font-family: var(--font-mono); font-size: 12px; letter-spacing: .14em; color: var(--indigo-lift); }
.gc-stop h3 { margin: 8px 0 6px; font-size: 20px; }
.gc-stop p { margin: 0; color: var(--muted); font-size: 15.5px; line-height: 1.55; }

/* Outcomes pivot */
.pivot { max-width: 880px; margin-inline: auto; padding: 24px clamp(18px, 2.4vw, 30px); }
.pivot-tabs { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
.pv-row { display: grid; grid-template-columns: .55fr 1fr auto; gap: 16px; align-items: center; }
.pv-row span { font-family: var(--font-mono); font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }
.pv-bar { height: 10px; border-radius: 999px; background: rgba(255,255,255,.05); overflow: hidden; }
.pv-bar b { display: block; height: 100%; width: 0; border-radius: 999px; background: linear-gradient(90deg, var(--indigo), var(--indigo-bright)); transition: width 1.1s var(--ease-reveal); }
.pv-n { font-family: var(--font-mono); font-size: 13px; color: var(--indigo-lift); font-variant-numeric: tabular-nums; }
.pivot-note { margin-top: 18px; color: var(--dim); font-size: 15px; }

/* T+1 band */
.t1-band { display: grid; grid-template-columns: auto 1fr auto; gap: clamp(18px, 3vw, 40px); align-items: center; padding: 26px clamp(20px, 3vw, 38px); max-width: 1100px; margin-inline: auto; }
.t1-band img { height: 74px; width: auto; }
.t1-band-chip { font-family: var(--font-mono); font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--indigo-lift); }
.t1-band p { margin: 6px 0 0; color: var(--text); font-size: clamp(18px, 1.6vw, 22px); line-height: 1.45; }

@media (max-width: 1050px) {
  .gc-strip { grid-template-columns: repeat(2, 1fr); gap: 26px 0; }
  .conn-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 680px) {
  .gc-strip, .conn-grid { grid-template-columns: 1fr; }
  .t1-band { grid-template-columns: 1fr; text-align: left; }
}
@media (prefers-reduced-motion: reduce) {
  .trail-pulse { animation: none; }
}

/* =============================================================================
   Platform page - reimagined instruments (pl-*). Token-driven, light/dark aware.
   Reveals key on the site's .io-in (added by [data-io] in effects.js).
   ========================================================================== */

/* Layout shells */
.pl-split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,60px);align-items:center}
.pl-split2{display:grid;grid-template-columns:.82fr 1.18fr;gap:clamp(22px,3vw,40px);align-items:center}
.pl-split .sec-head{margin-bottom:0}
.sec-head.is-centered{margin-inline:auto;text-align:center;max-width:880px}
.sec-head.is-right{text-align:right}
.sec-head.is-right .eyebrow{justify-content:flex-end}

/* Instrument reveal (soft fade-up; inner animations play on .io-in) */
.pl-layerstack,.pl-ledger,.pl-resolver,.pl-matrix,.pl-t1{
  opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-slow) var(--ease-reveal),transform var(--dur-slow) var(--ease-reveal);
}
.pl-layerstack.io-in,.pl-ledger.io-in,.pl-resolver.io-in,.pl-matrix.io-in,.pl-t1.io-in{opacity:1;transform:none}

/* Shared SVG ink (theme aware) */
.pl-dial text{font-family:var(--font-mono)}
.pl-hair{stroke:var(--brd)}
.pl-ink-indigo{stroke:var(--indigo-bright)}
.pl-ink-lift{stroke:var(--indigo-lift)}
.pl-ink-warn{stroke:var(--warn)}
.pl-svg-text{fill:var(--text)}
.pl-svg-lift{fill:var(--indigo-lift)}
.pl-svg-dim{fill:var(--dim)}
.pl-svg-danger{fill:var(--danger)}
.pl-lg-indigo{fill:var(--indigo-bright)}
.pl-lg-lift{fill:var(--indigo-lift)}
.pl-lg-warn{fill:var(--warn)}

/* ---- One layer: interactive stack, no card. Hover lifts a participant. ---- */
.pl-layerstack{display:flex;justify-content:center;padding:20px 0 40px;min-height:300px}
.pl-stack{position:relative;width:440px;height:230px;max-width:100%}
.pl-tab{font-family:var(--font-mono);font-size:11px;letter-spacing:.08em;color:var(--dim);text-transform:uppercase}
.pl-unified-in{text-align:center}
.pl-u-main{font-weight:700;font-size:17px;color:var(--text);letter-spacing:-.01em}
.pl-u-sub{font-family:var(--font-mono);font-size:11px;color:var(--indigo-lift);letter-spacing:.06em;margin-top:6px}

/* ---- Golden truth: reconcile your record vs each counterparty, field by field ---- */
.pl-ledger{border-radius:var(--radius-lg);border:1px solid var(--brd-strong);background:var(--elev);
  box-shadow:var(--shadow);padding:20px 22px;min-height:300px}
.pl-lhead{display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11px;color:var(--muted);
  letter-spacing:.08em;text-transform:uppercase;padding-bottom:12px;border-bottom:1px solid var(--brd)}
.pl-lcount{margin-left:auto;color:var(--dim);text-transform:none}
.pl-t0{margin-left:12px;color:var(--indigo-lift);border:1px solid var(--brd-hover);border-radius:6px;padding:2px 7px}
.pl-cmp-cols,.pl-row{display:grid;grid-template-columns:96px 1fr 1fr 20px;align-items:center;gap:12px}
.pl-cmp-cols{padding:12px 0 6px;font-family:var(--font-mono);font-size:10px;letter-spacing:.06em;text-transform:uppercase;color:var(--dim)}
.pl-row{padding:9px 0;border-bottom:1px solid var(--line);font-family:var(--font-mono);font-size:12.5px}
.pl-k{color:var(--dim);letter-spacing:.04em;text-transform:uppercase;font-size:10.5px}
.pl-ours{color:var(--text)}
.pl-theirs{color:var(--muted);transition:color .3s}
.pl-row.checking .pl-theirs{color:var(--indigo-lift)}
.pl-row.bad .pl-theirs{color:var(--danger)}
.pl-chk{width:18px;height:18px;border-radius:50%;border:1px solid var(--brd);position:relative;justify-self:end}
.pl-row.checking .pl-chk{border-color:var(--warn)}
.pl-row.checking .pl-chk::after{content:"";position:absolute;inset:4px;border-radius:50%;background:var(--warn)}
.pl-row.ok .pl-chk{border-color:var(--ok);background:var(--ok-bg)}
.pl-row.ok .pl-chk::after{content:"";position:absolute;left:6px;top:3px;width:4px;height:8px;border:solid var(--ok);border-width:0 2px 2px 0;transform:rotate(45deg)}
.pl-row.bad .pl-chk{border-color:var(--danger);background:var(--danger-bg)}
.pl-row.bad .pl-chk::before,.pl-row.bad .pl-chk::after{content:"";position:absolute;left:8px;top:4px;width:1.6px;height:9px;background:var(--danger);border-radius:2px}
.pl-row.bad .pl-chk::before{transform:rotate(45deg)}
.pl-row.bad .pl-chk::after{transform:rotate(-45deg)}
.pl-verdict{min-height:44px;margin-top:14px}
.pl-ok,.pl-flag{display:none;align-items:center;gap:10px;padding:11px 13px;border-radius:var(--radius-md);font-size:12px;color:var(--text)}
.pl-ok{background:var(--ok-bg);border:1px solid var(--ok)}
.pl-flag{background:var(--danger-bg);border:1px solid var(--danger)}
.pl-rd{width:11px;height:11px;border-radius:50%;flex:0 0 auto}
.pl-ok .pl-rd{background:var(--ok)}
.pl-flag .pl-rd{background:var(--danger)}

/* ---- Signature: root-cause resolver dial (keeps re-locking on the live cause) ---- */
.pl-resolver{display:flex;flex-direction:column;align-items:center;padding:20px 24px 26px}
.pl-dial{width:100%;max-width:660px;height:auto}
.pl-beam{stroke:var(--warn)}
.pl-reason-box{fill:var(--danger-bg);stroke:var(--danger);stroke-opacity:.5}
.pl-dial g.pl-ring{transform-box:view-box;transform-origin:230px 185px}
.pl-dial-cap{max-width:560px;text-align:center;margin:14px auto 0;color:var(--muted);font-size:var(--fs-small)}

/* ---- T+1: the silver London mark ---- */
.pl-t1{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(28px,4vw,56px);align-items:center}
.pl-t1-copy .sec-title{margin-top:8px}
.pl-t1-art{display:flex;justify-content:center}
.pl-t1-art .t1-mark{width:min(100%,380px)}

/* ---- Analytics: counterparty x root-cause heat matrix, with counts + legend ---- */
.pl-matrix{padding:24px}
.pl-mx-head{font-family:var(--font-mono);font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.08em;margin:0 0 14px}
.pl-mx-grid{display:grid;grid-template-columns:96px repeat(5,1fr);gap:6px;align-items:center}
.pl-colh{font-family:var(--font-mono);font-size:9.5px;color:var(--dim);letter-spacing:.02em;text-transform:uppercase;text-align:center;line-height:1.2}
.pl-rowh{font-family:var(--font-mono);font-size:11px;color:var(--muted);text-align:right;padding-right:8px}
.pl-mx-foot{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-top:16px;flex-wrap:wrap}
.pl-mx-legend{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:10.5px;color:var(--dim)}
.pl-mx-ramp{width:80px;height:8px;border-radius:3px;background:linear-gradient(90deg,transparent,var(--indigo-bright))}
.pl-mx-call{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:10.5px;color:var(--warn)}
.pl-mx-call::before{content:"";width:12px;height:12px;border-radius:3px;border:1.6px solid var(--warn)}

/* ---- Today / tomorrow ---- */
.pl-today,.pl-tomorrow{position:relative}
.pl-today{display:flex;flex-direction:column;justify-content:center;gap:14px;min-height:280px;padding:clamp(26px,3vw,40px)}
.pl-today-line{font-size:var(--fs-h3);line-height:1.3;color:var(--text);font-weight:500;letter-spacing:-.01em;margin:0}
.pl-tomorrow > .eyebrow{margin-bottom:12px}
.pl-tomorrow .rt-stage{margin:0}
.pl-tag{position:absolute;top:16px;right:18px;font-family:var(--font-mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;padding:3px 9px;border-radius:6px;z-index:4}
.pl-tag.live{color:var(--ok);background:var(--ok-bg);border:1px solid var(--ok)}
.pl-tag.dev{color:var(--indigo-lift);background:var(--info-bg);border:1px solid var(--brd-hover)}

@media (max-width:900px){
  .pl-split,.pl-split2,.pl-t1{grid-template-columns:1fr}
  .pl-stack{width:100%}
  .sec-head.is-right{text-align:left}
  .sec-head.is-right .eyebrow{justify-content:flex-start}
}

@media (prefers-reduced-motion:reduce){
  .pl-layerstack,.pl-ledger,.pl-resolver,.pl-matrix,.pl-t1{opacity:1;transform:none}
}

/* Keep the Roundtable's outside seat labels inside the narrower platform column */
.pl-tomorrow .rt-instrument{max-width:600px;margin-inline:auto;display:block}
.pl-tomorrow .rt-stage{padding-inline:clamp(18px,3vw,52px)}
@media (max-width:900px){ .pl-tomorrow .rt-instrument{max-width:520px} }

/* Roundtable fit, tuned: smaller instrument + more column share so labels clear */
.pl-split2{grid-template-columns:.66fr 1.34fr}
.pl-tomorrow .rt-instrument{max-width:500px}
.pl-tomorrow .rt-stage{padding-inline:clamp(8px,1.6vw,22px)}
@media (max-width:900px){ .pl-split2{grid-template-columns:1fr} .pl-tomorrow .rt-instrument{max-width:460px} }


/* --- ./pages/t1.css --- */
/* T+1 in Europe page. Signature: the live countdown and the window
   compression rail. The deadline is the monument. */

.t1p-hero { display: grid; grid-template-columns: 1.08fr .92fr; gap: clamp(30px, 4.5vw, 70px); align-items: center; }
.t1p-hero .lead { max-width: 620px; }
.t1p-art { display: grid; justify-items: center; gap: 26px; }
.t1p-art .t1-mark { width: min(100%, 430px); }

.t1p-count { display: flex; gap: clamp(14px, 2vw, 26px); font-variant-numeric: tabular-nums; }
.t1p-count .cell { text-align: center; border: 1px solid var(--brd); border-radius: 16px; background: var(--glass); padding: 14px 18px 12px; min-width: 86px; }
.t1p-count b { font-size: clamp(30px, 3.2vw, 46px); font-weight: 700; color: var(--text); display: block; line-height: 1; }
.t1p-count span { font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--dim); display: block; margin-top: 8px; }

/* The compression rail */
.cmp { display: grid; gap: 26px; padding: clamp(26px, 3.4vw, 44px); }
.cmp-row { display: grid; grid-template-columns: 92px 1fr; gap: 18px; align-items: center; }
.cmp-tag { font-family: var(--font-mono); font-size: 15px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.cmp-rail { position: relative; border: 1px solid var(--brd); border-radius: 14px; background: var(--bg-2); padding: 12px; display: flex; gap: 10px; overflow: hidden; transition: width 1.6s var(--ease-reveal); width: 100%; }
.cmp-row.is-t1 .cmp-rail { width: 100%; }
.io-in .cmp-row.is-t1 .cmp-rail { width: 54%; }
.cmp-chip { font-family: var(--font-mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--brd); border-radius: 999px; padding: 8px 14px; white-space: nowrap; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.cmp-row.is-t1 .cmp-chip { border-color: var(--brd-strong); }
.cmp-note { display: flex; justify-content: space-between; gap: 18px; font-family: var(--font-mono); font-size: 12.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); flex-wrap: wrap; }
.cmp-note .warn { color: var(--warn); }

/* Cited stats */
.t1p-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.t1p-stat { display: grid; gap: 10px; padding: 30px 28px; align-content: start; }
.t1p-stat .n { font-size: clamp(48px, 5vw, 74px); font-weight: 700; line-height: 1; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.t1p-stat .d { color: var(--muted); line-height: 1.55; }
.t1p-stat .src { font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); margin-top: 6px; }

/* The T+0 answer */
.t0-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.t0-row { display: grid; grid-template-columns: 1fr auto; gap: 8px 16px; padding: 24px 26px; align-items: center; }
.t0-row b { grid-column: 1; grid-row: 1; }
.t0-row .tag { grid-column: 2; grid-row: 1; justify-self: end; }
.t0-row .tag { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ok); border: 1px solid var(--ok); background: var(--ok-bg); border-radius: 999px; padding: 5px 12px; }
.t0-row b { font-size: 19px; color: var(--text); }
.t0-row p { grid-column: 1 / -1; margin: 0; color: var(--muted); line-height: 1.6; font-size: 15.5px; }
.t0-hl { grid-column: 1 / -1; padding: 30px clamp(24px, 3vw, 40px); display: grid; grid-template-columns: 1fr auto; gap: 10px 22px; align-items: center; }
.t0-hl b { grid-column: 1; grid-row: 1; }
.t0-hl .tag { grid-column: 2; grid-row: 1; justify-self: end; }
.t0-hl .tag { font-family: var(--font-mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ok); border: 1px solid var(--ok); background: var(--ok-bg); border-radius: 999px; padding: 5px 12px; }
.t0-hl b { font-size: clamp(21px, 2vw, 27px); color: var(--text); }
.t0-hl p { grid-column: 1 / -1; margin: 0; color: var(--muted); line-height: 1.65; }

/* Readiness checklist */
.chk { max-width: 980px; margin-inline: auto; display: grid; gap: 14px; }
.chk-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 26px; padding: 22px 26px; align-items: center; }
.chk-row .gap { color: var(--text); font-size: 17.5px; line-height: 1.5; }
.chk-row .fix { color: var(--muted); line-height: 1.55; font-size: 15.5px; display: flex; align-items: center; gap: 12px; }
.chk-row .fix svg { flex: 0 0 auto; color: var(--ok); }

/* Road to October 2027 */
.road-panel { padding: clamp(26px, 3.4vw, 46px); }
.road-svg { display: block; width: 100%; height: auto; overflow: visible; }
.road-line { stroke: var(--brd-strong); stroke-width: 2; }
.road-draw { stroke: var(--indigo-bright); stroke-width: 2.6; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 2.2s var(--ease-reveal); }
.io-in .road-draw { stroke-dashoffset: 0; }
.road-stop circle { fill: var(--elev); stroke: var(--brd-strong); stroke-width: 2.4; }
.road-stop.now circle { stroke: var(--indigo-bright); filter: drop-shadow(0 0 12px var(--indigo-bright)); }
.road-stop.fin circle { stroke: var(--ok); filter: drop-shadow(0 0 12px var(--ok)); }
.road-h { fill: var(--text); font-size: 21px; font-weight: 700; text-anchor: middle; }
.road-l { fill: var(--muted); font-family: var(--font-mono); font-size: 13px; letter-spacing: .1em; text-transform: uppercase; text-anchor: middle; }

@media (max-width: 1050px) {
  .t1p-hero { grid-template-columns: 1fr; }
  .t1p-stats { grid-template-columns: 1fr; }
  .t0-grid { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .cmp-row { grid-template-columns: 1fr; }
  .chk-row { grid-template-columns: 1fr; }
  .t1p-count .cell { min-width: 64px; padding: 10px 12px 9px; }
}
@media (prefers-reduced-motion: reduce) {
  .cmp-rail, .road-draw { transition: none; }
  .io-in .cmp-row.is-t1 .cmp-rail { width: 54%; }
}

/* Europe T+1 hero: center the countdown under the London mark, and give the
   hero sub and actions room to breathe. */
.t1p-art { display: flex; flex-direction: column; align-items: center; text-align: center; }
.t1p-art .t1-mark-wrap { display: flex; justify-content: center; }
.t1p-count { justify-content: flex-start; margin: clamp(26px, 3.5vw, 44px) 0 0; }  /* timer sits below the hero text */
.t1p-hero .lead { margin: 18px 0 0; }
.t1p-hero .hero-actions { justify-content: center; margin-top: clamp(22px, 3vw, 34px); }  /* buttons sit under the mark */

/* Europe stats: unboxed, thought-leadership metric styling (purple flashing
   unit, left accent, magnify on hover) with larger, more readable body text. */
.t1p-stats { align-items: start; }
.t1p-stat { position: relative; padding: 22px 6px 22px 20px; background: none; border: 0; transition: transform .4s cubic-bezier(.22,.61,.36,1); }
.t1p-stat::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 2px; border-radius: 2px; background: var(--indigo-bright); box-shadow: 0 0 12px var(--indigo-bright); transform: scaleY(0); opacity: 0; transition: transform .36s cubic-bezier(.22,.61,.36,1), opacity .28s ease; }
.t1p-stat:hover::before { transform: scaleY(1); opacity: 1; }
.t1p-stat .stat-num { font-size: clamp(46px, 4vw, 60px); font-weight: 800; line-height: 1; color: var(--text); letter-spacing: -.03em; font-variant-numeric: tabular-nums; transform-origin: left center; transition: transform .4s cubic-bezier(.22,.61,.36,1); }
.t1p-stat:hover .stat-num { transform: translateX(8px) scale(1.06); }
.t1p-stat .stat-num .u { color: var(--indigo-lift); }
.t1p-stat .stat-num .u.is-pct { margin-left: .06em; }
.t1p-stat:hover .stat-num .u { animation: uShimmer .6s ease-out 1; }
.t1p-stat .d { font-size: 17px; line-height: 1.62; color: var(--muted); margin: 6px 0 0; transform-origin: left center; transition: color .3s ease, transform .38s cubic-bezier(.22,.61,.36,1); }
.t1p-stat:hover .d { color: var(--text); transform: translateX(8px) scale(1.02); }

/* T+0 answer windows: bigger, more readable body text. */
.t0-row p, .t0-hl p { font-size: 17px; line-height: 1.66; }
.t0-row b { font-size: 20px; }

/* Readiness: unboxed rows, larger text, hairline dividers, hover magnify. */
.chk-row { background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: 22px 6px; transition: transform .34s var(--ease-out); }
.chk-row:last-child { border-bottom: 0; }
.chk-row:hover { transform: scale(1.01); }
.chk-row .gap { font-size: 18px; color: var(--muted); }
.chk-row .fix { font-size: 17px; color: var(--text); }

/* Readiness redesign: boxed problem -> fix rows, larger readable text. */
.chk { max-width: 1080px; display: grid; gap: 16px; }
.chk-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: clamp(16px, 3vw, 40px); padding: 24px clamp(22px, 3vw, 34px); border: 1px solid var(--brd); border-radius: 16px; background: var(--glass); transition: transform .3s ease, border-color .3s ease; }
.chk-row:hover { transform: scale(1.008); border-color: var(--brd-hover); }
.chk-row.panel:hover { transform: var(--window-hover-transform); }
.chk-tag { display: block; font-family: var(--font-mono); font-size: 11.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--dim); margin-bottom: 8px; }
.chk-tag.is-ok { color: var(--ok); }
.chk-gap p { margin: 0; font-size: 18px; line-height: 1.5; color: var(--muted); }
.chk-fix p { margin: 0; font-size: 18px; line-height: 1.5; color: var(--text); font-weight: 500; display: flex; gap: 10px; align-items: flex-start; }
.chk-fix svg { flex: 0 0 auto; color: var(--ok); margin-top: 1px; }
.chk-arrow { color: var(--indigo-lift); display: flex; }
@media (max-width: 760px) { .chk-row { grid-template-columns: 1fr; } .chk-arrow { display: none; } }


/* --- ./pages/error.css --- */
/* -----------------------------------------------------------------------------
   404. Header and footer are the shared shell; the middle is deliberately
   empty apart from the mark.

   The art is centred by letting the section absorb whatever vertical space is
   left between the header and the footer, rather than by guessing a height.
   #ssSite.site is already a flex container with a full-viewport minimum, so
   main only has to become a flex item that grows, and the section only has to
   grow inside it. That stays correct at every window size, and on a short
   window the section simply stops growing and the page scrolls as normal.

   Measured before this rule at 1440x900: the art's centre sat 66px above the
   true midpoint, partly because the section's own min-height was smaller than
   the space available and partly because .section pads 56px at the top and
   76px at the bottom. Both are neutralised here.

   Note: base.njk writes <body class="v3-page {{ pageKey }}">, so this page also
   carries the class "404". A CSS selector cannot start with a digit, hence
   [data-page="404"], which base.njk sets alongside it.
   -------------------------------------------------------------------------- */
body[data-page="404"] #main.page-body {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.err-stack {
  flex: 1;
  min-height: clamp(320px, 46vh, 640px);
  justify-content: center;
  padding-top: 0;
  padding-bottom: 0;
}

.err-art {
  display: block;
  width: min(760px, 62vw);
  height: auto;
  margin: 0 auto;
}

/* Must take its colour from the theme token, not inherit and dim. Verified: an
   opacity-only rule rendered as near-black text on the near-black dark
   background and was effectively invisible. */
.err-msg {
  margin: 22px 0 0;
  font-size: clamp(17px, 1.5vw, 20px);
  color: var(--muted);
}

@media (max-width: 760px) { .err-art { width: 82vw; } }


/* --- ./pages/search.css --- */
/* -----------------------------------------------------------------------------
   SEARCH RESULTS (/search/)

   This file is deliberately short. The page is built almost entirely out of
   components that already exist, so there is very little here that is new:

     .sec-head / .eyebrow / .h1 / .sec-intro   the standard page header
     .f-list / .f-row / .f-ico / .h4 / .small-t  the feature-row list, the same
                                               unboxed row with a left accent
                                               bar and a hover magnify used on
                                               the platform and Europe T+1 pages
     .sec-caption                              the mono micro-label
     .data-label                               the mono section tag
     .btn .btn-secondary                       the empty-state action

   The only genuinely new thing is the search bar, and that is a deliberate
   restatement of the header's .site-search in shell/frame.css: no box, no
   border, no fill, an icon that lights up, and a hairline that turns indigo and
   glows on focus. The header version also expands on hover, which is pointless
   here because the bar is the point of the page, so that part is dropped.
   -------------------------------------------------------------------------- */

.srch-stack { max-width: 860px; }
.srch-stack .sec-head { margin-bottom: 30px; }

/* --- The bar. Modelled on .site-search, unboxed. --------------------------

   The bar spans the full width of .srch-stack on purpose, so its hairline lines
   up exactly with the dividers between the results below it. A narrower bar
   read as a separate, unrelated element.

   Two states drive the colour, and they are deliberately not the same thing:

     :focus-within   the cursor is in the field
     .has-query      the field has text in it, focused or not

   The second one is why arriving from the header with a query already typed
   shows a purple bar rather than a grey one: the page is not focused, but there
   is a search in progress and the bar should say so. Clearing the field fades
   it back to grey and the placeholder returns. scripts/site.js toggles the
   class; every transition below is symmetrical, so it fades both ways.

   The purple is var(--icon-hover), which is already a theme pair: #7C60FF on
   dark, #5333EC on light. Same token the header search uses.
   -------------------------------------------------------------------------- */
.srch-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 6px 2px 14px 0;
  border-bottom: 1px solid var(--line);
}
/* The live underline, exactly the treatment .site-search::after uses. */
.srch-bar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  border-radius: 999px;
  background: var(--icon-hover);
  box-shadow: 0 0 12px color-mix(in srgb, var(--icon-hover) 28%, transparent);
  opacity: 0;
  transform: scaleX(.02);
  transform-origin: left center;
  transition: transform var(--motion-window), opacity .34s ease;
}
.srch-bar:focus-within::after,
.srch-bar.has-query::after {
  opacity: 1;
  transform: scaleX(1);
}

.srch-btn {
  flex: none;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color .24s ease, transform var(--motion-window), filter .34s ease;
}
.srch-btn svg { width: 20px; height: 20px; }
.srch-bar:focus-within .srch-btn,
.srch-bar.has-query .srch-btn,
.srch-btn:hover {
  color: var(--icon-hover);
  transform: scale(1.12);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--icon-hover) 72%, transparent));
}

.srch-bar input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 500;
  letter-spacing: -.01em;
  padding: 6px 0;
}
.srch-bar input::placeholder { color: var(--dim); font-weight: 400; }
/* The native clear button is a grey bitmap that cannot be restyled, only
   filtered. Hidden, and replaced by .srch-clear below. */
.srch-bar input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
/* Same reasoning as .site-search in shell/frame.css: the default ring draws a
   rectangle around a field that has deliberately no box, and the focus state
   here is already unmistakable without it. The bar's hairline doubles in
   height, turns indigo and gains a glow, and the icon scales and glows too, so
   focus is signalled by size and light, not by colour alone. */
.srch-bar input:focus,
.srch-bar input:focus-visible { outline: none; }

/* --- Results -------------------------------------------------------------- */
.srch-count { margin: 22px 0 0; min-height: 1.4em; color: var(--dim); }
.srch-results:empty { display: none; }
.srch-results { margin-top: 10px; }

/* .f-row is a div elsewhere on the site. Here the whole row is the link. */
a.srch-row { text-decoration: none; color: inherit; }
a.srch-row:last-child { border-bottom: 0; }
.srch-row .srch-sec {
  font-size: 11.5px;
  letter-spacing: .14em;
  color: var(--dim);
  margin-bottom: 7px;
  transform-origin: left center;
  transition: color .34s ease;
}
.srch-row:hover .srch-sec { color: var(--indigo-lift); }
.srch-row:hover .h4 { color: var(--indigo-lift); }
/* The matched words. A tint rather than colour alone, so it survives both
   themes and does not rely on hue to be noticed. */
.srch-row mark {
  background: color-mix(in srgb, var(--indigo-lift) 24%, transparent);
  color: var(--text);
  border-radius: 3px;
  padding: 0 2px;
}

.srch-all-lead { margin: 40px 0 4px; color: var(--dim); }
.srch-all[hidden] { display: none; }

/* --- No match ------------------------------------------------------------
   A dead end is the wrong answer for somebody who arrived with a question, so
   this block is built to move them on rather than to apologise. It sits on the
   same left edge as the results and the bar, with real air around the actions
   instead of a button jammed under a paragraph.
   ------------------------------------------------------------------------ */
.srch-none {
  max-width: 60ch;
  padding: 34px 0 8px;
}
.srch-none-lead {
  margin: 0;
  font-size: clamp(20px, 2vw, 24px);
  line-height: 1.4;
  letter-spacing: -.01em;
  color: var(--text);
}
.srch-none-lead b { color: var(--indigo-lift); font-weight: 700; }
.srch-none-body {
  margin: 14px 0 0;
  font-size: 17px;
  line-height: 1.68;
  color: var(--muted);
}
.srch-none-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 30px;
}
.srch-none-try {
  margin: 30px 0 0;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1.9;
  color: var(--dim);
}

@media (max-width: 520px) {
  .srch-none-actions { gap: 10px; }
  .srch-none-actions .btn { flex: 1 0 100%; justify-content: center; }
}

@media (max-width: 640px) {
  .srch-bar { gap: 10px; }
  .srch-bar input { font-size: 19px; }
}

/* -----------------------------------------------------------------------------
   CLEAR BUTTON (.srch-clear)

   Two bars that swing into a cross, borrowed from the FAQ plus icon and the
   menu button so the site has one idea about how a cross is drawn rather than
   three. Same easing as the FAQ icon.

   It is not in the tab order. Escape already clears the field and is faster for
   anyone using a keyboard, and a control that only exists while there is text
   is a confusing thing to land on.
   -------------------------------------------------------------------------- */
.srch-clear {
  position: relative;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  margin-left: 10px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  border-radius: 50%;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s ease, visibility .35s;
}
.srch-clear i {
  position: absolute;
  left: 7px;
  top: 14px;
  width: 16px;
  height: 1.5px;              /* thin, like the menu bars, not the browser's slab */
  border-radius: 2px;
  background: var(--indigo-lift);
  transform: rotate(0deg) scaleX(.2);
  transition: transform .6s cubic-bezier(.3, .8, .3, 1), background .3s ease;
}
/* Shown by site.js on the same condition that lights the bar: there is a query.
   The bars grow out from the middle and rotate into the cross. Going away, they
   unwind and fold back in. */
.srch-bar.has-query .srch-clear { opacity: 1; visibility: visible; }
.srch-bar.has-query .srch-clear i:first-child { transform: rotate(45deg) scaleX(1); }
.srch-bar.has-query .srch-clear i:last-child  { transform: rotate(-45deg) scaleX(1); }

.srch-clear:hover i { background: var(--indigo-bright); }
.srch-clear:hover i:first-child { transform: rotate(225deg) scaleX(1); }
.srch-clear:hover i:last-child  { transform: rotate(135deg) scaleX(1); }
.srch-clear:focus-visible { outline: 2px solid var(--indigo-lift); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  .srch-clear i { transition: none; }
  .srch-clear:hover i:first-child { transform: rotate(45deg) scaleX(1); }
  .srch-clear:hover i:last-child  { transform: rotate(-45deg) scaleX(1); }
}


/* --- ./components/forms.css --- */
/* =============================================================================
   Forms - inputs, selects, textareas, labels  (form windows)
   -----------------------------------------------------------------------------
   The authored, documented source of truth for form controls (Contact,
   Request Demo). Wrap fields in <form class="ss-form">; each field is a
   <label> that contains its text then the control:

     <form class="ss-form">
       <div class="form-grid">                          two-up on wide, stacks on narrow
         <label>Name<input type="text" placeholder="…"></label>
         <label>Inquiry type<select>…</select></label>
       </div>
       <label>Message<textarea rows="4"></textarea></label>
       <button class="btn btn-primary">Submit</button>
     </form>

   Controls fill their label, share one radius/border, and lift on focus with an
   indigo focus ring. Selects get a custom chevron (native arrow removed).
   ========================================================================== */

/* Sits clear of any heading above it (e.g. "How can we help?" in the panel). */
.ss-form { display: flex; flex-direction: column; gap: 18px; margin-top: 22px; }

/* Submit keeps its natural width at the left edge (live-site behavior) instead
   of stretching across the flex column. Add .is-wide-submit on the form when
   the button should span the whole card (e.g. Request Demo). */
.ss-form > button[type="submit"] { align-self: flex-start; }
.ss-form.is-wide-submit > button[type="submit"] { align-self: stretch; width: 100%; }


/* Label = field title stacked above its control. */
.ss-form label {
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: .01em;
}

/* Two fields per row on wide screens; each drops to full width under ~210px. */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 18px;
}

/* Shared control base - input, select, textarea. */
.ss-form input,
.ss-form select,
.ss-form textarea {
  font: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--brd);
  border-radius: 11px;
  min-height: 49px;
  padding: 12px 15px 13px;
  outline: none;
  width: 100%;
  transition: border-color .2s, box-shadow .2s, background .2s;
}

.ss-form textarea { resize: vertical; min-height: 120px; }

.ss-form input::placeholder,
.ss-form textarea::placeholder { color: var(--dim); }

/* Whiter lift on hover, and persistently once a field is filled (completed).
   :not(:placeholder-shown) = the input/textarea now holds a value. */
.ss-form input:hover,
.ss-form select:hover,
.ss-form textarea:hover,
.ss-form input:not(:placeholder-shown),
.ss-form textarea:not(:placeholder-shown) {
  border-color: var(--field-glow-brd);
  box-shadow: 0 0 0 1px var(--field-glow-brd), 0 0 16px var(--field-glow);
  background-color: var(--elev);   /* not `background` - keeps the select chevron */
}

/* Focus - indigo ring + slightly lifted surface. */
.ss-form input:focus,
.ss-form select:focus,
.ss-form textarea:focus {
  border-color: var(--brd-hover);
  box-shadow: 0 0 0 3px var(--info-bg);
  background-color: var(--elev);   /* not `background` - keeps the select chevron */
}

/* Select - native arrow removed, custom chevron drawn from two gradients. */
.ss-form select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-right: 38px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 19px) center, calc(100% - 14px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.ss-form option { background: var(--elev); color: var(--text); font-weight: 500; padding: 10px 14px; }

/* Light mode: glassy see-through fields (match dark-mode transparency) */
[data-theme="light"] .ss-form input,
[data-theme="light"] .ss-form select,
[data-theme="light"] .ss-form textarea { background-color: rgba(255,255,255,.2); }
.ss-form option:checked { background: var(--hover); color: var(--text); }
/* Until a real value is chosen, a required select shows its "Select …" prompt
   in the same grey as input placeholders. (:invalid = required + empty value;
   forms are novalidate so this never blocks submission.) */
.ss-form select:required:invalid { color: var(--dim); }

/* -----------------------------------------------------------------------------
   Request Demo layout - three-up field grid with starred titles.
     <label><span class="field-title">First Name<span class="req">*</span></span>
            <input …></label>
   -------------------------------------------------------------------------- */
.request-demo-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}
@media (max-width: 900px) { .request-demo-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .request-demo-grid { grid-template-columns: 1fr; } }
.field-title {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
}
.req { color: var(--indigo-bright); margin-left: 0; }

/* Success state - hidden via the [hidden] attribute until site.js reveals it
   after a confirmed submission (form hides, this block takes its place). */
.form-success {
  display: grid;
  gap: 16px;
  padding: 44px 0 12px;   /* drop the confirmation lower, clear of the submit button */
}
.form-success[hidden] { display: none; }


/* Accessible inline form error (role="alert"), replacing alert() dialogs. */
.form-error {
  margin: 0 0 16px;
  padding: 11px 15px;
  border-radius: 10px;
  background: rgba(229, 72, 77, .12);
  border: 1px solid rgba(229, 72, 77, .55);
  color: var(--text);
  font-size: 14px;
  line-height: 1.45;
}
.ss-form [aria-invalid="true"] {
  border-color: #e5484d !important;
  box-shadow: 0 0 0 1px rgba(229, 72, 77, .4);
}


/* --- ./components/faq.css --- */
/* =============================================================================
   FAQ - accordion, group labels, and the gated "unlock" block  (FAQ page)
   -----------------------------------------------------------------------------
   Questions are native <details>/<summary> so they work without JS:

     <div class="faq-group-label">General</div>
     <div class="faq-list">
       <details class="faq-item">
         <summary class="faq-q">Question?<span class="faq-ico"></span></summary>
         <div class="faq-a"><p>Answer.</p></div>
       </details>
     </div>

   The gated section wraps a .faq-gate-head (pitch + .faq-unlock mini-form) and
   its own .faq-list. Until site.js adds .unlocked to .faq-gate, the questions
   are dimmed and locked (a small padlock replaces the +). Locked items swap
   icons with a springy rotate; unlocking is remembered per-browser.
   ========================================================================== */

.faq-list {
  border-top: 1px solid var(--line);
  max-width: 860px;
}
.faq-item { border-bottom: 1px solid var(--line); }

/* Question row - full-width click target with the +/× icon on the right. */
.faq-q {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 26px 4px;
  font-size: clamp(17px, 1.7vw, 21px);
  font-weight: 600;
  color: var(--text);
  transition: color .2s;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q:hover { color: var(--indigo-lift); }

/* Hover: the question magnifies from the left (same language as Resource rows)
   while the + icon pulses. Wrap the question in .faq-q-text so only the text
   scales, not the icon. */
.faq-q-text {
  transform-origin: left center;
  transition: transform var(--motion-hover);
}
.faq-q:hover .faq-q-text { transform: scale(1.05); }
.faq-q:hover .faq-ico { animation: faqIcoPulse 1.3s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .faq-q:hover .faq-ico { animation: none; } }
@keyframes faqIcoPulse {
  0%, 100% { transform: scale(1); filter: none; }
  50% { transform: scale(1.28); filter: drop-shadow(0 0 7px var(--indigo-bright)); }
}

/* Plus icon drawn from two bars; the vertical bar spins away when open. */
.faq-ico {
  position: relative;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
.faq-ico::before,
.faq-ico::after {
  content: "";
  position: absolute;
  background: var(--indigo-bright);
  border-radius: 2px;
  transition: transform .6s cubic-bezier(.3, .8, .3, 1);
}
.faq-ico::before { left: 0; top: 8px; width: 18px; height: 2px; }
.faq-ico::after { left: 8px; top: 0; width: 2px; height: 18px; }
details[open] .faq-ico::after { transform: rotate(90deg); opacity: 0; }
details[open] .faq-ico::before { transform: rotate(180deg); }

/* Answer body - fades/slides in when the item opens. */
.faq-a { overflow: hidden; }
.faq-a p {
  margin: 0 0 18px;
  padding-right: 42px;
  font-size: 16px;
  line-height: 1.7;
  color: var(--muted);
}
details[open] .faq-a { animation: faqOpen .4s ease; }
@keyframes faqOpen {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}

/* Mono category label above each question group ("General", "T+1 in Europe"). */
.faq-group-label {
  font-family: var(--font-mono);
  font-size: 16px;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--indigo-lift);
  margin: 50px 0 6px;
}
.section > .faq-group-label:first-child { margin-top: 0; }

/* -----------------------------------------------------------------------------
   Gated block - glass pitch panel + inline unlock form above locked questions.
   The head is a .panel (glass, spotlight, sheen sweep, hover magnify all come
   from the global panel object) - use <div class="panel faq-gate-head">.
   -------------------------------------------------------------------------- */
.faq-gate-head {
  margin-top: 54px;
  padding: clamp(24px, 3vw, 34px);
  border-color: var(--brd-hover);
  border-radius: 18px;
  max-width: 860px;
}
.faq-gate-head h3 {
  margin: 0;
  font-size: clamp(20px, 2vw, 26px);
  letter-spacing: -.015em;
}
.faq-gate-head p {
  margin: 9px 0 0;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.62;
  max-width: 62ch;
}

/* Unlock mini-form - a compact .ss-form (all field styling - glass controls,
   hover lift, focus ring, select chevron - comes from the global form object;
   use <form class="ss-form faq-unlock">). This layer only sets the layout:
   a three-up grid (First/Last/Email, then Company/Ecosystem + Unlock),
   collapsing to two then one column as the gate narrows. */
.faq-unlock {
  margin-top: 22px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  align-items: end;
}
.faq-unlock label {
  font-size: 12px;
  gap: 7px;
}
/* Unlock fills its grid cell and matches the field height beside it. */
.faq-unlock > button[type="submit"] {
  align-self: end;
  justify-self: stretch;
  width: 100%;
  min-height: 49px;
}
@media (max-width: 720px) { .faq-unlock { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .faq-unlock { grid-template-columns: 1fr; } }
.faq-unlocked-note {
  margin-top: 18px;
  display: none;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-family: var(--font-mono);
  letter-spacing: .04em;
  color: var(--ok);
}
/* The pip pulses green: --signal feeds the shared dotGlow keyframes, so
   re-pointing it at --ok makes the standard .anim pulse glow green here. */
.faq-unlocked-note .live-dot {
  background: var(--ok);
  box-shadow: 0 0 10px var(--ok);
  --signal: var(--ok);
}
.faq-gate.unlocked .faq-unlock { display: none; }
.faq-gate.unlocked .faq-unlocked-note { display: flex; }
/* Same breathing room below the gate panel as above it (54px). */
.faq-gate .faq-list { margin-top: 54px; }
.faq-gate:not(.unlocked) .faq-q {
  color: var(--dim);
  cursor: default;
  pointer-events: none;
}

/* Locked items carry BOTH icons stacked; lock and + crossfade on unlock. */
.faq-ico-wrap {
  position: relative;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}
/* Slow, springy crossfade: each padlock melts away as its + spins in. */
.faq-ico-wrap .faq-ico {
  position: absolute;
  inset: 0;
  transition: opacity .9s ease, transform 1.15s cubic-bezier(.3, 1.25, .4, 1);
}
.lk-lock {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--dim);
  transition: opacity .9s ease, transform 1.15s cubic-bezier(.3, 1.25, .4, 1);
}
.faq-gate:not(.unlocked) .faq-ico-wrap .faq-ico { opacity: 0; transform: scale(.4) rotate(-90deg); }
.faq-gate.unlocked .lk-lock { opacity: 0; transform: rotate(90deg) scale(.3); pointer-events: none; }


/* --- ./components/team-cards.css --- */
/* =============================================================================
   Team / headshot cards  (.tm-card)
   -----------------------------------------------------------------------------
   Portrait tiles with a frosted hover state: at rest the photo shows with the
   name + role below it; on hover (or keyboard focus) a blurred overlay fades in,
   the name rises to the top with a LinkedIn badge, and the bio reveals. The
   whole tile is a link to the person's LinkedIn.

   Markup:
     <div class="tm-grid">
       <article class="tm-card" tabindex="0">
         <a class="tm-frame" href="…" target="_blank" rel="noopener" aria-label="Name on LinkedIn">
           <img class="tm-photo" src="…" alt="Name" style="object-position:50% 18%">
         </a>
         <div class="tm-over">
           <div class="tm-over-head">
             <div class="tm-over-id"><h3>Name</h3><p>Role</p></div>
             <span class="tm-li" aria-hidden="true"><svg …>…</svg></span>
           </div>
           <p class="tm-bio">Short bio…</p>
         </div>
         <div class="tm-meta"><h3>Name</h3><p>Role</p></div>
       </article>
     </div>

   Per-photo framing uses named .tm-crop-* classes so every headshot adjustment
   is kept global and reviewable. Touch devices (no hover) fall back to a static,
   always-open card.
   ========================================================================== */

.tm-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 30px 22px;
}
.tm-grid-roster {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}
.tm-grid-roster > .tm-card { flex: 0 1 calc((100% - 88px) / 5); min-width: 0; }

.tm-card { position: relative; cursor: pointer; outline: none; }
.tm-card:hover,
.tm-card:focus-within { z-index: 5; }

/* Portrait frame - indigo gradient behind a cover photo, lifts on hover. */
.tm-frame {
  position: relative;
  display: block;
  text-decoration: none;
  cursor: pointer;
  aspect-ratio: 7 / 10;
  border-radius: 18px;
  overflow: hidden;
  background: #fff;
  border: 0;
  box-shadow: none;
  transition: box-shadow .34s ease, transform var(--motion-window);
}
.tm-card:hover .tm-frame,
.tm-card:focus-visible .tm-frame,
.tm-card:focus-within .tm-frame {
  box-shadow: 0 18px 44px -28px color-mix(in srgb, var(--indigo-bright) 58%, transparent);
  transform: none;
}
.tm-frame:focus-visible {
  outline: 2px solid var(--indigo-bright);
  outline-offset: 4px;
}

/* The headshot - covers the frame, zooms slightly on hover. */
.tm-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 16%;
  transform: translate(var(--tx, 0%), var(--ty, 0%)) scale(var(--z, 1));
  transform-origin: 50% 50%;
  will-change: auto;
  transition: transform var(--motion-hover);
}
.tm-crop-david { object-position: 50% 19%; }
.tm-crop-cynthia,
.tm-crop-ken { object-position: 50% 15%; }
.tm-crop-tracy { object-position: 50% 18%; }
.tm-crop-ben { object-position: 50% 28%; }
.tm-crop-george { object-position: 50% 3%; }
.tm-crop-jonathan {
  object-position: 50% 0%;
  --z: 1.46;
  --ty: 15%;   /* nudged down so the face sits level with the rest of the row */
}
.tm-crop-scott { object-position: 50% 8%; --z: 1.16; }
.tm-crop-neil {
  object-position: 50% 10%;
  --z: 1.18;
  --ty: 11%;
}
.tm-card:hover .tm-photo,
.tm-card:focus-within .tm-photo {
  transform: translate(var(--tx, 0%), var(--ty, 0%)) scale(calc(var(--z, 1) * 1.06));
}

/* Frosted hover overlay - sits over the frame; clicks pass through to the link. */
.tm-over {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  aspect-ratio: 7 / 10;
  z-index: 3;
  border-radius: 18px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 18px 18px 19px;
  pointer-events: none;
  backdrop-filter: blur(9px) saturate(.95) brightness(.9);
  -webkit-backdrop-filter: blur(9px) saturate(.95) brightness(.9);
  background: linear-gradient(180deg, rgba(8, 6, 16, .42) 0%, rgba(8, 6, 16, .26) 45%, rgba(8, 6, 16, .54) 100%);
  opacity: 0;
  transition: opacity .42s ease;
}
.tm-card:hover .tm-over,
.tm-card:focus-within .tm-over { opacity: 1; }

.tm-over-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  opacity: 0;
  transform: translateY(-16px);
  transition: opacity .42s ease, transform var(--motion-hover);
}
.tm-card:hover .tm-over-head,
.tm-card:focus-within .tm-over-head { opacity: 1; transform: translateY(0); }

.tm-over-id h3 { margin: 0; font-size: 20px; font-weight: 700; color: #fff; letter-spacing: -.014em; line-height: 1.14; text-shadow: 0 1px 10px rgba(0, 0, 0, .5); }
.tm-over-id p { margin: 6px 0 0; font-size: 15px; font-weight: 600; font-family: var(--font-mono); letter-spacing: .05em; text-transform: uppercase; color: #D9D2FF; text-shadow: 0 1px 8px rgba(0, 0, 0, .55); }

/* Overlay action badges. LinkedIn uses its brand blue; booking uses the
   SmartSettle indigo cube with a white hurricane mark. */
.tm-actions {
  flex: 0 0 auto;
  display: grid;
  gap: 8px;
  justify-items: end;
  pointer-events: auto;
}
.tm-action {
  position: relative;
  flex: 0 0 auto;
  width: 31px;
  height: 31px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  color: #fff;
  transform-origin: center;
  transition: box-shadow .34s ease, filter .34s ease;
}
.tm-action:hover,
.tm-action:focus-visible {
  filter: brightness(1.08);
}
.tm-action:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}
.tm-li {
  background: #0A66C2;
  box-shadow: 0 6px 18px rgba(10, 102, 194, .55);
}
.tm-book {
  background: linear-gradient(145deg, var(--indigo-bright), var(--indigo));
  box-shadow: 0 6px 18px rgba(83, 51, 236, .58);
}
.tm-action svg,
.tm-action img {
  width: 17px;
  height: 17px;
  display: block;
  object-fit: contain;
  transform-origin: center;
  transition: transform var(--motion-window);
}
.tm-book img { width: 36px; height: 36px; }
.tm-action:hover svg,
.tm-action:focus-visible svg,
.tm-action:hover img,
.tm-action:focus-visible img { transform: scale(1.18); }
.tm-book[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  right: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  width: max-content;
  max-width: 190px;
  padding: 7px 9px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--elev) 94%, transparent);
  border: 1px solid var(--brd-strong);
  color: var(--text);
  font-size: 11px;
  line-height: 1.25;
  font-weight: 650;
  letter-spacing: 0;
  white-space: nowrap;
  box-shadow: 0 10px 24px rgba(0,0,0,.28);
  opacity: 0;
  pointer-events: none;
  transition: opacity .16s ease;
}
.tm-book[data-tip]:hover::after,
.tm-book[data-tip]:focus-visible::after {
  opacity: 1;
}

.tm-bio {
  margin: auto 0;
  font-size: 14.5px;
  line-height: 1.48;
  color: #fff;   /* overlay sits on a dark photo scrim - stay white in both themes */
  text-wrap: pretty;
  font-weight: 400;
  text-shadow: 0 1px 8px rgba(0, 0, 0, .5);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity .44s ease .06s, transform .95s var(--ease-reveal) .06s;
}
.tm-card:hover .tm-bio,
.tm-card:focus-within .tm-bio { opacity: 1; transform: translateY(0); }

/* Name + role shown below the photo at rest; fades out as the overlay opens. */
.tm-meta { padding: 14px 2px 0; transition: opacity .34s ease, transform var(--motion-hover); }
.tm-card:hover .tm-meta,
.tm-card:focus-within .tm-meta { opacity: 0; transform: none; }
.tm-meta h3 { margin: 0; font-size: 20px; font-weight: 700; color: var(--text); letter-spacing: -.014em; }
.tm-meta p { margin: 6px 0 0; font-size: 15.5px; line-height: 1.35; font-weight: 650; color: var(--indigo-lift); font-family: var(--font-mono); letter-spacing: .04em; text-transform: uppercase; }

/* Touch devices - no hover, so show a static open card (overlay flattened out). */
@media (hover: none) {
  .tm-over {
    position: static;
    aspect-ratio: auto;
    overflow: visible;
    opacity: 1;
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    padding: 13px 2px 0;
  }
  .tm-over-head { opacity: 1; transform: none; }
  .tm-over-id h3 { color: var(--text); }
  .tm-actions { justify-items: start; grid-auto-flow: column; }
  .tm-action { box-shadow: none; }
  .tm-book[data-tip]::after { display: none; }
  .tm-bio { opacity: 1; transform: none; color: var(--muted); margin: 9px 0 0; font-size: 14.5px; }
  .tm-photo { filter: none !important; }
  .tm-meta { display: none; }
}

@media (max-width: 1180px) {
  .tm-grid-roster > .tm-card { flex-basis: calc((100% - 44px) / 3); }
}
@media (max-width: 760px) {
  .tm-grid-roster > .tm-card { flex-basis: calc((100% - 22px) / 2); }
}
@media (max-width: 540px) {
  .tm-grid-roster > .tm-card { flex-basis: 100%; }
}


/* --- ./components/webinar.css --- */
/* =============================================================================
   Webinar recap page (/resources/webinar-jul29)
   -----------------------------------------------------------------------------
   Kept in its own file rather than in blocks.css so the recap feature can be
   branched, shipped, or reverted without touching the shared long-form styles
   that the Privacy and Terms pages depend on.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   GATED WEBINAR RECAP (.wg-player / .wg-gate) - resources/webinar-jul29.
   The player mount ships EMPTY and hidden. site.js injects an iframe into it
   only after the Worker grants access, so there is no video URL in the page
   source. Do not put a fallback iframe in here.
   -------------------------------------------------------------------------- */
.wg-player {
  position: relative;
  margin: 0 0 34px;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--brd);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
}
.wg-player[hidden] { display: none; }
.wg-player iframe,
.wg-player video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: contain; background: #000; }

/* Belt and braces on the download affordance. controlsList="nodownload" is the
   real mechanism (set in site.js); this hides the button in WebKit builds that
   ignore it. Neither is a security control - the actual protection is that the
   host only serves the file to smartsettle.ai with a signed, expiring URL. */
.wg-player video::-webkit-media-controls-download-button { display: none; }

/* Captions. ::cue is the only hook browsers give for subtitle text, and it
   accepts a deliberately short list of properties - background, colour, font,
   line-height. Sizing is a percentage because it resolves against the video
   box, so it scales with the player instead of fighting it. The same rules are
   duplicated in a STYLE block inside the .vtt file, which is what applies when
   the track is served cross-origin. */
.wg-player video::cue {
  background: rgba(11, 10, 16, .80);
  color: #F4F3FA;
  font-family: var(--font-sans, system-ui), sans-serif;
  font-size: 88%;
  line-height: 1.45;
}
.wg-player video::-webkit-media-text-track-display { padding-bottom: 6px; }
.wg-player video::-webkit-media-controls-enclosure { overflow: hidden; }
.wg-gate { scroll-margin-top: 100px; transition: opacity .32s ease, transform .32s ease; }

/* Handing over from form to player: the panel lifts and fades, the player
   fades up in its place. Without this the video simply popped into existence.
   site.js sets [hidden] on the panel once the fade finishes, so it leaves the
   layout entirely rather than sitting there invisible. */
.wg-gate.is-dismissed { opacity: 0; transform: translateY(-8px); pointer-events: none; }
.wg-player { opacity: 0; transition: opacity .45s ease .06s, transform .45s ease .06s; transform: translateY(8px); }
.wg-player.is-live { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .wg-gate, .wg-player { transition: none; transform: none; }
}
.wg-covered { margin-top: 56px; }

/* Honeypot. Positioned off-canvas rather than display:none, because bots skip
   fields that are display:none but still fill ones they can "see" in the DOM. */
.hp-field {
  position: absolute;
  left: -9999px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* -----------------------------------------------------------------------------
   CHAPTER STRIP (.wg-chapters)

   Sits flush under the player, so it reads as part of it rather than as a
   separate widget. No browser allows drawing inside its native video scrubber,
   so this is the closest honest thing: a second bar, immediately below, where
   each segment is as wide as its chapter is long. Glance at it and you can see
   that the Q&A is the last quarter of the recording.

   Built entirely in JS from the chapters VTT, so if that fetch fails there is
   simply no strip and the player is exactly as it was.
   -------------------------------------------------------------------------- */
/* Only when a strip was actually built: the player keeps its own rounded
   bottom and its margin when there are no chapters. */
.wg-player.has-chapters {
  margin-bottom: 0;
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}
.wg-chapters { margin: 0 0 34px; }

.wg-rail {
  display: flex;
  gap: 2px;
  height: 12px;
  border-radius: 0 0 14px 14px;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--brd);
  border-top: 0;
  padding: 2px;
}
.wg-seg {
  position: relative;
  flex: 1 1 0;
  min-width: 4px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: var(--line);
  cursor: pointer;
  overflow: hidden;
  transition: background .18s ease, transform .18s ease;
}
.wg-seg:hover { background: var(--brd-hover); transform: scaleY(1.35); }
.wg-seg:focus-visible { outline: 2px solid var(--indigo-lift); outline-offset: 2px; }
/* The played portion of each segment. Width is set from currentTime in JS. */
.wg-seg-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  display: block;
  background: var(--indigo-lift);
  border-radius: inherit;
}
.wg-seg.is-current { background: var(--brd-hover); }
.wg-seg.is-current .wg-seg-fill { background: var(--grad-hi); }

.wg-now {
  margin: 14px 0 0;
  font-size: 18px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
}
.wg-now[data-state="idle"] { font-weight: 500; color: var(--muted); }

/* Chapter titles on hover, BELOW the strip. Above meant covering the bottom of
   the picture, including the native controls, which is the one part of the
   frame you cannot afford to hide. Positioned in JS because the left offset
   depends on which segment you are over, and clamped there so a tooltip near
   either end stays inside the layout. */
.wg-chapters { position: relative; }
.wg-tip {
  position: absolute;
  /* Just under the rail, not under the whole block: tight to the strip you are
     pointing at. It covers the status line while you hover, which is fine,
     because the line and the tooltip are saying the same kind of thing. */
  top: 26px;
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  gap: 10px;
  align-items: baseline;
  width: max-content;
  max-width: min(440px, 92%);
  padding: 9px 13px;
  border-radius: 10px;
  border: 1px solid var(--brd);
  background: var(--bg);
  box-shadow: 0 14px 38px rgba(0, 0, 0, .3);
  color: var(--text);
  font-size: 14px;
  line-height: 1.35;
  pointer-events: none;
}
.wg-tip[hidden] { display: none; }
.wg-tip-t {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--indigo-lift);
  flex: 0 0 auto;
}

/* -----------------------------------------------------------------------------
   WHAT WE COVERED (.f-row[data-seek])

   The navigation for this page, so it is bigger at rest than a supporting list.

   THIS IS THE RESOURCES ROW RECIPE, COPIED. Do not improve it.

   The rows on /resources/ are the smoothest magnify on the site, and the
   difference turned out to be a single property: they do not animate a glow.
   A blurred shadow on text has to be repainted from scratch at every frame, at
   every new size, and no amount of layer promotion helps because the shadow is
   part of the paint. That repaint is what made the letters step through sizes
   instead of gliding. Removing it fixed the choppiness outright.

   So: same mono 800 weight at 20px, same --indigo-bright resting to
   --indigo-lift lit, same 1.85 on the number, same --motion-hover timing, and
   crucially the same short transition list of transform and colour only.

   The headings keep the purple and the slightly larger 1.10, which are this
   page's choices. Everything about HOW it moves comes from the resources rows.

   The "this section is playing" signal is a pulsing dot beside the timecode,
   because a dot can pulse forever without touching text paint at all.
   -------------------------------------------------------------------------- */
[data-webinar-jumps] .f-row { padding-top: 22px; padding-bottom: 22px; }
[data-webinar-jumps] .f-row.is-jump { cursor: pointer; }
[data-webinar-jumps] .f-row.is-jump:focus-visible {
  outline: 2px solid var(--indigo-lift);
  outline-offset: 6px;
  border-radius: 10px;
}

/* The number, matched to .res-n property for property. It looked skinny
   because it had no weight of its own and fell back to regular. */
[data-webinar-jumps] .f-num {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 800;
  color: var(--indigo-bright);
  padding-top: 0;
  /* Anchor the scale to the top of the DIGITS, not the top of the box.
     Every glyph sits some distance below its own line box, and that gap scales
     with everything else, so anchoring the box corner still walked the digits
     downward: measured at 4x, the ink dropped 5px while the box stayed put.
     0.325em is where the digit tops actually sit in this mono face, measured
     rather than guessed, so scaling now pivots on the ink itself.

     No vertical nudge on top of that. Matching the digit tops to the cap height
     mathematically made them read high, because round glyphs like 0 and 3
     overshoot a flat cap and have to sit a hair lower to look level. The resting
     position was always right. The only thing wrong was the drift on magnify,
     and the pivot alone fixes that. In em so it survives a font-size change. */
  transform-origin: left 0.325em;
  transition: transform var(--motion-hover), color .34s ease;
}
[data-webinar-jumps] .f-row.is-jump:hover .f-num,
[data-webinar-jumps] .f-row.is-active .f-num {
  transform: scale(1.85);
  color: var(--indigo-lift);
}

[data-webinar-jumps] .f-row .h4 {
  display: block;
  margin: 0;
  font-size: 21px;
  /* Same corner anchor as the number. If one grows from its middle and the
     other from its top they drift apart by a pixel or two at full size, which
     is small enough to look like a mistake rather than a choice. Anchored the
     same way they are locked together at every point in the movement. */
  transform-origin: left top;
  transition: transform var(--motion-hover), color .34s ease;
}
[data-webinar-jumps] .f-row.is-jump:hover .h4,
[data-webinar-jumps] .f-row.is-active .h4 {
  transform: scale(1.10);
  /* Theme purple, not white: light purple on dark, dark purple on light. */
  color: var(--indigo-lift);
}

[data-webinar-jumps] .f-row .small-t {
  font-size: 16px;
  margin-top: 8px;
  transform-origin: left center;
  transition: transform var(--motion-hover), color .34s ease;
}
[data-webinar-jumps] .f-row.is-jump:hover .small-t,
[data-webinar-jumps] .f-row.is-active .small-t {
  transform: scale(1.025);
  color: var(--muted);
}

.wg-jump-t {
  display: inline-block;
  margin-left: 10px;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 500;
  color: var(--dim);
  vertical-align: middle;
  transition: color .34s ease;
}
[data-webinar-jumps] .f-row.is-jump:hover .wg-jump-t,
[data-webinar-jumps] .f-row.is-active .wg-jump-t { color: var(--text); }

/* Playing now. The same dot as the event cards, and the only thing on this list
   that answers the video rather than the pointer: hovering a row never shows it,
   and it is absent before playback starts and after the recording ends.

   The dot is a CHILD of this wrapper, not the wrapper itself. .live-dot.anim
   animates its own opacity, so opacity set on it directly is ignored and every
   row showed a half-lit dot. Nested opacity multiplies, so the wrapper can hide
   it outright while the pulse carries on underneath. */
.wg-jump-live {
  display: inline-block;
  margin-left: 9px;
  vertical-align: middle;
  opacity: 0;
  transform: scale(.4);
  transition: opacity .55s ease, transform .55s var(--ease-reveal);
}
.wg-jump-live .live-dot { display: block; }
[data-webinar-jumps] .f-row.is-active .wg-jump-live { opacity: 1; transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  [data-webinar-jumps] .f-num,
  [data-webinar-jumps] .f-row .h4,
  [data-webinar-jumps] .f-row .small-t { transform: none !important; }
}

/* The recording light on the page's own date line. Same red pip as the event
   cards, sitting on the text baseline rather than floating above it: .live-dot
   is a block, so inline it needs to be told how to sit. */
.wg-rec-dot {
  display: inline-block;
  margin-right: 9px;
  vertical-align: middle;
  position: relative;
  top: -1px;
}


/* --- ./objects/article.css --- */
/* =============================================================================
   EDITORIAL ARTICLE - the global margin structure for long-form articles
   (Thought Leadership pieces). Reuse this object for every future article;
   do NOT restyle margins per page.
   -----------------------------------------------------------------------------
   Page skeleton (two sections share one centred 720px column):

     <section class="container section" data-screen-label="Article">
       <div class="tl-article">
         <a class="tl-back" href="…">← Thought Leadership</a>
         <div class="tl-article-date">June 2026 · Market Structure</div>
         <h1 class="h1 tl-article-title">Headline</h1>
         <div class="tl-byline"> <a class="author-chip">…</a> </div>
       </div>
     </section>
     <section class="container section is-article-body" data-rail="Article">
       <div class="tl-article">
         <p class="tl-lead">Standfirst…</p>
         <div class="tl-body"> <h2>…</h2> <p>…</p> </div>
       </div>
     </section>

   THE MARGIN CONTRACT (keep these as they are):
   - Article column: max-width 720px, centred (margin: 0 auto).
   - Header→body: the body section carries no top padding (.is-article-body),
     so the standfirst sits 34px under the byline (its own margin-top).
   - Body rhythm: h2 +46px above, paragraphs +18px, pull quotes 64px block
     margins, metrics rows 36px block margins.
   ========================================================================== */

.tl-article {
  max-width: 720px;
  margin: 0 auto;
}

/* The body section flows straight on from the article header - no section gap.
   (Overrides the global section rhythm at higher specificity, no !important.) */
.page-body > section + section.is-article-body { padding-top: 0; }

/* Mono date/topic kicker between the back link and the headline.
   .is-accent recolors it indigo (e.g. the live-webinar kicker). */
.tl-article-date {
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  margin-top: 26px;
}
/* Accent variant - indigo, and larger: it carries date + time on event pages. */
.tl-article-date.is-accent {
  color: var(--indigo-lift);
  font-size: 16px;
  font-weight: 600;
}
.tl-article-title {
  margin-top: 14px;
  font-size: clamp(34px, 4.6vw, 58px);
  line-height: 1.04;
  letter-spacing: -.035em;
}

/* "← Thought Leadership" return link - arrow nudges, label underlines. */
.tl-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--indigo-bright);
  text-decoration: none;
}
.tl-back svg { width: 17px; height: 17px; transition: transform .28s cubic-bezier(.5, 1.4, .5, 1); }
.tl-back:hover svg { transform: translateX(-5px); }
.tl-back span { position: relative; }
.tl-back span::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform .25s cubic-bezier(.5, .5, .2, 1);
}
.tl-back:hover span::after { transform: scaleX(1); transform-origin: left center; }

/* Byline strip under the headline. */
.tl-byline {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}

/* -----------------------------------------------------------------------------
   Author chip - avatar + name/role that links out and reveals a bio card on
   hover/focus. Reusable anywhere an author is credited.
   -------------------------------------------------------------------------- */
.author-chip {
  position: relative;
  z-index: 5;
  display: inline-flex;
  align-items: center;
  gap: 17px;
  text-decoration: none;
  transition: transform .3s cubic-bezier(.22, .61, .36, 1);
}
.author-chip:hover,
.author-chip:focus-visible {
  transform: translateY(-2px);
  outline: none;
  z-index: 60;
}
.author-ava {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  overflow: hidden;
  flex: 0 0 auto;
  background: #fff;
  box-shadow: 0 0 0 1px var(--brd-strong);
  transition: box-shadow .32s ease, transform .35s cubic-bezier(.34, 1.45, .5, 1);
}
.author-ava img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 29%;
  display: block;
}
.author-chip:hover .author-ava,
.author-chip:focus-visible .author-ava {
  box-shadow: 0 0 0 2px var(--indigo-bright), 0 8px 20px color-mix(in srgb, var(--indigo-bright) 34%, transparent);
  transform: scale(1.06);
}
.author-meta {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.author-chip .author-name {
  /* Family stated rather than inherited, and the weight dropped from 800 to
     the 700 both card bylines use. Inter does ship 800, so this was never a
     different face, only the one place on the site running two steps heavier
     than every other author name. */
  font-family: var(--font-sans);
  font-size: 20.5px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.25;
  text-decoration: underline transparent;
  text-underline-offset: 3px;
  text-decoration-thickness: 1.5px;
  transition: text-decoration-color .25s ease;
}
.author-chip:hover .author-name,
.author-chip:focus-visible .author-name { text-decoration-color: var(--indigo-bright); }
.author-role {
  font-family: var(--font-sans);
  font-size: 16px;
  color: var(--dim);
  line-height: 1.25;
  margin-top: 2px;
}
.author-bio {
  position: absolute;
  left: 0;
  bottom: calc(100% + 13px);
  top: auto;
  width: 360px;
  max-width: 82vw;
  background: var(--elev);
  border: 1px solid var(--brd-hover);
  border-radius: 14px;
  padding: 15px 18px 16px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--muted);
  box-shadow: var(--shadow);
  text-wrap: pretty;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transform-origin: left bottom;
  transition: opacity .26s ease, transform .3s cubic-bezier(.22, .61, .36, 1), visibility .26s;
  pointer-events: none;
  z-index: 40;
}
.author-bio::before {
  content: "About the author";
  display: block;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--indigo-bright);
  margin-bottom: 7px;
  font-weight: 500;
}
.author-chip:hover .author-bio,
.author-chip:focus-visible .author-bio {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* -----------------------------------------------------------------------------
   Article typography - standfirst, running copy, drop word, pull quote.
   -------------------------------------------------------------------------- */
.tl-lead {
  font-size: clamp(19px, 2vw, 22px);
  line-height: 1.55;
  color: var(--text);
  font-weight: 500;
  margin: 34px 0 0;
  letter-spacing: -.01em;
}
.tl-body { margin-top: 8px; }
.tl-body h2 {
  font-size: clamp(21px, 2.2vw, 27px);
  font-weight: 700;
  letter-spacing: -.015em;
  color: var(--text);
  margin: 46px 0 0;
}
.tl-body p {
  font-size: 17.5px;
  line-height: 1.78;
  color: var(--muted);
  margin: 18px 0 0;
}
.tl-body p:first-of-type { clear: left; }
.tl-body strong { color: var(--text); font-weight: 700; }
/* --indigo-lift, not --indigo: --indigo is a fill colour with no dark pair and
   renders at 2.94:1 on the dark page. See the note in foundation/tokens.css. */
.tl-body strong.accent { color: var(--indigo-lift); }

/* Oversized opening word floated into the first paragraph. */
.tl-dropword {
  float: left;
  font-size: 3.05em;
  font-weight: 800;
  line-height: .8;
  padding: 8px 16px 2px 0;
  margin-top: 4px;
  color: var(--indigo-lift);
  letter-spacing: -.02em;
}

/* Centred pull quote with the indigo bar; magnifies as it scrolls through
   the viewport on browsers that support scroll-driven animations. */
.tl-body p.tl-pull {
  position: relative;
  margin: 64px auto;
  padding: 0 8px;
  max-width: 680px;
  border: 0;
  text-align: center;
  text-wrap: balance;
  font-size: clamp(26px, 3.4vw, 40px);
  line-height: 1.28;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -.022em;
  transform-origin: center center;
}
.tl-body p.tl-pull::before {
  content: "";
  display: block;
  position: static;
  width: 48px;
  height: 3px;
  border-radius: 3px;
  margin: 0 auto 26px;
  background: var(--indigo-bright);
  box-shadow: 0 0 14px var(--indigo-bright);
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .tl-body p.tl-pull {
      animation: pullMagnify linear both;
      animation-timeline: view();
      animation-range: cover 12% cover 88%;
    }
  }
}
@keyframes pullMagnify {
  0% { opacity: .32; transform: scale(.9); }
  50% { opacity: 1; transform: scale(1.05); }
  100% { opacity: .32; transform: scale(.9); }
}

/* -----------------------------------------------------------------------------
   In-article metric rows - stat + description pairs with the hover bar.
   -------------------------------------------------------------------------- */
.tl-metrics {
  margin: 36px 0;
  border-top: 1px solid var(--line);
}
.tl-metric {
  position: relative;
  display: grid;
  grid-template-columns: minmax(150px, 200px) 1fr;
  gap: 28px;
  align-items: center;
  padding: 24px 4px 24px 16px;
  border-bottom: 1px solid var(--line);
  transition: padding-left .32s cubic-bezier(.22, .61, .36, 1);
}
.tl-metric::before {
  content: "";
  position: absolute;
  left: 0;
  top: 20px;
  bottom: 20px;
  width: 2px;
  border-radius: 2px;
  background: var(--indigo-bright);
  box-shadow: 0 0 12px var(--indigo-bright);
  transform: scaleY(0);
  transform-origin: center;
  opacity: 0;
  transition: transform .36s cubic-bezier(.22, .61, .36, 1), opacity .28s ease;
}
.tl-metric:hover::before { transform: scaleY(1); opacity: 1; }
.tl-metric .stat-num {
  margin: 0;
  transform-origin: left center;
  will-change: transform;
  transition: transform .4s cubic-bezier(.22, .61, .36, 1);
}
.tl-metric:hover .stat-num { transform: translateX(8px) scale(1.1); }
.tl-metric .stat-num .u { color: var(--indigo-lift); margin-left: -.05em; }
/* Unit gap correction. The default -.05em is tuned for wide-bearing digits
   like "1" (12.1M reads with a clear ~8px ink gap). "4" and "5" carry almost
   no right bearing, so % and B need positive margins to land the SAME visual
   gap (values measured from glyph ink at 800/46px). */
.tl-metric .stat-num .u.is-pct { margin-left: .12em; }
.tl-metric .stat-num .u.is-b { margin-left: .08em; }
.tl-metric:hover .stat-num .u { animation: uShimmer .6s ease-out 1; }
@keyframes uShimmer {
  0%, 100% { color: var(--indigo-lift); text-shadow: none; }
  42% { color: var(--grad-hi); text-shadow: 0 0 13px color-mix(in srgb, var(--indigo-lift) 75%, transparent); }
}
.tl-metric .d {
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--muted);
  margin: 0;
  transform-origin: left center;
  will-change: transform;
  transition: color .3s ease, transform .38s cubic-bezier(.22, .61, .36, 1);
}
.tl-metric:hover .d { color: var(--text); transform: translateX(8px) scale(1.03); }
@media (max-width: 600px) {
  .tl-metric { grid-template-columns: 1fr; gap: 8px; padding: 22px 4px; }
}

/* End-of-article CTA sits 48px under the last paragraph. */
.tl-article .cta-shine { margin-top: 48px; }

/* -----------------------------------------------------------------------------
   AUTHOR AVATAR (.ava)
   One framing for every headshot, everywhere. The source portraits are 640x1138
   and the chosen circle is 790px across, centred at 320, 464. That circle is
   WIDER than the image, so the photo cannot fill it: 640/790 is 81.01% of the
   circle, leaving a sliver either side. That sliver is white on purpose, so the
   cut-out reads as the subject on a card rather than as a crop that ran out.

   Every number below is that one circle expressed against the box:
     width  640 / 790 = 81.01%
     height 1138 / 790 = 144.05%   (set by the width, so it is not declared)
     left   0.5 - 320/790 = 9.49%
     top    0.5 - 464/790 = -8.73%
   Change the circle and change these four together, nothing else.
   -------------------------------------------------------------------------- */
.ava {
  position: relative;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 0 0 1px var(--brd);
}
.ava img {
  position: absolute;
  left: 9.49%;
  top: -8.73%;
  width: 81.01%;
  height: auto;
  display: block;
}
/* Sizes are named for the slot, not a pixel value, so they can be tuned without
   the class turning into a lie. */
.ava.is-card    { width: 60px; height: 60px; }   /* blog cards */
.ava.is-feature { width: 72px; height: 72px; }   /* homepage featured card */

/* The article byline already had its own wrapper, so it only needs the framing. */
.author-ava img {
  position: absolute;
  left: 9.49%;
  top: -8.73%;
  width: 81.01%;
  height: auto;
  object-fit: unset;
  object-position: unset;
}
.author-ava { position: relative; }

/* The name and role sit in a two-line block beside a circle. align-items:center
   on the row centres the block, but only if the block's own height is the sum
   of two predictable lines, which is what the line-heights above pin down. The
   flex rows are restated here so a future change to one does not quietly drop
   the centring on another. */
.tl-byline,
.tl-feat-author,
.byrow { align-items: center; }
.author-meta,
.tl-feat-author > div,
.byrow > div { display: flex; flex-direction: column; justify-content: center; }


/* --- ./pages/article-ai-post-trade.css --- */
/* =============================================================================
   ARTICLE FIGURES - "How AI Is Changing Post-Trade Operations for the Better"
   -----------------------------------------------------------------------------
   Page-scoped feature visuals. Everything is composed from foundation/tokens.css.

   ONE RULE ACROSS EVERY FIGURE:
   all of the content is readable at rest, and the motion plays ONCE when the
   figure first enters the viewport. Nothing is hidden behind a hover. The
   trigger is the `is-lit` class, added by article-ai-post-trade.js on first
   intersection and never removed, so a figure stays in its finished state for
   the rest of the visit.

   Devices, in reading order, none repeated:
     1. .five     the five questions magnify in sequence and stay magnified
     2. .feeds    six sources slide in off the edges into one record, one at a time
     3. .stl      settlement checks change state as a playhead sweeps the axis
     4. .ask      question types, answer resolves out of a running cypher
     5. .markfig  the mark traces itself slowly and fills in brand purple
     6. .gov      controls write themselves out, get their mark, then roll

   No rules between items anywhere: spacing does the separating.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   Shared plumbing
   -------------------------------------------------------------------------- */
.tl-body .fig { margin: 44px 0; padding: 0; }

/* Break out of the 720px article column for the wide instruments. The max()
   stops the breakout ever coming out NARROWER than the column itself, which it
   did at the middle widths where the page gutter is at its widest. */
.tl-body .fig-wide {
  --wide: max(100%, min(1060px, calc(100vw - 2 * var(--gutter))));
  width: var(--wide);
  margin-left: 50%;
  transform: translateX(-50%);
}

.tl-body .fig ul,
.tl-body .fig ol { list-style: none; margin: 0; padding: 0; }

/* Snap a figure back to its rest state with no motion at all. Used for one
   frame by SSFig.replay so a replay starts from zero rather than from wherever
   the previous run had got to. */
.ss-noanim,
.ss-noanim *,
.ss-noanim *::before,
.ss-noanim *::after {
  transition: none !important;
  animation: none !important;
}


/* =============================================================================
   1 · .five - the five questions
   At rest all five are on the page, small and dim. On view they magnify one
   after another, top to bottom, and stay magnified.
   The list is a block centred on the column, but the lines share one left edge
   and the numbers sit in their own gutter: centring each line individually made
   the stack read ragged. Growth is from the left edge for the same reason.
   ========================================================================== */
.five { }
.five-list {
  display: grid;
  gap: 22px;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
  padding: 16px 0 20px;
}
.five-q {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 16px;
  align-items: baseline;
  font-size: clamp(20px, 2.5vw, 29px);
  font-weight: 600;
  line-height: 1.28;
  letter-spacing: -.02em;
  color: var(--dim);
  transform: scale(.78);
  transform-origin: left center;
  opacity: .28;
  /* One long, single-direction ease. The earlier spring overshoot is what made
     the cascade feel jumpy rather than played. */
  transition:
    transform 1.55s var(--ease-reveal),
    opacity   1.05s cubic-bezier(.3, .7, .3, 1),
    color     1.05s ease;
  transition-delay: calc(var(--i) * .3s);
  will-change: transform, opacity;
}
.five.is-lit .five-q { transform: scale(1); opacity: 1; color: var(--text); }

/* Hover only makes sense once the cascade has finished. `is-settled` (added by
   the script when the last line lands) drops the stagger delay, otherwise a
   hover on line five would wait most of a second before answering. */
/* The site's hover magnify, not one of my own: --window-hover-transform is
   scale(1.025) and --motion-hover is .95s of --ease-reveal. Every magnify on
   this page uses those two so the article behaves like the rest of the site. */
.five.is-settled .five-q {
  transition: transform var(--motion-hover), color .45s ease;
  transition-delay: 0s;
  cursor: default;
}
.five.is-settled .five-q:hover { transform: var(--window-hover-transform); }
.five.is-settled .five-q:hover .five-n { color: var(--grad-hi); }

/* No rule under each question: the magnification alone carries the beat. */

.five-n {
  font-family: var(--font-mono);
  font-size: .78em;
  font-weight: 600;
  letter-spacing: .16em;
  color: var(--dim);
  transition: color .95s ease;
  transition-delay: calc(var(--i) * .27s + .16s);
}
.five.is-lit .five-n { color: var(--indigo-lift); }
.five-t { text-wrap: pretty; }

@media (max-width: 620px) {
  .five-list { gap: 17px; width: auto; }
  .five-q { gap: 11px; }
}


/* =============================================================================
   2 · .puzzle - the shape in the middle
   Eight sources arrive from beyond the edges and interlock. Four of them meet
   at the centre of the board, and the hole their inner edges leave between them
   is the mark. Nothing is added to finish the record: the record is finished by
   the shape the pieces make. The outline then draws in purple, the board locks
   gold, and a soft bloom comes out of the hole.

   The hole is a mask over the whole board rather than eight hand-cut pieces:
   exact, and it survives any change to the grid. The gold is the system's
   --warn pair; there is no gold token, and a literal hex here would be the only
   hard-coded colour on the page.
   ========================================================================== */
.puzzle {
  --beat: .5s;
  --seat: 4.6s;      /* 7 * beat + the last piece's travel */
  --lock: 5s;
  --logo: 5.7s;      /* the mark arrives once the board has gone gold */
}

/* Centred over the board, which is itself centred in the column. */
.pz-head {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 14px;
  padding-bottom: 14px;
}
.pz-head-k {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .22em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--dim);
  transition: color 1.1s ease;
  transition-delay: var(--lock);
}
.puzzle.is-lit .pz-head-k { color: var(--warn); }
.pz-head-id {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--text);
}

.pz-stage {
  position: relative;
  overflow: hidden;          /* this is what puts the pieces off screen */
}
.pz-svg { display: block; width: 100%; height: auto; }

/* ---- the eight pieces --------------------------------------------------- */
.pz-piece {
  transform: translate(var(--tx), var(--ty)) rotate(var(--rot));
  transform-origin: 470px 370px;
  opacity: 0;
  will-change: transform, opacity;
  transition:
    transform 1.3s var(--ease-reveal),
    opacity    .5s ease;
  transition-delay: calc(var(--o) * var(--beat));
}
.puzzle.is-lit .pz-piece { transform: translate(0px, 0px) rotate(0deg); opacity: 1; }


/* Two paths per piece. The base is the panel and never changes; the gold is a
   translucent wash laid over it. Tinting the panel itself with --warn-bg turned
   the white pieces into flat beige, because --warn-bg is an alpha colour and it
   was replacing the white rather than sitting on it. */
.pz-base {
  fill: var(--panel-2);
  fill-rule: evenodd;
}
.pz-shape {
  fill: transparent;
  fill-rule: evenodd;
  stroke: var(--brd-strong);
  stroke-width: 1.2;
  vector-effect: non-scaling-stroke;
  transition: fill 1.2s ease, stroke 1.2s ease;
  transition-delay: var(--lock);
}
.puzzle.is-lit .pz-shape { fill: var(--warn-bg); stroke: var(--warn); }
/* The mark, arriving in the window the cutter left. The board is cut with the
   silhouette, counter and all, so nothing is standing inside the shape for
   this to fight with. It is the only brand purple on the figure, and it lands
   after the board has locked, so the sequence reads: pieces, record, mark. */
.pz-logo {
  fill: var(--indigo-bright);
  opacity: 0;
  transform-origin: 470px 370px;
}
.puzzle.is-lit .pz-logo {
  animation: pzLogo 1.9s var(--ease-reveal) both;
  animation-delay: var(--logo);
}
@keyframes pzLogo {
  from { opacity: 0; transform: scale(.975); }
  to   { opacity: 1; transform: scale(1); }
}

.pz-t1, .pz-t2 {
  text-anchor: middle;
  font-family: var(--font-sans);
  fill: var(--muted);
  transition: fill 1.2s ease;
  transition-delay: var(--lock);
}
/* The board is no longer stretched across the wide measure, so a viewBox unit
   is close to a CSS pixel and the labels can simply be set at a readable size
   instead of being scaled down to nothing. */
.pz-t1 { font-size: 37px; font-weight: 700; letter-spacing: -.015em; }
.pz-t2 { font-size: 31px; font-weight: 500; }
.puzzle.is-lit .pz-t1 { fill: var(--text); }

/* Nothing sits in the middle: the cutter took it. What you see through the
   shape is the page, and the line around it is the border of whichever pieces
   the cutter bit into. */


/* =============================================================================
   3 · .stl - settlement checks, caught before settlement
   A horizontal timeline. The axis runs trade date to settlement, ticks carry
   the sense of time passing, and a one pixel playhead sweeps across them. Each
   row is one check; it changes state when the playhead reaches that position.

   STATE MODEL, and nothing outside it
     grey    unverified     the check has not completed yet
     amber   fail risk      predictive, this may fail
     red     expected fail  concrete, this will fail unless someone acts
     purple  verified       fixed and confirmed

   A segment takes the colour of the state that STARTED it, so the line after a
   red dot stays red until the next dot lands. Every class here is prefixed:
   the panel uses names like row, label, chip and dot, all of which already mean
   something else on this site.
   ========================================================================== */
.stl {
  --stl-rule: var(--hair, rgba(94, 65, 238, .10));
  --stl-tickh: 16px;
  --stl-tick: #b8b3d2;
  --stl-tick-major: #8d86b5;
  --stl-tick-rule: rgba(94, 65, 238, .12);
  --stl-axis: var(--muted);
  --stl-grey-txt: var(--muted);
  --stl-grey-bg: rgba(124, 120, 137, .13);
  --stl-amber: #e0921a;
  --stl-amber-txt: #8a5a05;
  --stl-amber-bg: rgba(224, 146, 26, .15);
  --stl-red: #e0455f;
  --stl-red-txt: #b02439;
  --stl-red-bg: rgba(224, 69, 95, .13);
  --stl-purple: #5e41ee;
  --stl-purple-dot: #6b53f0;
  --stl-purple-txt: #4630c4;
  --stl-purple-bg: rgba(94, 65, 238, .11);
  /* Settlement reached. The only place green is used, and it means done. */
  --stl-green: #12a878;
  --stl-green-txt: #0a7550;
  --stl-green-bg: rgba(18, 168, 120, .14);
  --stl-track: rgba(94, 65, 238, .20);
}
/* The signal colours are tuned for the light page. On the dark page the same
   hues sit far too close to the background, the purple worst of all, so every
   one of them is lifted here. The meanings do not change, only the values. */
[data-theme="dark"] .stl {
  --stl-rule: rgba(255, 255, 255, .09);
  --stl-tick: #6d6890;
  --stl-tick-major: #8f89b5;
  --stl-tick-rule: rgba(255, 255, 255, .13);

  --stl-amber: #f2ac3f;
  --stl-amber-txt: #f5c377;
  --stl-amber-bg: rgba(242, 172, 63, .16);

  --stl-red: #ff667c;
  --stl-red-txt: #ff93a3;
  --stl-red-bg: rgba(255, 102, 124, .16);

  --stl-purple: #9179ff;
  --stl-purple-dot: #a692ff;
  --stl-purple-txt: #bcaeff;
  --stl-purple-bg: rgba(145, 121, 255, .18);
  --stl-track: rgba(145, 121, 255, .24);

  --stl-green: #2fd7a0;
  --stl-green-txt: #64e3ba;
  --stl-green-bg: rgba(47, 215, 160, .17);
}

/* No surface and no column field: the timeline sits on the page like every
   other figure in this article, so it follows the theme instead of fighting it. */
.stl-panel {
  position: relative;
  width: 100%;
  padding: 2px 0 0;
  color: var(--text);
}
.stl-axis {
  position: relative;
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--stl-axis);
  margin-bottom: 9px;
}
/* Grey until the sweep actually gets there. It is a destination, not a
   result, so it has no business being green from the first frame. */
.stl-end { color: var(--stl-axis); transition: color .5s ease; }
.stl-end.is-settled { color: var(--stl-green); }
.stl-end.is-settled { animation: stlSettle 1.6s cubic-bezier(.2, .8, .3, 1) both; }
@keyframes stlSettle {
  0%   { text-shadow: none; letter-spacing: .18em; opacity: .85; }
  35%  { text-shadow: 0 0 14px rgba(14, 156, 110, .55); letter-spacing: .24em; opacity: 1; }
  100% { text-shadow: 0 0 0 rgba(14, 156, 110, 0); letter-spacing: .18em; opacity: 1; }
}
/* Ticks are a scale, not an effect. They sit still on a hairline; the playhead
   is the only thing that moves across them. A taller mark every fifth gives
   the eye something to count. */
.stl-ticks {
  position: relative;
  height: var(--stl-tickh);
  margin-bottom: 20px;
  border-bottom: 1px solid var(--stl-tick-rule);
}
/* Readable standing still, not only under the lens: every tick is a real mark
   at rest and every fifth is heavier and full height, so the scale can be
   counted without waiting for the sweep. */
.stl-ticks i {
  position: absolute;
  bottom: 0;
  width: 1px;
  height: 10px;
  background: var(--stl-tick);
  transform-origin: bottom center;
  transform: scaleY(.62);
  opacity: .62;
  will-change: transform, opacity;
}
.stl-ticks i.is-major {
  width: 2px;
  height: var(--stl-tickh);
  background: var(--stl-tick-major);
  opacity: .85;
}

/* The playhead fills this box, so it spans the ticks to the last line by
   construction. It used to be measured and set in pixels, which drifted the
   moment anything above it reflowed. It starts on the line the ticks stand on
   rather than cutting through them, and bottom 12px is the last row's 8px of
   padding plus the 4px under its 2px line. */
.stl-body { position: relative; }
.stl-rows { position: relative; transition: opacity .42s ease; }
/* The last half second of the hold, so a cycle ends by fading out rather
   than by everything vanishing on one frame. */
.stl-rows.is-cycling { opacity: 0; }
.stl-row {
  position: relative;
  padding: 0 0 20px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--stl-rule);
}
.stl-row:last-child { border-bottom: 0; margin-bottom: 0; padding-bottom: 8px; }
.stl-label {
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: -.01em;
  line-height: 1.25;
  margin-bottom: 9px;
  color: var(--text);
}
/* One status line, held in place. Fades out, swaps, fades back in, so there is
   never a frame with two states on the same row. */
.stl-status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  min-height: 19px;
  margin-bottom: 15px;
  opacity: 1;
  transition: opacity .22s ease;
}
.stl-status.is-swapping { opacity: 0; }
.stl-chip {
  display: inline-block;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.35;
  padding: 3px 7px;
  border-radius: 3px;
  white-space: nowrap;
}
.stl-chip.is-grey   { color: var(--stl-grey-txt);   background: var(--stl-grey-bg); }
.stl-chip.is-amber  { color: var(--stl-amber-txt);  background: var(--stl-amber-bg); }
.stl-chip.is-red    { color: var(--stl-red-txt);    background: var(--stl-red-bg); }
.stl-chip.is-purple { color: var(--stl-purple-txt); background: var(--stl-purple-bg); }
.stl-chip.is-green  { color: var(--stl-green-txt);  background: var(--stl-green-bg); }
.stl-cause { font-size: 15.5px; line-height: 1.5; }
.stl-cause.is-grey   { color: var(--stl-grey-txt); }
.stl-cause.is-amber  { color: var(--stl-amber-txt); }
.stl-cause.is-red    { color: var(--stl-red-txt); }
.stl-cause.is-purple { color: var(--stl-purple-txt); }
.stl-cause.is-green  { color: var(--stl-green-txt); }

.stl-track { position: relative; height: 10px; }
.stl-base {
  position: absolute;
  left: 0; right: 0; top: 4px;
  height: 2px;
  background: var(--stl-track);
  border-radius: 2px;
}
.stl-seg {
  position: absolute;
  top: 4px;
  height: 2px;
  border-radius: 2px;
  transition: background-color .6s cubic-bezier(.22, .78, .3, 1);
}
.stl-seg.is-amber  { background: var(--stl-amber); }
.stl-seg.is-red    { background: var(--stl-red); }
.stl-seg.is-purple { background: var(--stl-purple); }
.stl-dot {
  position: absolute;
  top: 5px;
  width: 9px; height: 9px;
  margin-left: -4.5px; margin-top: -4.5px;
  border-radius: 50%;
  background: currentColor;
  animation: stlPop .5s cubic-bezier(.2, .9, .25, 1.35) both;
  transition: color .6s cubic-bezier(.22, .78, .3, 1);
}
.stl-dot.is-amber  { color: var(--stl-amber); }
.stl-dot.is-red    { color: var(--stl-red); }
.stl-dot.is-purple { color: var(--stl-purple-dot); }
.stl-dot.is-green  { color: var(--stl-green); }
@keyframes stlPop { from { transform: scale(.2); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.stl-dot::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: currentColor;
  opacity: .15;
}
.stl-dot.is-live::after { animation: stlRing 2.1s cubic-bezier(.25, .6, .35, 1) infinite; }
@keyframes stlRing {
  0%   { transform: scale(.75); opacity: .32; }
  65%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}
/* Present from the first frame. It only collapses once settlement is reached. */
.stl-head {
  position: absolute;
  top: var(--stl-tickh);
  bottom: 12px;
  /* Same weight as a major tick, and it starts ON the rule the ticks stand on
     rather than one pixel under it, so the two read as one continuous mark. */
  width: 2px;
  background: color-mix(in srgb, var(--text) 26%, transparent);
  pointer-events: none;
  transform-origin: center;
  transition: transform .95s cubic-bezier(.4, 0, .2, 1), opacity .95s ease;
}
.stl-head.is-collapsed { transform: scaleY(0); opacity: 0; }
/* No instant reset any more: coming out of is-collapsed runs the same
   transition backwards, so the line grows from its middle back to full
   height instead of snapping in. */

@media (max-width: 760px) {
  .stl-axis { font-size: 10px; }
  .stl-label { font-size: 15px; }
  .stl-cause { font-size: 13.5px; }
}


/* =============================================================================
   4 · .ask - the plain-English console
   The question types. The answer is not boxed: it resolves out of character
   noise, left to right, behind a travelling scan line, then sits at full
   reading contrast.
   ========================================================================== */
.ask {
  border: 1px solid var(--brd);
  border-radius: var(--radius-lg);
  background: var(--elev);
  overflow: hidden;
  box-shadow: var(--shadow);
}
.ask-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 18px;
  border-bottom: 1px solid var(--line);
}
.ask-k {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--indigo-lift);
  font-weight: 600;
}
.ask-dots { display: inline-flex; gap: 5px; }
.ask-dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--brd-strong); }
.ask-state {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Fixed geometry, sized to the longest line each slot ever holds. The question
   and the answer both change length every cycle, so the boxes reserve exactly
   what they need: the window must neither breathe nor carry dead space. */
/* The question slot is two lines tall whether or not this question needs two.
   At narrow widths several of them wrap, and a one-line slot let the wrapped
   second line run straight through the rule below it. */
.ask-body { padding: 22px 22px 20px; height: 178px; }
.ask-line { display: flex; align-items: baseline; gap: 10px; height: 58px; }
.ask-caret { font-family: var(--font-mono); font-size: 17px; color: var(--indigo-lift); line-height: 1; }
.ask-q {
  font-size: 18px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--text);
  letter-spacing: -.01em;
}
.ask-cursor {
  display: inline-block;
  width: 9px; height: 18px;
  transform: translateY(2px);
  background: var(--indigo-bright);
  animation: askBlink 1s steps(1) infinite;
}
@keyframes askBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* The answer region. A rule wipes open, a scan line crosses once, and the
   characters lock in behind it. No box, no tinted panel. */
.ask-out { position: relative; margin-top: 6px; padding-top: 16px; height: 72px; }
.ask-rule {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: color-mix(in srgb, var(--indigo-bright) 45%, transparent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .5s var(--ease-out);
}
.ask-out.is-open .ask-rule { transform: scaleX(1); }
/* Centre the mark against the whole answer, not its first line, so it stays
   put whether the answer wraps to one line or three. */
.ask-a { display: flex; gap: 11px; align-items: center; }
/* The mark stands in for a bullet, and only appears once there is an answer. */
.ask-arrow {
  flex: 0 0 auto;
  width: 15px;
  /* No nudge. .ask-a centres it, so it lands right on one line or three;
     the old translateY was a leftover from when this row was baseline-aligned. */
  opacity: 0;
  transition: opacity .3s ease;
}
.ask-arrow .ask-mk { display: block; width: 100%; height: auto; }
.ask-arrow .ask-mk path { fill: var(--indigo-bright); }
.ask-out.is-open .ask-arrow { opacity: 1; }
.ask-a-t {
  font-size: 16px;
  line-height: 1.65;
  color: var(--text);
  font-weight: 500;
  letter-spacing: -.005em;
  text-wrap: pretty;
}
/* Characters still resolving read as noise: mono, dim, no weight. */
.ask-a-t .n {
  font-family: var(--font-mono);
  font-weight: 400;
  color: var(--indigo-lift);
  opacity: .55;
}


/* =============================================================================
   5 · .markfig - the mark, drawn
   Starts empty. The first line types itself while the mark traces, then that
   line goes as the mark fills in brand purple, and the line that actually
   matters arrives underneath it, larger. No numbers: there are none worth
   claiming for this section.
   ========================================================================== */
.mk-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 22px 0 26px;
  text-align: center;
}

/* Line one. Typed by the script, then dismissed. */
.mk-top {
  min-height: 1.5em;
  font-family: var(--font-mono);
  font-size: 13.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  transition: opacity 2.3s var(--ease-reveal), transform 2.3s var(--ease-reveal);
  transition-delay: var(--after, 2.4s);
}
/* Dimmed, not dismissed: it is still the first half of the sentence. */
.markfig.is-lit .mk-top { opacity: .38; transform: translateY(-4px); }

.mk-mark { position: relative; display: block; width: clamp(84px, 10vw, 108px); }
.mk-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* The trace. pathLength="1" normalises both blades so one dash rule draws
   either of them regardless of their real length, and both are always at the
   same fraction, so they draw together. */
.mk-t {
  fill: none;
  stroke: var(--indigo-bright);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
}
/* No CSS animation on the trace: a second clock is exactly what let it drift.
   The script writes stroke-dashoffset every frame from the same progress value
   that drives the typing, so the two cannot separate. The stroke runs on the
   continuous value and the text on the same value rounded to whole characters,
   which is what keeps the line smooth while the text still ticks over one
   letter at a time. */

/* The fill arrives behind the finished outline, in the brand purple. */
.mk-f {
  fill: var(--indigo-bright);
  opacity: 0;
  transform-origin: 91px 95px;
}
.markfig.is-lit .mk-f {
  animation: mkFill 2.3s var(--ease-reveal) both;
  animation-delay: var(--after, 2.4s);
}
@keyframes mkFill {
  from { opacity: 0; transform: scale(.965); }
  to   { opacity: 1; transform: scale(1); }
}

.mk-glow {
  position: absolute;
  inset: -36%;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--indigo-bright) 34%, transparent), transparent 68%);
  opacity: 0;
}
.markfig.is-lit .mk-glow { animation: mkBloom 3s ease-out var(--after, 2.4s) both; }
@keyframes mkBloom {
  0%   { opacity: 0;   transform: scale(.6); }
  35%  { opacity: 1;   transform: scale(1.05); }
  100% { opacity: .3;  transform: scale(1); }
}

/* Line two. The one worth reading, so it is the one that is set large. */
.mk-btm {
  font-size: clamp(22px, 2.8vw, 31px);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.025em;
  color: var(--text);
  text-wrap: balance;
  opacity: 0;
  transform: translateY(10px);
  /* Same delay, same duration, same easing as the fill above. They are one
     event and they have to be described identically or they drift apart. */
  transition: opacity 2.3s var(--ease-reveal), transform 2.3s var(--ease-reveal);
  transition-delay: var(--after, 2.4s);
}
.markfig.is-lit .mk-btm { opacity: 1; transform: none; }


/* =============================================================================
   6 · .gov - the control ledger
   Line and note write themselves out together, slowly. When both finish the row
   pulses, and only then does its mark get drawn. When the last one lands the
   ledger ripples top to bottom in one smooth pass and every row ends magnified
   and lit. The marks carry no box: mark, line, rule, nothing else.
   ========================================================================== */
.gov-row {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 16px;
  will-change: transform;
  /* Centred, so the mark sits on the optical middle of the line and its note. */
  align-items: center;
  padding: 13px 2px;
  transform-origin: left center;
}

.gov-check { display: flex; align-items: center; justify-content: center; }
.gov-check svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: var(--indigo-bright);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}
.gov-check path {
  stroke-dasharray: 26;
  stroke-dashoffset: 26;
  transition: stroke-dashoffset .75s cubic-bezier(.3, .8, .3, 1);
}
.gov-row.is-done .gov-check path { stroke-dashoffset: 0; }
.gov-row.is-done .gov-check svg { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--indigo-bright) 65%, transparent)); }

.gov-txt { display: block; min-height: 52px; }
.gov-name {
  display: block;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--muted);
  transition: color .5s ease;
}
.gov-note {
  display: block;
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: .04em;
  line-height: 1.5;
  color: var(--dim);
  transition: color .5s ease;
}
/* Characters still resolving read as noise, exactly as they do in the console. */
.gov-name .n, .gov-note .n {
  font-family: var(--font-mono);
  font-weight: 400;
  color: var(--indigo-lift);
  opacity: .55;
}

/* The beat every row lands on once the cypher clears. */
.gov-row.is-pulse { animation: govPulse .72s cubic-bezier(.37, 0, .28, 1) 1; }
@keyframes govPulse {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.04); }
  100% { transform: scale(1); }
}

/* All systems go: one smooth pass down the ledger that ENDS magnified. */
.gov-ledger.is-roll .gov-row {
  animation: govRoll 1.45s cubic-bezier(.37, 0, .28, 1) both;
  animation-delay: calc(var(--i) * .17s);
}
/* The one deliberate exception to the hover-magnify rule on this page: this is
   a ripple, not a hover, so it rises past the resting scale and comes back to
   it rather than stopping there. Symmetric ease in and out, no overshoot. */
@keyframes govRoll {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.05); }
  100% { transform: scale(1); }
}
.gov-ledger.is-roll .gov-check svg {
  animation: govFlash 1.45s ease-out both;
  animation-delay: calc(var(--i) * .17s);
}
@keyframes govFlash {
  0%, 100% { filter: drop-shadow(0 0 7px color-mix(in srgb, var(--indigo-bright) 65%, transparent)); }
  45%      { filter: drop-shadow(0 0 13px var(--indigo-bright)) brightness(1.2); }
}

/* Settled: a rail draws the height of the ledger. */
.gov { position: relative; }
.gov-rail { display: none; }
.gov-rail-unused {
  position: absolute;
  left: -16px;
  top: 4px; bottom: 4px;
  width: 1px;
  background: linear-gradient(180deg, var(--indigo-bright), color-mix(in srgb, var(--indigo-bright) 8%, transparent));
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 1.25s var(--ease-reveal);
}
.gov.is-set .gov-rail-unused { transform: scaleY(1); }


.gov-ledger.is-set .gov-name { color: var(--text); }
/* The sub line takes its purple on the first frame of the ripple, so the
   colour arrives with the movement rather than after it. */
.gov-ledger.is-set .gov-note,
.gov-ledger.is-roll .gov-note { color: var(--indigo-lift); }
.gov-note { transition: color .45s var(--ease-reveal); }
.gov-ledger.is-roll .gov-note { transition-delay: calc(var(--i) * .17s); }


/* =============================================================================
   The mid-article quote
   The homepage featured-card quote: the same .fi-mark and .fi-pull objects out
   of components/home.css, with the accent span on the payoff clause. It is set
   larger here because it is the only quote on the page rather than one panel of
   a card. It magnifies ONCE as it comes into view and stays there, and the
   accent is lit from the moment it arrives. Nothing about it responds to the
   pointer.
   ========================================================================== */
.tl-body .q-feat {
  margin: 74px auto;
  max-width: 700px;
  padding: 8px 4px;
  text-align: center;
  transform: scale(.93);
  transform-origin: center center;
  opacity: .55;
  will-change: transform, opacity;
  transition:
    transform 1.4s var(--ease-reveal),
    opacity   1.1s ease;
}
.tl-body .q-feat.is-lit { transform: scale(1); opacity: 1; }

.tl-body .q-feat .fi-mark { line-height: .8; opacity: .95; text-shadow: 0 0 18px rgba(129, 120, 255, .55); }
.tl-body .q-feat .fi-pull {
  margin-top: 8px;
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.28;
  letter-spacing: -.022em;
  text-wrap: balance;
}
.tl-body .q-feat .fi-pull span { color: var(--grad-hi); }


/* =============================================================================
   Closing statement
   Drawn corner brackets, left aligned, signed. Draws once on view.
   ========================================================================== */
/* The site's own rule puts 48px under the body and the closing block sits on
   66px above it, so the page ended lopsided. Both are 66px now. */
.tl-article .cta-shine { margin-top: 104px; }

.tl-body .close-note {
  position: relative;
  margin: 66px 0 0;
  padding: 40px clamp(22px, 4vw, 44px);
}
.cn-br {
  position: absolute;
  width: 0; height: 0;
  border: 0 solid var(--indigo-bright);
  opacity: 0;
  transition: width .85s var(--ease-reveal), height .85s var(--ease-reveal), opacity .45s ease;
}
.close-note.is-lit .cn-br { width: 34px; height: 34px; opacity: 1; }
.cn-br.is-tl { top: 0; left: 0; border-top-width: 1.5px; border-left-width: 1.5px; }
.cn-br.is-tr { top: 0; right: 0; border-top-width: 1.5px; border-right-width: 1.5px; transition-delay: .12s; }
.cn-br.is-bl { bottom: 0; left: 0; border-bottom-width: 1.5px; border-left-width: 1.5px; transition-delay: .24s; }
.cn-br.is-br { bottom: 0; right: 0; border-bottom-width: 1.5px; border-right-width: 1.5px; transition-delay: .36s; }

.tl-body .cn-q {
  margin: 0;
  font-size: clamp(21px, 2.6vw, 29px);
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--text);
  text-wrap: pretty;
}
.tl-body .cn-sig {
  margin: 26px 0 0;
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Name on its own line, role and company underneath it. */
.tl-body .cn-sig span {
  display: block;
  font-size: 21px;
  letter-spacing: .04em;
  color: var(--indigo-lift);
  font-weight: 700;
  margin-bottom: 6px;
}


/* -----------------------------------------------------------------------------
   Reduced motion: every figure shows its finished state immediately.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .five-q, .five-n, .pz-piece, .pz-shape, .pz-v, .pz-head-k,
  .five-q { transform: none; opacity: 1; color: var(--text); }
  .five-n { color: var(--indigo-lift); }
  .five-q::after { animation: none; }
  .pz-piece { transform: none; opacity: 1; }
  .pz-logo { animation: none; opacity: 1; }
  .pz-shape { fill: var(--warn-bg); stroke: var(--warn); }
  .pz-v { fill: var(--text); }
  .pz-head-k { color: var(--warn); }
  /* The timeline renders its resolved frame from the script; all that is
     needed here is to stop the marker and the settlement label pulsing. */
  .stl-dot, .stl-dot::after, .stl-end { animation: none !important; }
  .stl-status { transition: none; }
  .stl-head { display: none; }
  .stl-ticks i { transform: scaleY(.62) !important; opacity: .62 !important; }
  .mk-t { animation: none; stroke-dashoffset: 0; }
  .mk-f { animation: none; opacity: 1; }
  .mk-glow { animation: none; opacity: .3; }
  .mk-top { opacity: .38; }
  .mk-btm { opacity: 1; transform: none; }
  .ask-cursor { animation: none; }
  .gov-ledger.is-roll .gov-row, .gov-ledger.is-roll .gov-check svg, .gov-row.is-pulse { animation: none; }
  .cn-br { width: 34px; height: 34px; opacity: 1; }
}


/* --- ./effects/effects.css --- */
/* =============================================================================
   Effects - Ambient background & motion
   -----------------------------------------------------------------------------
   The animated atmosphere. CSS here defines how the effects look; the motion
   that follows the cursor is driven by scripts/effects.js.
   ========================================================================== */

/* -----------------------------------------------------------------------------
   GLOW - two soft light orbs (#glowCloud lag + #glowCore tight) that trail the
   cursor. Fixed, behind content, screen-blended. Fades out when the pointer
   leaves the page. Position is set each frame by scripts/effects.js.
   -------------------------------------------------------------------------- */
.glow {
  position: fixed; left: 0; top: 0; border-radius: 50%;
  /* z-index 0 (matches the live site): the orbs must paint BEHIND the page
     content so glass panels frost them via backdrop-filter. At z-index 2 they
     floated above every panel and the whole see-through effect vanished. */
  pointer-events: none; z-index: 0;
  mix-blend-mode: var(--glow-blend); will-change: auto;
  opacity: .9;
  transition: opacity .5s ease;
}
.glow-cloud { width: 600px; height: 600px; background: radial-gradient(circle, var(--cloud-1), transparent 60%); }
.glow-core  { width: 210px; height: 210px; background: radial-gradient(circle, var(--cloud-2), transparent 60%); }

/* -----------------------------------------------------------------------------
   AURORA - drifting colour clouds inside a section. Add
   <div class="aurora"><b class="a1"></b><b class="a2"></b><b class="a3"></b></div>
   as the first child of a hero/section.
   -------------------------------------------------------------------------- */
/* Full-viewport width so the glow reaches the window edges (fading out there)
   instead of being clipped at the narrow content margins. */
.aurora { position: absolute; top: 0; bottom: 0; left: 50%; width: 100vw; transform: translateX(-50%); overflow: hidden; pointer-events: none; z-index: 0; }
.aurora b {
  position: absolute; display: block; border-radius: 50%;
  filter: blur(72px); opacity: .55; mix-blend-mode: var(--glow-blend); will-change: auto;
}
.aurora .a1 { width: 42vw; height: 42vw; left: -6vw; top: -10vw; background: radial-gradient(circle, var(--cloud-1), transparent 67%); animation: drift1 26s ease-in-out infinite; }
.aurora .a2 { width: 38vw; height: 38vw; right: -6vw; top: -6vw; background: radial-gradient(circle, var(--cloud-2), transparent 66%); animation: drift2 32s ease-in-out infinite; }
.aurora .a3 { width: 34vw; height: 34vw; left: 34vw; top: 14vw; background: radial-gradient(circle, var(--cloud-3), transparent 66%); animation: drift3 38s ease-in-out infinite; }

/* -----------------------------------------------------------------------------
   KEYFRAMES - the shared motion library. Components reference these by name
   (e.g. .text-grad, .live-dot.anim, .aurora b, .cta-orbit). All token-driven so
   they read correctly in both themes.
   -------------------------------------------------------------------------- */
/* Animated indigo sweep across headline text / stat numbers (.text-grad). */
@keyframes gradFlow { 0% { background-position: 0% 0; } 100% { background-position: -200% 0; } }

/* Live status pip (.live-dot.anim) - a gentle opacity breathe + glow bloom. */
@keyframes ssPulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
@keyframes dotGlow { 0%, 100% { box-shadow: 0 0 6px var(--signal); } 50% { box-shadow: 0 0 16px var(--signal), 0 0 6px var(--signal); } }

/* Footer place separator dot (.foot-place i) - pulses purple with a soft halo. */
@keyframes dotPulse {
  0%, 100% { opacity: .55; color: var(--indigo-lift); text-shadow: 0 0 0 transparent; }
  50%      { opacity: 1;   color: var(--grad-hi);     text-shadow: 0 0 14px var(--signal), 0 0 7px var(--indigo-lift); }
}

/* Drifting aurora clouds (.aurora b). */
@keyframes drift1 { 0%, 100% { transform: translate(0, 0) scale(1); }    50% { transform: translate(6vw, 4vw) scale(1.12); } }
@keyframes drift2 { 0%, 100% { transform: translate(0, 0) scale(1.06); } 50% { transform: translate(-5vw, 5vw) scale(.92); } }
@keyframes drift3 { 0%, 100% { transform: translate(0, 0) scale(1); }    50% { transform: translate(-4vw, -5vw) scale(1.1); } }

/* Rotating conic border trace on CTA panels (.cta-shine / --cta-trace). */
@keyframes ctaTrace { to { --cta-trace: 360deg; } }

/* -----------------------------------------------------------------------------
   SECTION RAIL - removed per request (the floating scroll indicator).
   -------------------------------------------------------------------------- */
.rail { display: none !important; }

/* -----------------------------------------------------------------------------
   PERFORMANCE - keep the renderer from being pinned by the always-on ambient
   animations (drifting glow clouds, gradient headline, pulses).
   • While the tab is hidden, pause every animation (scripts/effects.js toggles
     .anim-off on <html>).
   • For users who prefer reduced motion, stop the ambient motion entirely.
   -------------------------------------------------------------------------- */
html.anim-off *,
html.anim-off *::before,
html.anim-off *::after { animation-play-state: paused !important; }

@media (prefers-reduced-motion: reduce) {
  .aurora b,
  .text-grad,
  .cta-orbit,
  .prose li::before,
  .foot-place i,
  .live-dot.anim { animation: none !important; }
  .glow { display: none; }
}


/* --- ./shell/frame.css --- */
/* =============================================================================
   Shell page frame
   -----------------------------------------------------------------------------
   Full-bleed dark canvas with a centred content column.

   The imported V3 dump sets `body { display:flex }` with a cream background -
   that was built for the full-screen STANDALONE pages, where .site fills the
   viewport. On the shared shell pages it shrank .site to its content width and
   centred it, leaking the cream body colour down both sides, and left the header
   wider than the page content.

   Making .site full-width fixes both: the dark canvas covers the viewport, and
   .header-inner / .container / .footer-top all resolve to the SAME centred
   column (they each use width:min(1000px, 100% - gutter)).
   ========================================================================== */
html, body { background: var(--bg); }
body { display: block; color: var(--text); }
.site {
  width: 100%;
  min-height: 100vh;
  display: flex;                 /* sticky-footer column: pins the footer to the */
  flex-direction: column;        /* bottom on short pages instead of leaving a gap */
  overflow-x: clip;
  padding-top: var(--header-h);
  background: transparent;   /* let the fixed .site-bg grid + glow field show through */
  color: var(--text);
}   /* clip full-viewport glow without creating a scroll container */
.site > .page-body { flex: 1 0 auto; }   /* content grows to fill, pushing footer down */
.site > .site-footer { flex: 0 0 auto; }

/* Header, content and footer ALL share one centred width - the header never
   extends past the body margins. Narrow, tight, balanced column. */
.container,
.footer-top,
.footer-bottom-inner { width: min(1300px, calc(100% - var(--gutter))); }
/* The header bar runs a touch wider (smaller gutter) so the long nav has room
   before it collapses to the hamburger; both use fluid gutters so they
   compress cleanly on tablet/phone instead of clinging to a fixed margin. */
.header-inner { width: min(1340px, calc(100% - var(--gutter-header))); }
.container,
.header-inner,
.footer-top,
.footer-bottom-inner { margin-inline: auto; }

.section { padding-block: var(--section-pad); }
.text-param {
  --text-color: inherit;
  --text-size: inherit;
  --text-weight: inherit;
  color: var(--text-color);
  font-size: var(--text-size);
  font-weight: var(--text-weight);
}

.site-header {
  position: fixed !important;
  top: 0;
  left: 0;
  right: 0;
  height: var(--header-h);
  z-index: var(--z-header);
  transform: none !important;
  isolation: isolate;
  pointer-events: auto;
  background: var(--header-bg);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
}
.header-inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
}

.nav { display: flex; align-items: center; }
.nav-link,
.nav-dd-btn {
  color: var(--muted);
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  font-family: inherit;
  font-weight: 600;
}
.nav-dd { position: relative; }
.nav-dd-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: 0;
  background: transparent;
}
.caret {
  width: 6px;
  height: 6px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .25s ease;
}
.nav-dd:hover .caret { transform: rotate(-135deg) translate(-1px, -1px); }
.dd-menu {
  position: absolute;
  top: calc(100% + 16px);
  left: 50%;
  min-width: 248px;
  padding: 8px;
  border-radius: 18px;
  background: var(--elev);
  border: 1px solid var(--brd);
  box-shadow: var(--shadow);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%) translateY(8px);
  transition: opacity .24s ease, visibility .24s ease, transform var(--motion-window);
}
.nav-dd:hover .dd-menu,
.nav-dd:focus-within .dd-menu {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
.dd-menu::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 18px;
}
.dd-link {
  display: block;
  padding: 11px 14px;
  border-radius: 12px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
  transition: background .32s ease, color .2s ease;
}
.dd-link small {
  display: block;
  margin-top: 2px;
  color: var(--dim);
  font-size: 12.5px;
  font-weight: 500;
}
.dd-link:hover { background: var(--hover); }
.dd-link-cta {
  color: var(--on-accent);
  background: var(--indigo);
  font-weight: 700;
  margin-top: 4px;
  box-shadow: 0 4px 18px -6px var(--glow-2);
}
.dd-link-cta small { color: var(--on-accent); opacity: .82; font-weight: 500; }
.dd-link-cta:hover { background: var(--indigo-2); }

.header-tools {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
}
.theme-btn { position: relative; width: 40px; height: 40px; }
.ti {
  position: relative;
  width: 19px;
  height: 19px;
  transition: transform .28s cubic-bezier(.4,1.4,.5,1), filter .25s ease;
}
.ti svg {
  position: absolute;
  inset: 0;
  width: 19px;
  height: 19px;
  transition: transform .55s cubic-bezier(.5,1.5,.4,1), opacity .4s ease;
}
[data-theme="dark"] .ti-moon { opacity: 1; transform: rotate(0deg) scale(1); }
[data-theme="dark"] .ti-sun { opacity: 0; transform: rotate(110deg) scale(.3); }
[data-theme="light"] .ti-moon { opacity: 0; transform: rotate(-110deg) scale(.3); }
[data-theme="light"] .ti-sun { opacity: 1; transform: rotate(0deg) scale(1); }

.menu-toggle {
  display: none;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  position: relative;
  flex: 0 0 auto;
}
.menu-toggle span {
  position: absolute;
  left: 11px;
  right: 11px;
  height: 1.8px;
  border-radius: 2px;
}
.menu-toggle span:nth-child(1) { top: 14px; }
.menu-toggle span:nth-child(2) { top: 19px; }
.menu-toggle span:nth-child(3) { top: 24px; }

.scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-scrim);
  background: rgba(0,0,0,.5);
  backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
}
.site.menu-open .scrim,
.scrim.open { opacity: 1; visibility: visible; }
.drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: var(--z-drawer);
  width: min(360px, 86vw);
  height: 100%;
  background: var(--elev);
  border-left: 1px solid var(--brd);
  box-shadow: var(--shadow);
  transform: translateX(102%);
  overflow: hidden;   /* the inner .drawer-scroll scrolls; the CTA stays pinned */
  display: flex;
  flex-direction: column;
}
.site.menu-open .drawer,
.drawer.open { transform: translateX(0); }

.site-header .menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.site-header .menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.site-header .menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* --- Header / nav responsive strategy ---------------------------------------
   The body content keeps wide side margins for readability, but the header bar
   spans a little wider (smaller gutter) so the long nav has room. The nav is
   also compacted, letting the full menu hold until a genuinely tight window
   before collapsing to the hamburger. */
.nav { gap: clamp(52px, 5vw, 78px); }

/* Header page links - slightly larger, and they magnify on hover (same springy
   feel as the icon buttons).
   Magnify technique (dual copy, like the brand logo's purple hover swap): each
   label holds an in-flow copy at the resting size (.nl-rest) plus an absolutely
   centered copy pre-typeset at the magnified size (.nl-big = 15.5px × 1.1).
   Hover scales both while crossfading, so both settled states are native crisp
   rasters - animating one copy either smeared the glyphs (composited texture)
   or shimmered per-frame (main-thread re-raster): the choppiness. */
.site-header .nav-link,
.site-header .nav-dd-btn {
  font-size: 15.5px;
  transition: color .2s ease;
}
.site-header .nav-link { display: inline-block; }
.site-header .nav-link:hover,
.site-header .nav-dd:hover .nav-dd-btn { color: var(--icon-hover); }

.site-header .nl { position: relative; display: inline-block; }
.site-header .nl-rest,
.site-header .nl-big {
  display: inline-block;
  /* --ease-out (no overshoot): a springy bezier over-scaled then settled back,
     reading as a choppy double-movement. */
  transition: transform var(--motion-window), opacity .34s ease;
}
.site-header .nl-big {
  position: absolute; left: 50%; top: 50%;
  font-size: 17.05px; white-space: nowrap;
  transform: translate(-50%, -50%) scale(.9091);
  opacity: 0;
}
.site-header .nav-link:hover .nl-rest,
.site-header .nav-dd:hover .nav-dd-btn .nl-rest { transform: scale(1.1); opacity: 0; }
.site-header .nav-link:hover .nl-big,
.site-header .nav-dd:hover .nav-dd-btn .nl-big { transform: translate(-50%, -50%) scale(1); opacity: 1; }

/* Brand logo - behaves like the theme toggle: normal colour at rest, accent
   purple on hover (crossfading to the logo-purple-*.png assets, generated from
   logo-white.png at the theme accent colours - a CSS mask approach hung the
   browser compositor, so real bitmaps it is), and magnifies on hover. The
   .logo-hover imgs sit stacked on the .logo-base imgs; the theme's
   logo-dark/logo-light display rules pick which pair is active. */
/* No will-change here: keeping the brand permanently composited made the GPU
   resample the logo bitmap at a fractional offset - it painted crisp on load,
   then went blurry once the layer was promoted. Promotion now only happens
   during the hover transition itself. */
.brand { position: relative; transition: transform var(--motion-window); }
.brand {
  display: inline-flex;
  align-items: center;
  height: 28px;
  flex: 0 0 auto;
}
.logo-light { display: none; }
.logo-dark { display: block; }
[data-theme="light"] .logo-light { display: block; }
[data-theme="light"] .logo-dark { display: none; }
.brand img.logo-light,
.foot-brand img.logo-light { display: none; }
.brand img.logo-dark,
.foot-brand img.logo-dark { display: block; }
[data-theme="light"] .brand img.logo-light,
[data-theme="light"] .foot-brand img.logo-light { display: block; }
[data-theme="light"] .brand img.logo-dark,
[data-theme="light"] .foot-brand img.logo-dark { display: none; }
/* Pin both logo boxes to stable pixel sizes so the browser rasterizes them
   cleanly during hover and theme transitions. */
.brand img { width: auto; height: 28px; }
.brand-logo { height: 28px; width: auto; display: block; color: var(--text); transition: color .34s ease; }
.brand:hover .brand-logo { color: var(--indigo-lift); }
.foot-brand img { width: auto; height: 24px; }

/* Footer columns: let the PRODUCT column size to its longest link so
   "The Resolution Roundtable" sits on one line - v3-export's 1fr squeezed it
   below its natural width and wrapped it. That freed-up width made COMPANY
   and CONNECT stretch wider than their content needs while sitting close
   together, reading as cramped; widen the gap to give the three right
   columns room to breathe. Desktop only; the ≤1000px layouts in v3-export
   (2-col / 1-col) have plenty of room and stay as-is. */
@media (min-width: 1001px) {
  .footer-top {
    grid-template-columns: minmax(280px, 1.25fr) repeat(3, minmax(170px, .75fr));
    column-gap: clamp(44px, 5vw, 76px);
    align-items: start;
  }
  .foot-col { min-width: 0; }
  .foot-col a { max-width: 24ch; }
}
.brand:hover { transform: scale(1.08); }
.brand img { transition: opacity .34s ease; }
.brand img.logo-hover { position: absolute; left: 0; top: 50%; translate: 0 -50%; opacity: 0; }
.brand:hover img.logo-base { opacity: 0; }
.brand:hover img.logo-hover { opacity: 1; }

.site-footer {
  position: relative;
  z-index: 1;
  border-top: 1px solid var(--line);
  background: var(--footer-bg);
  margin-top: auto;
}
.footer-top {
  padding: 44px 0 32px;
  display: grid;
  grid-template-columns: 1.7fr 1fr 1fr 1fr;
  gap: 36px;
}
.foot-brand img { margin-bottom: 14px; }
.foot-tag {
  max-width: 262px;
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 14.5px;
  line-height: 1.65;
}
.foot-col h5,
.foot-col .foot-h {
  margin: 0 0 13px;
  color: var(--dim);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.foot-col a {
  display: block;
  margin-bottom: 9px;
  color: var(--muted);
  font-size: 14.5px;
  font-weight: 500;
  text-decoration: none;
  transition: color .2s ease;
}
.foot-col a:hover { color: var(--icon-hover); }
.footer-bottom { border-top: 1px solid var(--line); }
.footer-bottom-inner {
  padding: 16px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.footer-bottom-inner span { font-size: 13px; }
.foot-legal {
  display: flex;
  gap: 8px;
  align-items: center;
}
.foot-legal a {
  color: var(--dim);
  text-decoration: none;
  transition: color .2s ease;
}
.foot-legal a:hover { color: var(--icon-hover); }

/* The theme toggle's icon sits ~10px inside its invisible 40px button, so the
   flexbox's equal side gaps LOOK unequal (logo→Platform reads tighter than
   Company→toggle). Shift the nav right to balance the two optically. */
.site-header .nav { margin-left: 18px; }
.site-header .header-tools { position: relative; }
.site-header .theme-btn,
.site-header .desk-cta {
  transition: opacity .34s ease, transform var(--motion-window), filter .34s ease;
}

/* Header search: hover/focus expands the input. Rather than sliding the nav off
   to the left (which ran it off-screen at tight widths), we FADE the rest of the
   header out so the search has the bar to breathe - nav, Request Demo and the
   theme toggle fade together, then return on blur. The SmartSettle AI brand mark
   stays put and fully visible throughout (never fades with the rest). */
.site-header .brand {
  transition: transform .5s var(--ease-out), opacity .34s ease;
}
/* `display .4s allow-discrete` lets the nav FADE in/out as it collapses to the
   hamburger across the 900px breakpoint, instead of snapping (modern browsers;
   older ones fall back to an instant swap). */
.site-header .nav {
  transition: transform .4s var(--ease-out), opacity .3s ease, display .4s allow-discrete;
}
.site-header .header-inner:has(.site-search:hover) .nav,
.site-header .header-inner:has(.site-search:focus-within) .nav {
  opacity: 0;
  transform: translateX(-8px);
  pointer-events: none;
}
.site-header .header-tools:has(.site-search:hover) .theme-btn,
.site-header .header-tools:has(.site-search:focus-within) .theme-btn,
.site-header .header-tools:has(.site-search:hover) .desk-cta,
.site-header .header-tools:has(.site-search:focus-within) .desk-cta {
  opacity: 0;
  transform: translateX(-18px);
  filter: blur(2px);
  pointer-events: none;
}
.site-search {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  width: 38px;
  height: 38px;
  transition: width 1.25s var(--ease-reveal);   /* slow, smooth expand */
}
.site-search:hover,
.site-search:focus-within { width: min(300px, 30vw); }
.site-search::after {
  content: "";
  position: absolute;
  left: 38px;
  right: 8px;
  bottom: 5px;
  height: 1px;
  border-radius: 999px;
  background: var(--icon-hover);
  box-shadow: 0 0 12px color-mix(in srgb, var(--icon-hover) 28%, transparent);
  opacity: 0;
  transform: scaleX(.02);
  transform-origin: left center;
  transition: transform var(--motion-window), opacity .34s ease;
}
.site-search:hover::after,
.site-search:focus-within::after {
  opacity: 1;
  transform: scaleX(1);
}
.site-search-btn {
  position: relative;
  z-index: 2;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color .24s ease, transform var(--motion-window), filter .34s ease;
}
.site-search-btn svg { width: 17px; height: 17px; }
.site-search:hover .site-search-btn,
.site-search:focus-within .site-search-btn {
  color: var(--icon-hover);
  transform: scale(1.12);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--icon-hover) 72%, transparent));
}
.site-search input {
  position: absolute;
  right: 0;
  width: 100%;
  height: 38px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  padding: 0 8px 0 40px;
  opacity: 0;
  pointer-events: none;
  transform: translateX(8px);
  transform-origin: right center;
  transition: opacity .5s ease .3s, transform 1.25s var(--ease-reveal);
}
.site-search:hover input,
.site-search:focus-within input {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(0);
}
.site-search input::placeholder { color: var(--dim); }
/* Chromium draws a native clear button inside type="search". In this header it
   lands on top of the search icon, which reads as a stray glyph rather than a
   control. Escape clears the field, so nothing is lost by removing it. */
.site-search input::-webkit-search-cancel-button,
.site-search input::-webkit-search-decoration,
.drawer-search input::-webkit-search-cancel-button,
.drawer-search input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

/* Opened by a click on the icon rather than by hover. The click handler in
   scripts/site.js focuses the field, so :focus-within already does the work;
   this class keeps the field open on touch, where focus can be lost to the
   soft keyboard before the transition finishes. */
.site-search.is-open { width: min(300px, 30vw); }
.site-search.is-open::after { opacity: 1; transform: scaleX(1); }
.site-search.is-open input { opacity: 1; pointer-events: auto; transform: translateX(0); }
.site-search.is-open .site-search-btn {
  color: var(--icon-hover);
  transform: scale(1.12);
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--icon-hover) 72%, transparent));
}
/* The reset's blue :focus-visible ring reads as a stray border inside the open
   search bar; the indigo underline + glowing icon already signal focus here. */
.site-search input:focus,
.site-search input:focus-visible { outline: none; }

/* Dropdown section labels - same treatment as the mobile drawer's categories. */
.dd-sec {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 14px 14px 7px;
  opacity: .82;
}
.dd-sec::before {
  content: "";
  width: 12px;
  height: 1px;
  border-radius: 999px;
  background: currentColor;
  opacity: .58;
}
.dd-menu .dd-sec:first-child { margin-top: 8px; }

.dd-link-cta {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: transform var(--motion-window), background .34s ease, box-shadow .34s ease;
  transform-origin: center;
}
.dd-link-cta::after {
  content: "";
  position: absolute;
  top: -40%;
  bottom: -40%;
  left: -56%;
  width: 30%;
  border-radius: inherit;
  pointer-events: none;
  background:
    radial-gradient(ellipse at center, rgba(255,255,255,.22) 0%, rgba(255,255,255,.1) 34%, transparent 68%),
    linear-gradient(115deg, transparent 0%, transparent 30%, rgba(255,255,255,.08) 46%, rgba(255,255,255,.2) 50%, rgba(255,255,255,.08) 54%, transparent 70%, transparent 100%);
  filter: blur(4px);
  transform: translate3d(0, 0, 0) skewX(-14deg);
  opacity: 0;
  transition: transform .62s cubic-bezier(.4,.8,.3,1), opacity .28s ease;
}
.dd-link-cta:hover {
  transform: scale(1.035);
  box-shadow: 0 12px 26px -10px var(--glow-2);
}
.dd-link-cta:hover::after {
  transform: translate3d(540%, 0, 0) skewX(-14deg);
  opacity: .72;
}
.dd-link-cta > * { position: relative; z-index: 1; }

/* Hero sits comfortably below the header (not jammed against it). */
.page-body > section:first-child { padding-top: 56px; }

/* Let the background glow reach the window edges: sections that contain an
   aurora don't clip it (the aurora clips its own clouds to the hero height, and
   .site clips any horizontal overflow at the viewport edge). Only the text
   content stays in the narrow column. */
.section:has(.aurora) { overflow: visible; }

/* Section rhythm - one consistent gap between sections (not doubled top+bottom
   padding), so the space between e.g. "About Us" and "Our Mission" matches the
   clean spacing on the style guide. */
.page-body > section { padding-top: var(--section-pad); padding-bottom: 0; }
/* The V3 dump zeroes follow-on sections with a more specific selector
   (.page-body > section + section { padding-top:0 }); restate the rhythm at the
   same specificity here (imported last) so --section-pad actually applies. */
.page-body > section + section { padding-top: var(--section-pad); }
.page-body > section:last-child { padding-bottom: var(--section-pad); }
/* A divider at the very top of a section gets no extra top margin (the section's
   own padding already spaces it from the section above) but keeps breathing room
   below it so it isn't jammed against the heading that follows. */
.section > .divider:first-child { margin-top: 0; margin-bottom: 30px; }

/* Compact nav so the header fits the narrow column that aligns with the body:
   "Our Team" and "Thought Leadership" live in the Company dropdown (top-level
   shows Platform · The Resolution Roundtable · Company). The nav AND the Request
   Demo button stay together until the window is tight, then everything collapses
   to the hamburger at once (<900px). */
.site-header .nav .nav-collapsible { display: none; }
/* The hamburger also fades/scales in rather than snapping (allow-discrete). */
.site-header .menu-toggle {
  transition: transform .28s var(--ease-out), color .24s ease, opacity .3s ease, display .3s allow-discrete;
}
@media (min-width: 900px) {
  .site-header .nav { display: flex !important; opacity: 1; transform: none; }
  .site-header .menu-toggle { display: none !important; opacity: 0; transform: scale(.85); }
  .site-header .header-tools .desk-cta { display: inline-flex !important; }
  /* Nav fades in when the window widens past the breakpoint. */
  @starting-style { .site-header .nav { opacity: 0; transform: translateY(-6px); } }
}
@media (max-width: 899px) {
  .site-search { display: none; }
  /* Collapse the whole nav + desktop CTA to the hamburger (which opens the
     mobile drawer). Everything fades across the breakpoint. */
  .site-header .nav { display: none !important; opacity: 0; transform: translateY(-6px); }
  .site-header .header-tools .desk-cta { display: none !important; }
  .site-header .menu-toggle { display: inline-flex !important; opacity: 1; transform: none; }
  /* Hamburger fades in when the window narrows past the breakpoint. */
  @starting-style { .site-header .menu-toggle { opacity: 0; transform: scale(.85); } }
}
@media (max-width: 1000px) {
  .footer-top {
    grid-template-columns: 1fr 1fr;
    gap: 30px;
  }
}
@media (max-width: 440px) {
  .footer-top { grid-template-columns: 1fr; }
}

.footer-bottom-inner span,
.footer-bottom-inner a,
.foot-place {
  font-family: var(--font-sans);
  letter-spacing: 0;
  color: var(--dim);
}
/* PHONE FOOTER.

   On a wide screen the bottom row is three things across: copyright, legal
   links, cities. On a phone that same row wrapped into an awkward L, with the
   cities jammed against the right edge under the links.

   Instead: two columns that each stack, copyright on the left and legal on the
   right, then the cities on their own centred row underneath. Two short lines
   read better than one long one at this width, and the separator dot between
   the legal links goes, because stacked items do not need a divider. The city
   dot stays, since that line is still one line.

   Desktop is untouched: it keeps the three-across layout and one line each. */
@media (max-width: 700px) {
  .footer-bottom-inner { align-items: flex-start; row-gap: 6px; }

  .foot-copy,
  .foot-legal {
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.45;
  }
  .foot-legal { align-items: flex-end; text-align: right; gap: 4px; }
  .foot-legal i { display: none; }

  .foot-place {
    flex: 1 0 100%;
    text-align: center;
    justify-content: center;
    margin-top: 8px;
  }
}
.foot-place i {
  font-style: normal;
  margin: 0 8px;
  animation: dotPulse 2.6s ease-in-out infinite;   /* pulsing purple separator dot */
}
@media (prefers-reduced-motion: reduce) { .foot-place i { animation: none; } }

/* Condensed footer in hamburger mode: brand block on the left, one curated link
   column on the right. Full columns are hidden below the nav breakpoint. */
.foot-mini { display: none; }
@media (max-width: 899px) {
  .footer-top { grid-template-columns: 1fr 1fr !important; gap: 28px !important; align-items: start; }
  .footer-top .foot-col:not(.foot-mini) { display: none; }
  .foot-mini { display: block; text-align: right; }
  /* Shrink each link box to its text so hovering only lights up when over the
     words (block links would span the whole column width). */
  .foot-mini a { display: block; width: fit-content; margin-left: auto; max-width: none; }
}


/* --- ./effects/reduced-motion.css --- */
/* =============================================================================
   REDUCED MOTION - the site-wide backstop.

   Individual components already switch off their own animations when the
   visitor has asked for less motion. That worked as far as it went, but it
   only ever covered the animations somebody remembered: an audit on
   2026-08-03 found twenty looping animations with no escape at all, including
   the spinning rings on the homepage and the Roundtable page, the partner
   logo marquee, the clock, and the flowing connector lines.

   Naming every selector is the wrong shape of fix, because the next animation
   somebody adds is missed again. This block covers everything, including
   anything added later, so the per-component rules become belt and braces
   rather than the only defence.

   WHY THESE EXACT VALUES

   animation-duration: 1ms, not 0. A zero-length transition does not fire
   `transitionend`, and effects.js listens for it twice (the arrow return at
   effects.js:125 and the T+1 mark return at effects.js:362) to clean up after
   itself. 1ms is imperceptible and still fires the event.

   animation-iteration-count: 1, not `animation: none` and not
   `animation-play-state: paused`. Setting the count to 1 with a 1ms duration
   lands each animation on its END state. That matters: `sectionIn` in
   shell/page.css animates opacity 0 to 1 with `fill-mode: both`, so freezing
   it at the start would leave whole sections invisible. Every looping
   animation on this site ends where it started (a full 360 degree spin, a
   pulse returning to rest, a marquee translated by exactly one of its two
   identical halves), so jumping to the end is visually a no-op for them.

   The reveal-on-scroll rules that set `opacity: 1` under reduced motion in
   components/home.css and shell/page.css are still required and still do the
   real work of keeping content visible. Do not remove them.

   This file is imported LAST in styles/index.css so it wins on source order.
   ============================================================================= */

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

  /* The load-in reveal, which was invisible under reduced motion until now.
     effects.js deliberately does NOT add the .pz / .pz-in classes when the
     visitor has asked for less motion, and relies on this CSS to leave the
     elements in place. components/home.css already tries to do that with
     `html.js [data-pz] { opacity: 1 }`, but it loses on specificity to
     `html.enter.js [data-pz] { opacity: 0 }` two lines above it: two classes
     beats one. The result, measured on 2026-08-03 with Chromium emulating
     `prefers-reduced-motion: reduce`, was that the homepage h1, the lead
     paragraph and both hero buttons had a computed opacity of 0 and never
     recovered, on the live site. Same on /platform/.

     !important rather than a specificity duel, because this file is the
     backstop and the reveal machinery lives in three separate stylesheets. */
  html.js [data-pz],
  html.enter.js [data-pz],
  html.js .site .container.section.rv,
  html.js .page-body > section {
    opacity: 1 !important;
    transform: none !important;
  }

  html {
    scroll-behavior: auto !important;
  }

  /* The ambient background glows drift continuously and are purely decorative. */
  .glow {
    display: none;
  }
}
