@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&display=swap');
/* =================================================================
   VAST CRM — banner + about
   Layout/motion mirrors the haxon.ai reference, palette is ours:
   orange #F48120 (from assets/img/logo.png) on warm black.
   ================================================================= */

*, *::before, *::after { box-sizing: border-box; }

:root {
  --bg:        #060607;
  --ink:       #eef1f8;
  --muted:     #3e4047;
  --accent:    #f48120;
  --accent-hi: #ff9d42;
  --line:      rgba(255,255,255,.10);
  --font: "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --nav-h: 64px;

  /* one container for the whole site: the bar, the banner and every section
     line their content up on the same two edges */
  --shell: 1472px;
  --gutter: clamp(18px, 4vw, 56px);

  /* Bootstrap focuses in blue out of the box — put it on the brand accent */
  --bs-focus-ring-color: rgba(244,129,32,.35);

  --heroFade: 1;   /* 1 in the banner -> 0 once scrolled past  (set from JS) */
  --star: 0;       /* starfield opacity, the inverse            (set from JS) */
  --wash: 1;       /* the warm glow, gone once the field is      (set from JS) */
}

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Bootstrap sizes .container-xxl per breakpoint; this is the site own shell,
   and it beats those on source order. */
.container-xxl {
  max-width: var(--shell);
  padding-left: var(--gutter);
  padding-right: var(--gutter);
}

/* an inner page with no hero of its own: it only has to clear the fixed bar,
   so an empty one closes straight into the footer */
.page { padding-top: var(--nav-h); }

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

/* Banner watermark. Layer order, back to front:
     -4 this image · -3 warm wash · -2 starfield · -1 particles · content
   The two dark gradients are stacked over the photo inside the same
   background, which knocks it back to watermark strength and keeps the
   left/right edges dark enough for the headline and stats to read. */
.banner-bg {
  position: fixed;
  inset: 0;
  z-index: -4;
  pointer-events: none;
  background:
    linear-gradient(to right,
      rgba(6,6,7,.72) 0%, rgba(6,6,7,.20) 22%,
      rgba(6,6,7,.20) 78%, rgba(6,6,7,.72) 100%),
    linear-gradient(to bottom,
      rgba(6,6,7,.42) 0%, rgba(6,6,7,.06) 45%, rgba(6,6,7,.58) 100%),
    url("../img/banner-bg.png") center / cover no-repeat;
  opacity: var(--heroFade);
}

/* the warm wash that sits under everything. It belongs to the backdrop, so
   it only paints on pages whose site-header carries the attribute. */
.has-backdrop body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -3;
  pointer-events: none;
  background:
    radial-gradient(ellipse 70% 55% at 50% 42%, rgba(244,129,32,.13), transparent 68%),
    radial-gradient(ellipse 90% 60% at 50% 110%, rgba(244,129,32,.07), transparent 70%);
  opacity: var(--wash);
}

.starfield {
  position: fixed;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: var(--star);
}

/* the one particle field — banner grid, mark, burst and the about icon
   are all the same dots on this canvas, so it must outlive both sections */
.markfield {
  position: fixed;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(ellipse 96% 96% at 50% 50%, #000 62%, transparent 100%);
          mask-image: radial-gradient(ellipse 96% 96% at 50% 50%, #000 62%, transparent 100%);
}

/* ---------------------------------------------------------- shared */
.gbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 12px;
  height: 50px;
  padding: 0 26px;
  border: 1px solid rgba(244,129,32,.55);
  border-radius: 10px;
  background: rgba(244,129,32,.05);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .01em;
  white-space: nowrap;
  transition: background .3s ease, border-color .3s ease, transform .3s ease;
}
.gbtn:hover {
  border-color: var(--accent-hi);
  background: rgba(244,129,32,.14);
  transform: translateY(-2px);
}
.gbtn__ico { width: 22px; height: 22px; }

/* ------------------------------------------------------------- nav
   Bootstrap's navbar owns the layout, the collapse and the dropdowns.
   Everything below is only this site's skin over it, so the component
   keeps working — click, keyboard and the mobile panel included. */
.vast-nav {
  --bs-navbar-color: rgba(255,255,255,.88);
  --bs-navbar-hover-color: #fff;
  --bs-navbar-active-color: #fff;
  padding: 0;
  min-height: var(--nav-h);
  background: rgba(6,6,7,.72);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom: 1px solid transparent;
  transition: background .3s ease, border-color .3s ease;
}
.vast-nav.is-stuck { background: rgba(6,6,7,.94); border-bottom-color: var(--line); }
.vast-nav > .container-xxl {
  position: relative;                 /* the menu is centred on the shell, not
                                         on the space the brand leaves */
  min-height: var(--nav-h);
}

.vast-nav .navbar-brand { padding: 0; margin: 0; }
.vast-nav .navbar-brand img { height: 38px; width: auto; }

/* --- menu: Markets, Trading, Accounts, Learn, About - each one opens a
       mega panel. The skin for those lives in the MEGA MENU block below. --- */
.vast-nav .navbar-nav { gap: clamp(4px, 1.6vw, 15px); }
.vast-nav .nav-link {
  display: inline-flex;
  align-items: center;
  padding: 5px clamp(8px, .8vw, 14px);
  border-radius: 6px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: color .22s ease;
}
/* the page the visitor is on. site-header sets this from its active="",
   so a page only has to name its own top-level item once. */
.vast-nav .nav-link.active { color: var(--accent); }
/* Bootstrap hardcodes a blue ring on .nav-link, so --bs-focus-ring-color
   alone does not reach it — restate the ring on the brand accent. */
.vast-nav .nav-link:focus-visible,
.vast-nav .dropdown-item:focus-visible,
.vast-nav .navbar-toggler:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color);
}

.vast-nav .dropdown-menu {
  min-width: 300px;
  padding: 14px 0;
  border: 0;
  border-radius: 0;                 /* square panel, like the reference */
  background: #0c0c0d;
  box-shadow: 0 30px 70px -18px rgba(0,0,0,.92);
}
.vast-nav .dropdown-item {
  width: auto;
  margin: 0 14px;
  padding: 14px 18px;
  border-radius: 6px;
  font-family: var(--font);
  font-size: 14.5px;
  font-weight: 500;
  color: rgba(255,255,255,.9);
  transition: background .16s ease, color .16s ease;
}
.vast-nav .dropdown-item:hover,
.vast-nav .dropdown-item:focus { background: rgba(255,255,255,.075); color: #fff; }

/* Above the collapse breakpoint the panels open on hover, as the reference
   does. Bootstrap's click and keyboard paths still work underneath — this
   only shows the panel early, it does not replace the toggle. */
@media (min-width: 1200px) {
  /* centre the menu on the bar itself, so a wider logo never shifts it */
  .vast-nav .offcanvas-body { flex-grow: 1; }   /* Bootstrap zeroes this at xl, and then
                                                   .navbar-actions has nothing to push against */
  .vast-nav .navbar-nav {
    position: absolute;
    left: 0; right: 0;
    justify-content: center;
    pointer-events: none;               /* the empty flanks must not swallow
                                           clicks on the brand or the buttons */
  }
  .vast-nav .navbar-nav > .nav-item { pointer-events: auto; }
  .vast-nav .nav-item.dropdown { position: relative; }
  .vast-nav .dropdown-menu { margin-top: 18px; }
  .vast-nav .nav-item.dropdown::after {   /* keeps hover alive across the gap */
    content: "";
    position: absolute;
    left: 0; right: 0; top: 100%;
    height: 20px;
  }
  .vast-nav .nav-item.dropdown:hover > .dropdown-menu,
  .vast-nav .nav-item.dropdown.is-open > .dropdown-menu { display: block; }
}

/* --- the two header buttons: Bootstrap's .btn is the base --- */
.navbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.btn-vast,
.btn-vast-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 42px;
  padding: 0 24px;
  border-radius: 6px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.btn-vast-outline { border: 1px solid #424242; background: transparent; color: var(--ink); }
/* colour restated on hover: Bootstrap .btn:hover would otherwise reach it */
.btn-vast-outline:hover { background: #292929; color: var(--ink); }
.btn-vast { border: 1px solid var(--accent); background: var(--accent); color: #000; }
.btn-vast:hover { border-color: var(--accent-hi); background: var(--accent-hi); color: #000; }

.vast-nav .navbar-toggler {
  padding: 0px;
  border: none;
  border-radius: 6px;
  background:transparent;
}
.vast-nav .navbar-toggler:focus { box-shadow: none; }
.vast-nav .navbar-toggler:hover { border-color: rgba(244,129,32,.5); }

/* ============================= BANNER ============================= */
/* The runway: the banner stays put while the mark forms, holds and bursts.
   240px was one notch of hold, so whether a single wheel flick landed on the
   assembled mark or jumped straight over it was luck. 420px gives the hold
   ~1.8 notches of its own — keep it past the end of burst1 in particle.js
   (2.20 + 0.95 notches = 378px). */
.hero { position: relative; height: calc(100svh + 420px); }

/* the pinned box stays custom — Bootstrap has no sticky-viewport primitive.
   The two columns inside it are a plain Bootstrap row. */
.hero__pin {
  position: sticky;
  top: 0;
  height: 100svh;
  padding: calc(var(--nav-h) + 46px) 0 96px;
  overflow: hidden;
  opacity: var(--heroFade);
}

.hero__aura {
  position: absolute;
  left: 50%; top: 50%;
  width: min(88vw, 900px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  pointer-events: none;
  background: radial-gradient(circle, rgba(244,129,32,.20) 0%, rgba(244,129,32,.06) 34%, transparent 64%);
}
.hero__l, .hero__r { position: relative; z-index: 2; }
.hero__l { align-self: center; }
.hero__r { max-width: 520px; }
@media (min-width: 992px) { .hero__r { margin-left: auto; } }

.hero__title {
  margin: 0 0 30px;
  font-family: var(--font);
  font-size: clamp(2.4rem, 6vw, 5rem);
  font-weight: 700;
  line-height: .96;
  letter-spacing: -.015em;
  text-transform: uppercase;
}

.stats {
  position: relative;
  margin-top: 42px;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(16px, 3vw, 46px);
  padding: 22px 28px;
  width: fit-content;
}
.stats__c {
  position: absolute;
  width: 15px; height: 15px;
  border: 1px solid rgba(244,129,32,.65);
}
.stats__c--tl { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.stats__c--tr { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.stats__c--bl { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.stats__c--br { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.stat b {
  display: block;
  font-family: var(--font);
  font-size: clamp(1.15rem, 2.1vw, 1.6rem);
  font-weight: 700;
  line-height: 1.1;
}
.stat span {
  display: block;
  margin-top: 4px;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: .02em;
  color: rgba(255,255,255,.5);
}

.hero__claim {
  margin: 0;
  font-family: var(--font);
  font-size: clamp(2rem, 5.2vw, 4.2rem);
  font-weight: 700;
  line-height: .98;
  letter-spacing: -.015em;
  text-transform: uppercase;
}
.hero__claim em {
  font-style: normal;
  color: var(--accent);
}
.hero__note {
  margin: 30px 0 0;
  padding: 20px 22px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255,255,255,.025);
  font-size: 14.5px;
  line-height: 1.7;
  color: rgba(255,255,255,.72);
}

.scrollring {
  position: absolute;
  z-index: 3;
  right: clamp(14px, 3vw, 40px);
  bottom: clamp(18px, 3.5vh, 40px);
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 50%;
  transition: border-color .25s ease, background .25s ease;
}
.scrollring:hover { border-color: var(--accent); background: rgba(244,129,32,.1); }
.scrollring__arrow { font-size: 17px; color: rgba(255,255,255,.62); }

/* ============================== ABOUT ============================= */
.about {
  position: relative;
  /* short top padding so the pad rides up under the mark sooner; the sides
     are the container's job now */
  padding: clamp(40px, 6vh, 80px) 0 clamp(50px, 7vh, 90px);
}
/* a pill, not a rule-and-label: the dot carries the accent and the border
   keeps it reading as a chip above the heading */
.eyebrow {
  margin: 0 0 25px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--accent);
}
.eyebrow i {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(244,129,32,.16);
}

/* One rule for every section headline - keep new sections on it rather than
   restating the type. Only the vertical rhythm is ever overridden. */
.about__title,
.numbers__title,
.platform__title,
.plats__title,
.why__title,
.kb__title,
.steps__title,
.accs__title,
.wall__title,
.sup__title,
.faq__title {
  margin: 0 0 32px;
  font-size: clamp(2rem, 4.6vw, 2.8rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.01em;
}
.about__title em,
.numbers__title em,
.platform__title em,
.plats__title em,
.why__title em,
.kb__title em,
.steps__title em,
.accs__title em,
.wall__title em,
.sup__title em,
.faq__title em { font-style: normal; color: var(--accent); }

.about__p,
.numbers__p {
  margin: 0 0 20px;
  max-width: 60ch;
  font-size: 15.5px;
  line-height: 1.78;
  color: rgba(255,255,255,.74);
}
.about__p:last-child,
.numbers__p { margin-bottom: 0; }

/* ---- the holo pad ---- */
.about__stage {
  position: relative;
  min-height: clamp(340px, 44vw, 480px);
}
.beam {
  position: absolute;
  left: 50%;
  bottom: 20%;
  width: 4px;
  height: 44%;
  transform: translateX(-50%);
  background: linear-gradient(to top, rgba(244,129,32,.95), rgba(244,129,32,0));
  filter: blur(1px);
  box-shadow: 0 0 30px 5px rgba(244,129,32,.5);
}
.pad {
  position: absolute;
  left: 50%;
  bottom: 4%;
  width: min(100%, 470px);
  height: auto;
  transform: translateX(-50%);
}
.pad__side { fill: rgba(244,129,32,.13); }
.pad__deck { fill: rgba(244,129,32,.05); }
.pad__edge {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  filter: drop-shadow(0 0 7px rgba(244,129,32,.9));
}
.pad__rail {
  fill: none;
  stroke: var(--accent-hi);
  stroke-width: 4;
  stroke-linejoin: round;
  filter: drop-shadow(0 0 11px rgba(244,129,32,1));
}
.pad__ring { fill: none; stroke: rgba(244,129,32,.55); stroke-width: 1.4; }
.pad__ring--in { stroke: rgba(244,129,32,.8); }
.pad__node { fill: #fff; filter: drop-shadow(0 0 6px rgba(244,129,32,1)); }
.pad__core { fill: rgba(244,129,32,.75); }
.pad__core--hot { fill: #fff; filter: drop-shadow(0 0 9px rgba(244,129,32,1)); }

/* scroll-in reveal */
[data-rise] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .8s cubic-bezier(.16,.84,.3,1), transform .8s cubic-bezier(.16,.84,.3,1);
  transition-delay: var(--rd, 0s);
}
[data-rise].is-in { opacity: 1; transform: none; }


/* ============================ BY THE NUMBERS ============================
   Heading block over a rail of stat cards. The rail lives inside the shell
   like every other section, and six cards never fit it, so the row scrolls
   sideways with the next card already showing at the edge. */
.numbers { position: relative; }
.numbers__pin { padding: clamp(14px, 2vh, 30px) 0 clamp(40px, 6vh, 80px); }

/* Pinned mode, switched on by main.js once it knows how far the rail has to
   travel. The section is grown by exactly that distance and the block holds
   still while vertical scroll plays it out sideways, so every card has been
   seen before the page moves on. Without JS the rules above stand and the
   rail just scrolls sideways by itself. */
.numbers.is-pinned .numbers__pin {
  position: sticky;
  top: 0;                             /* main.js re-centres this on the viewport */
  padding: clamp(12px, 2vh, 26px) 0;
}
.numbers.is-pinned .numbers__rail { overflow: hidden; padding-bottom: 0; }
.numbers.is-pinned .numbers__track { will-change: transform; }
.numbers__head { margin-bottom: clamp(24px, 3.4vh, 40px); }

.numbers__ghost {
  display: block;
  font-size: clamp(3.4rem, 9.5vw, 10.5rem);
  font-weight: 800;
  line-height: .86;
  letter-spacing: -.045em;
  text-align: right;
  color: rgba(255,255,255,.05);
  user-select: none;
}

.numbers__rail {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding-bottom: 18px;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,255,255,.22) rgba(255,255,255,.06);
}
.numbers__rail:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); border-radius: 16px; }
.numbers__rail::-webkit-scrollbar { height: 4px; }
.numbers__rail::-webkit-scrollbar-track { background: rgba(255,255,255,.06); border-radius: 999px; }
.numbers__rail::-webkit-scrollbar-thumb { background: rgba(255,255,255,.22); border-radius: 999px; }
.numbers__rail::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.34); }

.numbers__track {
  display: flex;
  gap: clamp(14px, 1.6vw, 24px);
  width: max-content;
  margin: 0;
  list-style: none;
  /* percent, not vw: it resolves against the rail, so a scrollbar never
     throws the first card off the heading edge */
  padding: 0 max(var(--gutter), calc((100% - var(--shell)) / 2 + var(--gutter)));
}

.numcard {
  flex: none;
  width: clamp(230px, 24vw, 310px);
  display: flex;
  flex-direction: column;
   border-radius: 0px;
  background: #0f0f0f;
  overflow: hidden;
  transition: border-color .25s ease, transform .25s ease;
}
.numcard:hover .numcard__tag{background-color: #fff; color: #000;}
.numcard__body { flex: 1; padding: 30px 26px 36px; }
.numcard__body b {
  display: block;
  font-size: clamp(2.3rem, 3.4vw, 3.1rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
}
.numcard__body span { display: block; margin-top: 14px; font-size: 15px; color: rgba(255,255,255,.72); }
/* decoration only - below lg it would just push the cards down */
@media (max-width: 991.98px) { .numbers__ghost { display: none; } }

.numcard__tag {
  margin: 0;
  padding: 14px 26px;
  background: var(--accent);
  color: #15100a;
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: .09em;
  line-height: 1.3;
  text-transform: uppercase;
}

/* =========================== MEGA MENU ===========================
   Five panels, one per top-level item. Each is still a Bootstrap dropdown
   menu, so click, Escape, outside-click and the mobile collapse keep
   working; data-bs-display="static" in the markup keeps Popper off it, so
   the rules below are the only positioning that applies.

   Desktop: the panel is position:fixed and spans the bar, which is why the
   centred <ul> above had its transform removed - a transformed ancestor
   would have become the panel's containing block. */

.vsprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.mm__ico,
.mm__arrow,
.mm__caret {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mm__ico { flex: none; width: 21px; height: 21px; margin-top: 2px; color: var(--accent); }
.mm__arrow { flex: none; width: 17px; height: 17px; }

/* the chevron on each top-level label. Bootstrap solid caret is off; this one
   is the same drawing as the panel icons, and it flips while the panel is up. */
.mm__caret {
  flex: none;
  width: 12px;
  height: 12px;
  margin-left: 7px;
  stroke-width: 2.6;
  opacity: .6;
  transition: transform .22s ease, opacity .22s ease;
}
.vast-nav .nav-item.mm:hover > .nav-link .mm__caret,
.vast-nav .nav-item.mm.is-open > .nav-link .mm__caret,
.vast-nav .nav-item.mm.show > .nav-link .mm__caret { transform: rotate(180deg); opacity: 1; }

/* the top-level label lights up while its panel is open */
.vast-nav .nav-item.mm > .dropdown-toggle::after { display: none; }   /* no caret in the reference */
.vast-nav .nav-item.mm:hover > .nav-link,
.vast-nav .nav-item.mm.is-open > .nav-link,
.vast-nav .nav-item.mm.show > .nav-link { background:#1b1b1b; color: #fff; }

.mm__inner { display: grid; gap: 30px; }
.mm__cols { display: grid; row-gap: 0; column-gap: 44px; align-content: start; }
.mm__group { min-width: 0; }

.mm__head {
  margin: 0 0 12px;
  font-size: 14.5px;
  font-weight: 600;
  color: rgba(255,255,255,.5);
}
.mm__head--gap { margin-top: 30px; }

.mm__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 5px; align-content: start; }

.mm__item {
  display: flex;
  gap: 13px; max-width: 320px;
  margin: 0 -12px;
  padding: 12px 12px;
  border-radius: 10px;
  transition: background .18s ease;
}
.mm__item:hover { background: rgba(255,255,255,.055); }
/* the row for the page you are on wears the hover state, held on */
.mm__item.active { background: rgba(255,255,255,.055); }

.mm__item:focus-visible {
  outline: 0;
  background: rgba(255,255,255,.055);
  box-shadow: 0 0 0 .2rem var(--bs-focus-ring-color);
}
.mm__txt { display: grid; gap: 3px; min-width: 0; }
.mm__txt b { font-size: 15px; font-weight: 700; line-height: 1.34; color: #fff; }
.mm__txt b sup { font-size: .56em; font-weight: 600; }
.mm__txt > span { font-size: 13.5px; line-height: 1.5; color: rgba(255,255,255,.62); }

/* --- the column on the right. It is flush with the top, right and bottom of
       the panel - that is why the panel itself carries no padding and .mm__cols
       pads its own side instead - and the card sits inside it on the padding.
       menu1-5.png are full card backdrops, empty at the bottom, so the title
       and button sit on the image rather than under it. --- */
.mm__promo {
  display: flex;
  padding: 20px;
  background: #141414;
}
.mm__promo-in {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
  min-height: 300px;
  padding: 24px 20px 22px;
  border-radius: 14px;
  background: #0f0f0f;
  overflow: hidden;
  text-align: center;
}
/* Top-anchored at the artwork's own proportion rather than stretched over the
   whole card. The card is as tall as the panel beside it, and a menu with a
   long list makes that much taller than the image - filling it would scale the
   artwork up and crop the sides off. Held to 600x676 it stays at natural size
   whatever the list does, and the card's own ground carries the rest, which is
   where the title and button were always meant to sit. */
.mm__promo-img {
  position: absolute;
  inset: 0 0 auto;
  aspect-ratio: 600 / 676;
}
.mm__promo-img img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }

.mm__promo-t,
.mm__promo-b { position: relative; z-index: 1; }
.mm__promo-t { margin: 0 0 16px; font-size: 16.5px; font-weight: 700; line-height: 1.34; }
.mm__promo-b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  height: 46px;
  padding: 0 15px;
  border-radius: 999px;
  background: #fff;                     /* the pill stays white; only the ink moves */
  color: #333;
  font-size: 14px;
  font-weight: 600;
  transition: color .2s ease;
}
.mm__promo-b:hover { color: #000; }
.mm__promo-b:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

@media (min-width: 1200px) {
  .vast-nav .nav-item.mm::after { height: 30px; }   /* hover bridge: label bottom to the panel top edge.
                                                      The labels are ~32px tall and centred in an 84px bar,
                                                      so the run down to the panel is ~26px — at 24 the
                                                      pointer fell through a dead strip on the way in. */

  .vast-nav .navbar-nav .mm__panel {
    position: fixed;                    /* pinned to the viewport so the panel spans
                                           the bar whichever item opened it. The selector
                                           carries three classes to outweigh Bootstrap own
                                           .navbar-expand-xl .navbar-nav .dropdown-menu. */
    top: calc(var(--nav-h) + 0px);
    left: var(--gutter);
    right: var(--gutter);
    width: auto;
    min-width: 0;
    max-width: calc(var(--shell) - 2 * var(--gutter));   /* the shell content box:
                                           with the insets above and auto margins the
                                           panel edges land exactly on the logo edge */
    margin: 0 auto;
    max-height: calc(100vh - var(--nav-h) - 24px);
    padding: 0;
    overflow-y: auto;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: #0f0f0f;
  }
  .mm__inner { grid-template-columns: minmax(0, 1fr) 360px; gap: 0; }
  .mm__cols { padding: 30px; }
  .mm__promo { border-radius: 0 18px 18px 0; }
  .mm__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mm__head--span { grid-column: 1 / -1; }
}

/* Between the collapse point and ~1400 the bar is tight: the menu is centred
   on the shell while the two buttons sit right, so the right side runs out of
   room first. Trim the buttons and the label padding rather than let them meet. */
@media (min-width: 1200px) and (max-width: 1399.98px) {
  .btn-vast,
  .btn-vast-outline { padding: 0 16px; }
  .vast-nav .nav-link { padding: 5px 8px; }
  .mm__caret { margin-left: 5px; }
}

@media (min-width: 1200px) and (max-width: 1439.98px) {
  .mm__cols { padding: 24px; }
  .mm__inner { grid-template-columns: minmax(0, 1fr) 300px; }
  .mm__promo { padding: 20px; }
  .mm__cols { column-gap: 30px; }
}


/* ============================== PLATFORM ==============================
   A bracketed headline over one image stage, with three tabs under it that
   swap the shot. The bar between them marks which tab is up. */
.platform {
  --plat-w: 1140px;                   /* the bar and the tabs stop short of the shell */
  position: relative;
  overflow-x: clip;                   /* the stage glow spills past the shell on
                                         narrow screens - clip it, do not scroll */
  padding: clamp(70px, 9vh, 130px) 0 clamp(90px, 12vh, 170px);
}
.platform__head { text-align: center; }

.platform__stage {
  position: relative;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  aspect-ratio: 2432 / 1024;
}
/* the glow behind the phones. The site-wide warm wash has already faded out
   by this section, so the stage carries its own. It is a positioned pseudo
   ahead of the shots in tree order, which paints it under them without
   needing a negative z-index that would fight the fixed canvases. */
.platform__stage::before {
  content: "";
  position: absolute;
  inset: -18% -13%;
  pointer-events: none;
  background: radial-gradient(ellipse 58% 70% at 50% 52%,
    rgba(244,129,32,.34), rgba(244,129,32,.12) 42%, transparent 72%);
}

.platform__shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;                 /* keeps the hidden shots out of the a11y
                                         tree while still allowing the fade */
  transition: opacity .45s ease, visibility .45s;
}
.platform__shot.is-on { opacity: 1; visibility: visible; }
.platform__shot img { width: 100%; height: 100%; object-fit: contain; }

.platform__bar {
  position: relative;
  height: 2px;
  max-width: var(--plat-w);
  margin: 0 auto;                     /* the line sits flush against the shot */
  overflow: hidden;
  border-radius: 2px;
  background: rgba(255,255,255,.09);
}
.platform__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: calc(100% / 3);
  border-radius: 2px;
  background: var(--accent);
  transition: transform .45s cubic-bezier(.16,.84,.3,1);
}

.platform__list {
  max-width: var(--plat-w);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 44px);
}
.platform__btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(22px, 3.4vh, 34px) 8px 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;
  opacity: .68;
  transition: opacity .25s ease;
}
.platform__btn.is-on,
.platform__btn:hover { opacity: 1; }
.platform__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); border-radius: 10px; }

.platform__ico {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin: 0 auto 16px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255,255,255,.04);
  transition: background .25s ease, border-color .25s ease, color .25s ease;
}
.platform__ico svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.platform__btn.is-on .platform__ico {
  border-color: var(--accent);
  background: var(--accent);
  color: #15100a;
}
.platform__btn b { display: block; margin: 0 0 10px; font-size: 16px; font-weight: 700; }
.platform__txt {
  display: block;
  max-width: 34ch;
  margin: 0 auto;
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(255,255,255,.62);
}

@media (max-width: 767.98px) {
  /* three columns get too narrow to read - stack them and let the bar span */
  .platform__list { grid-template-columns: 1fr; gap: 6px; }
  .platform__btn { padding-top: 24px; }
  .platform__fill { width: 100%; }
  .platform__bar { display: none; }
}

/* ========================= COMPLETE FOREX HUB ========================
   The one light section on the page. It carries its own ink tokens rather
   than flipping the globals, so everything above and below stays dark.
   The white ground paints over the fixed banner/starfield/particle layers
   on its own - those all sit on a negative z-index. */
.plats {
  --plats-w: 1240px;
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(64px, 8.5vh, 120px) 0;
  background: #fff;
  color: var(--ink-d);
}

.plats__head {
  max-width: 860px;
  margin: 0 auto clamp(34px, 4.5vh, 56px);
  text-align: center;
}
.plats__title { margin-bottom: 18px; }
.plats__lede {
  margin: 0;

}

/* the chip is white-on-glass by default, which disappears on a light ground */
.eyebrow--onlight {
  border-color: rgba(20,21,27,.14);
  background: #fff;
  color: var(--ink-d, #14151b);
}
/* on a white ground the dot is the only accent, so it carries no halo */
.eyebrow--onlight i { box-shadow: none; }

/* The five hub items read as a stack of full-width bands rather than a card
   grid. Each row is split down the middle - the numbered name against a thick
   accent rule on the outer edge, the copy on the other half - and the pair
   swaps sides row by row, so the eye zig-zags down the section. */
.plats__grid {
  max-width: var(--plats-w);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  gap: clamp(10px, 1.2vw, 16px);
}

.plat {
  position: relative;
  display: grid;
  grid-template-columns: 4fr 6fr;
  align-items: center;
  gap: clamp(18px, 3vw, 44px);
  padding: clamp(24px, 3vw, 38px) clamp(24px, 3vw, 40px);
  border: 1px solid var(--line-d);
  /* the hard stop drops the seam between the two halves, which is what gives
     the band its two-tone read on a white ground. It sits on the 40% line so
     it lands inside the gutter between the name and the copy, whatever the
     padding and gap resolve to at the current width. */
  background: linear-gradient(90deg, #f3f4f7 0 40%, #fafafb 40%);
  transition: border-color .25s ease, box-shadow .25s ease;
}

/* the accent rule is a pseudo-element so it can thicken on hover without
   the row reflowing around it */
.plat::before {
  content: "";
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: -1px;
  width: 6px;
  background: var(--accent);
  transition: width .25s ease;
}

/* every other row mirrors: copy on the left, name and rule on the right, and
   the columns flip with it so the narrow half stays under the name */
.plat:nth-child(even) {
  grid-template-columns: 6fr 4fr;
  background: linear-gradient(90deg, #fafafb 0 60%, #f3f4f7 60%);
}
.plat:nth-child(even)::before { left: auto; right: -1px; }
.plat:nth-child(even) .plat__head { grid-column: 2; grid-row: 1; }
.plat:nth-child(even) .plat__txt  { grid-column: 1; grid-row: 1; }

.plat:hover {
  box-shadow: 0 14px 34px rgba(20,21,27,.09);
}
.plat:hover::before { width: 10px; }

/* A row may carry a mark over its name - the platform pages do, the home
   page's rows do not. Selecting on the image rather than on a modifier is
   what keeps the two apart: no image in the markup, no rule to apply. The
   badges ship with their own ring, so nothing is drawn round them here. */
.plat__head img {
  display: block;
  width: clamp(46px, 4.2vw, 60px);
  height: auto;
  margin-bottom: 14px;
}
.plat__head b {
  display: block;
  font-size: clamp(19px, 1.6vw, 25px);
  font-weight: 800;
  line-height: 1.22;
  letter-spacing: -.01em;
}
.plat__txt {
  margin: 0;
  line-height: 1.8;

}

/* one column below the tablet break - the split stops earning its keep once
   each half is only a few words wide, so every row squares up on the left */
@media (max-width: 767.98px) {
  .plat,
  .plat:nth-child(even) {
    grid-template-columns: 1fr;
    gap: 10px;
    background: #f5f6f9;
  }
  .plat:nth-child(even)::before { left: -1px; right: auto; }
  .plat:nth-child(even) .plat__head { grid-column: 1; grid-row: 1; }
  .plat:nth-child(even) .plat__txt  { grid-column: 1; grid-row: 2; }
}
@media (max-width: 575.98px) {
  .plat__txt { font-size: 14.5px; line-height: 1.75; }
}


/* ============================ WHY CHOOSE ============================
   Four cards on a five-column grid, so the pair alternates 2/3 then 3/2
   and the row never reads as a plain quartet. The art is 1280x404 and
   full-bleed at the top of each card; the ratio is fixed so a narrow
   card and a wide one still line their copy up on the same baseline. */
.why {
  position: relative;
  overflow-x: clip;
  padding: clamp(70px, 9vh, 130px) 0 clamp(80px, 11vh, 150px);
}

/* The about page runs it on a ground of its own rather than the body's.
   The cards have to come up with it: at #0f0f0f they are darker than
   #151515, so on this ground they would sink into the section instead of
   sitting on it. #1b1b1b is the shade the contact panel already uses over
   the same ground. */
.why--panel { background: #151515; }


.why__head {
  max-width: 780px;
  margin: 0 auto clamp(34px, 4.5vh, 56px);
  text-align: center;
}
.why__title { margin-bottom: 18px; }
.why__lede {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: rgba(255,255,255,.62);
}

.why__grid {
  max-width: var(--why-w, 1240px);
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}
.why__card:nth-child(1),
.why__card:nth-child(4) { grid-column: span 2; }
.why__card:nth-child(2),
.why__card:nth-child(3) { grid-column: span 3; }

.why__card {
  --why-pad: clamp(20px, 2.4vw, 30px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #0f0f0f;
  transition: border-color .25s ease, transform .25s ease;
}
.why__card:hover { border-color: rgba(244,129,32,.45); transform: translateY(-3px); }

/* inset by the body padding, not full-bleed, so the art, the heading, the
   copy and the button all start on the same left edge */
.why__media {
  overflow: hidden;
  border-radius: 10px;
  aspect-ratio: 1280 / 404;
}
.why__media img { width: 100%; height: 100%; object-fit: cover; }
/* side by side the two cards are different widths, so the ratio would drop
   their headings on different lines. Fix the art height instead and let the
   narrow one crop - the compositions are all centred. */
@media (min-width: 992px) {
  .why__media { height: clamp(150px, 14.5vw, 215px); aspect-ratio: auto; }
}

.why__body { padding: clamp(18px, 2vw, 24px) var(--why-pad) var(--why-pad); }
.why__body b {
  display: block;
  margin-bottom: 10px;
  font-size: 16.5px;
  font-weight: 700;
  line-height: 1.3;
}
.why__body p {
  margin: 0 0 22px;
  font-size: 14.5px;
  line-height: 1.6;
  color: rgba(255,255,255,.62);
}

.why__cta {
  display: inline-flex;
  align-items: center;
  height: 38px;
  padding: 0 20px;
  border: 1px solid #424242;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.why__cta:hover { border-color: var(--accent); background: var(--accent); color: #000; }
.why__cta:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

/* the 2/3 split needs both cards side by side to mean anything - below lg
   they stack, and the art gets the full width it was cut for */
@media (max-width: 991.98px) {
  .why__grid { grid-template-columns: 1fr; }
  .why__grid > .why__card { grid-column: auto; }
}


/* =========================== KEY BENEFITS ===========================
   Heading column on the left, a horizontal accordion on the right. Only
   one panel is open: it takes every pixel the six closed strips leave
   over, so the row is always exactly as wide as the column. The closed
   strips carry the number and the title turned on its side.
   Below lg the same markup runs as an ordinary stacked accordion. */
.kb {
  position: relative;
  overflow-x: clip;
  padding: clamp(70px, 9vh, 130px) 0 clamp(80px, 11vh, 150px);
  /* the one section that sits on its own panel rather than the page black */
  background: #151515;
}
.kb__wrap {
  display: grid;
  grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}
.kb__title { margin-bottom: 18px; }
.kb__lede {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: rgba(255,255,255,.62);
}

.kb__list {
  display: flex;
  gap: 10px;
  min-height: clamp(430px, 40vw, 560px);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* closed: the strip is 66px and does not grow. Open: flex-grow takes the
   slack, which is the one property in the pair that animates cleanly. */
.kb__item {
  flex: 0 1 66px;
  min-width: 66px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #171717;
  transition: flex-grow .5s cubic-bezier(.16,.84,.3,1), border-color .3s ease;
}
.kb__item.is-on { flex-grow: 1; border-color: rgba(244,129,32,.35); }
.kb__item:not(.is-on):hover { border-color: rgba(255,255,255,.2); }

.kb__head {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 22px 8px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.kb__head:focus-visible { outline: 0; box-shadow: inset 0 0 0 .2rem var(--bs-focus-ring-color); }

.kb__num {
  flex: none;
  font-size: clamp(19px, 1.45vw, 22px);
  font-weight: 700;
  letter-spacing: -.01em;
  color: rgba(255,255,255,.42);
  transition: color .3s ease;
}
.kb__item.is-on .kb__num { color: var(--accent); }

/* rotate(180deg) on top of vertical-rl so the closed titles read bottom
   to top, and margin-top pins them to the foot of the strip */
.kb__name {
  margin-top: auto;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
  font-size: clamp(16px, 1.25vw, 19px);
  font-weight: 600;
  line-height: 1.2;
  color: rgba(255,255,255,.55);
}

.kb__item.is-on .kb__head {
  flex: none;
  flex-direction: row;
  align-items: flex-start;
  gap: 14px;
  padding: 26px 26px 0;
}
.kb__item.is-on .kb__num,
.kb__item.is-on .kb__name {
  font-size: clamp(19px, 1.5vw, 24px);
  line-height: 1.26;
}
.kb__item.is-on .kb__name {
  margin-top: 0;
  writing-mode: horizontal-tb;
  transform: none;
  white-space: normal;
  font-weight: 700;
  text-align: left;
  color: var(--ink);
}

/* closed the panel is a zero-height, invisible box - visibility, not
   display, so it stays out of the a11y tree and still fades on the way in */
.kb__panel {
  flex: 0 0 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  padding: 0;
  opacity: 0;
  visibility: hidden;
  overflow: hidden;
  transition: opacity .35s ease .12s, visibility .35s;
}
.kb__item.is-on .kb__panel {
  flex: 1 1 auto;
  padding: 0 26px 26px;
  opacity: 1;
  visibility: visible;
}
.kb__txt {
  margin: 14px 0 22px;
  max-width: 46ch;
  font-size: 14.5px;
  line-height: 1.65;
  color: rgba(255,255,255,.62);
}
.kb__media {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  border-radius: 10px;
}
.kb__media img { width: 100%; height: 100%; object-fit: cover; }

/* six 66px strips plus an open panel need a wide column to mean anything -
   below lg it drops to a plain stacked accordion */
@media (max-width: 991.98px) {
  .kb__wrap { grid-template-columns: 1fr; }
  .kb__list { flex-direction: column; min-height: 0; }
  .kb__item { flex: none; min-width: 0; }
  .kb__head,
  .kb__item.is-on .kb__head {
    flex: none;
    flex-direction: row;
    align-items: center;
    gap: 14px;
    padding: 18px 20px;
  }
  .kb__name {
    margin-top: 0;
    writing-mode: horizontal-tb;
    transform: none;
    white-space: normal;
    text-align: left;
  }
  .kb__item.is-on .kb__head { padding-bottom: 0; }
  .kb__item.is-on .kb__panel { padding: 0 20px 20px; }
  .kb__media { flex: none; aspect-ratio: 3 / 2; }
}

/* =========================== HOW TO JOIN ===========================
   Three steps under a centred head. Each art panel is the shared box
   texture with the step art laid over it, and a glow layer sits between
   the two - the step PNGs are transparent around the artwork, so fading
   that layer up on hover reads as a shadow thrown from behind the art. */
.steps {
  position: relative;
  overflow-x: clip;
  padding: clamp(60px, 8vh, 110px) 0 clamp(80px, 11vh, 150px);
}

.steps__head {
  max-width: 760px;
  margin: 0 auto clamp(38px, 5vh, 62px);
  text-align: center;
}
.steps__title { margin-bottom: 16px; }
.steps__lede {
  margin: 0 0 30px;
  font-size: 17px;
  line-height: 1.7;

}

/* this CTA sits under a lede rather than standing alone the way the hero
   button does, so it runs tighter. Scoped, so the hero keeps its size. */


.gbtn__arrow {
  flex: none;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .3s ease;
}
.gbtn:hover .gbtn__arrow { transform: translateX(3px); }

.steps__grid {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 30px);
}

/* the art panel. isolate keeps the glow and the art on their own stack,
   clear of the fixed starfield/particle layers sitting on negative z */
.step__box {
  position: relative;
  isolation: isolate;
  aspect-ratio: 5 / 4;
  margin-bottom: 20px;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: #0c0c0f url("../img/step-box-bg.png") center / cover no-repeat;
}

/* the lit copy of the same panel, held behind the artwork and faded up on
   hover. Both files are 1280x389 and painted center/cover, so their grids
   register exactly and the cross-fade reads as the glow switching on behind
   the art rather than as one picture swapping for another. */
.step__glow {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: url("../img/join-box-hover.png") center / cover no-repeat;
  opacity: 0;
  pointer-events: none;
  transition: opacity .38s ease;
}

/* the PNGs are 1280x389 with the artwork centred, so cover scales them on
   height and crops the empty flanks. The element is held short of the panel
   height and pinned to its foot, which shrinks the art to a little over half
   the panel width and leaves the head room the reference has, while the
   artwork still runs off the bottom edge the way it does in the file. */
.step__box img {
  position: absolute;
  z-index: 2;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 90%;
  object-fit: cover;
}

.step:hover .step__glow { opacity: 1; }

.step__head {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-bottom: 10px;
}
.step__ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  color: var(--accent);
}
.step__ico svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.step__head b {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
}
.step__txt {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.7;
  color: rgba(255,255,255,.62);
}

@media (max-width: 991.98px) { .steps__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 575.98px) {
  .steps__grid { grid-template-columns: 1fr; }
  .step__box { aspect-ratio: 16 / 11; }
}

/* =========================== ACCOUNT TYPES ==========================
   The head stays on the dark page, then a white ground opens under it and
   the cards are pulled back up so they straddle the seam - the top half of
   each card reads against the dark, the bottom against the white. Like
   .plats, the ground carries its own ink tokens instead of flipping the
   globals, and paints over the fixed banner/starfield layers on its own. */
.accs {
  /* how far the cards ride up over the seam. The ground offsets itself by the
     same amount plus the gap under the head, so the two always stay in step. */
  --accs-pull: clamp(130px, 14.5vw, 208px);
  position: relative;
  overflow-x: clip;
  padding-top: clamp(60px, 8vh, 110px);
  /* its own panel rather than the page black, the way .kb sits on one */
  background: #151515;
}

.accs__head {
  max-width: 760px;
  margin: 0 auto;
  text-align: center;
}
.accs__title { margin-bottom: 14px; }
.accs__lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: rgba(255,255,255,.62);
}

/* the chip on this head is a plain pill with a white label, the way the
   reference has it, rather than the outlined accent chip used elsewhere. It
   is lifted off the panel rather than tinted, so it reads on the lighter
   ground. The dot keeps the accent, so it stays the same component. */
.accs .eyebrow {
  border-color: rgba(255,255,255,.13);
  background: rgba(255,255,255,.06);
  color: #fff;
}

.accs__ground {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  /* flow-root, or the grid negative margin collapses straight through and
     drags the white ground up with it instead of lifting the cards off it */
  display: flow-root;
  /* the dark run between head and seam: the lift, plus the room the head
     needs under its lede */
  margin-top: calc(var(--accs-pull) + clamp(46px, 6vw, 70px));
  padding-bottom: clamp(64px, 8.5vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

.accs__grid {
  /* pulled back over the seam, so a card sits about half on the dark panel
     and half on the white ground */
  margin: calc(var(--accs-pull) * -1) auto 0;
  max-width: 1240px;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 1.8vw, 26px);
}

.acc {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 26px 24px 22px;
  border: 1px solid var(--line-d);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 7px 20px rgba(20,21,27,.10);
  transition: box-shadow .3s ease, transform .3s ease;
}
.acc:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 60px rgba(20,21,27,.16);
}

/* the tab in the corner picks up the card radius on the outer side and
   squares off where it meets the card edges */
.acc__tag {
  position: absolute;
  top: 0;
  right: 0;
  padding: 6px 13px;
  border-radius: 0 13px 0 12px;
  background: rgba(20,21,27,.06);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--muted-d);
}
.acc--hot .acc__tag {
  background: rgba(244,129,32,.13);
  color: #b25a08;
}

.acc__name {
  margin: 0 0 14px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink-d);
}
.acc__hero {
  display: flex;
  align-items: baseline;
  gap: 9px;
  margin: 0 0 12px;
}
.acc__hero b {
  font-size: clamp(30px, 2.8vw, 40px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.02em;
}
.acc__hero span {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--muted-d);
}
.acc__sub {
  margin: 0 0 20px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted-d);
}

.acc__list {
  margin: 0 0 22px;
  padding: 20px 0 0;
  border-top: 1px solid var(--line-d);
  list-style: none;
  display: grid;
  gap: 11px;
}
.acc__list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14.5px;
  line-height: 1.5;
 
}
.acc__list svg {
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* the buttons sit at the foot of the card whatever the copy above runs to */
.acc__btn {
  display: block;
  margin-top: auto;
  padding: 12px 18px;
  border: 1px solid var(--line-d);
  border-radius: 999px;
  background: #fff;
  font-size: 14px;
  font-weight: 600;
  text-align: center;
  color: var(--ink-d);
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.acc__btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.acc__btn--solid {
  border-color: var(--accent);
  background: var(--accent);
  color: #000;
}
.acc__btn--solid:hover {
  border-color: var(--accent-hi);
  background: var(--accent-hi);
  color: #000;
}
.acc__more {
  margin-top: 14px;
  font-size: 13.5px;
  font-weight: 600;
  text-align: center;
  color: var(--ink-d);
}
.acc__more:hover { color: var(--accent); }

/* ---- the funding rail ---- */
.fund {
  max-width: 1240px;
  margin: clamp(38px, 5vw, 50px) auto 0;
  padding: clamp(26px, 3vw, 38px) 0 clamp(28px, 3.2vw, 40px);
  border: 1px solid var(--line-d);
  border-radius: 16px;
  background: #f6f7f9;
}

/* The same panel standing on its own rather than closing out .accs. It has
   to hand down the light tokens that block was lending it, and carry the
   ground itself - it lands between two white sections on the about page, so
   the three read as one light block. The top margin belongs to the band
   here, not to the panel, or the two would stack. */
.fundband {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(44px, 6vh, 78px) 0 0;
  background: #fff;
  color: var(--ink-d);
}
.fundband .fund { margin-top: 0; }
.fund__title {
  margin: 0 0 clamp(20px, 2.4vw, 30px);
  font-size: clamp(1.15rem, 2.2vw, 1.6rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-align: center;
}
.fund__title em { font-style: normal; color: var(--accent); }

/* two identical tracks side by side, each sliding a full track width - the
   second takes over exactly where the first leaves, so the row never breaks */
.fund__rail {
  display: flex;
  overflow: hidden;
}
.fund__track {
  flex: none;
  display: flex;
  gap: 14px;
  margin: 0;
  padding: 0 7px;
  list-style: none;
  animation: fundrail 34s linear infinite;
}
.fund__rail:hover .fund__track { animation-play-state: paused; }
@keyframes fundrail { to { transform: translateX(-100%); } }

.fund__chip {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: none;
  padding: 11px 20px;
  border: 1px solid var(--line-d);
  border-radius: 999px;
  background: #fff;
  font-size: 16px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--ink-d);
}
.fund__chip svg {
  flex: none;
  width: 17px;
  height: 17px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 991.98px) {
  .accs { --accs-pull: clamp(96px, 13vw, 130px); }
  .accs__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 575.98px) {
  .accs { --accs-pull: clamp(76px, 18vw, 104px); }
  .accs__grid { grid-template-columns: 1fr; }
  .fund__chip { padding: 10px 16px; font-size: 13.5px; }
}


/* =========================== PLATFORM WALL ==========================
   The second white ground, running straight on from .accs so the two read
   as one light block. The six platform marks already ship as circular
   badges with their own ring, so they carry the row on their own - no
   tile behind them, or the frames would double up. */
.wall {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(50px, 7vh, 96px) 0 clamp(72px, 9.5vh, 140px);
  background: #fff;
  color: var(--ink-d);
}

.wall__head {
  max-width: 800px;
  margin: 0 auto clamp(38px, 5vh, 62px);
  text-align: center;
}
.wall__title { margin-bottom: 14px; }
.wall__lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: var(--muted-d);
}

.wall__grid {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 30px);
}

.brand {
  display: grid;
  justify-items: center;
  gap: 14px;
  text-align: center;
}
.brand img {
  width: clamp(64px, 6.2vw, 90px);
  height: auto;
  transition: transform .3s ease, filter .3s ease;
}
.brand b {
  font-size: 13.5px;
  font-weight: 700;
  line-height: 1.3;
}
.brand:hover img {
  transform: translateY(-5px);
  filter: drop-shadow(0 14px 24px rgba(244,129,32,.30));
}

@media (max-width: 991.98px) { .wall__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 575.98px) { .wall__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ============================== SUPPORT =============================
   Copy on the left, two contact panels on the right, and the dotted map
   behind both. The map PNG is dark-on-transparent, so it only reads on
   the page black - it needs no tint of its own. */
.sup {
  position: relative;
  overflow: hidden;
  padding: clamp(70px, 9vh, 130px) 0 clamp(80px, 11vh, 150px);
}
.sup__map {
  /* a watermark sitting in the middle of the section, not a full bleed -
     the aspect ratio comes from the file, so it never stretches */
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(840px, 64%);
  aspect-ratio: 1280 / 641;
  background: url("../img/world-map.png") center / contain no-repeat;
  pointer-events: none;
}
/* the map is an absolute child, so it would otherwise paint over the
   in-flow content next to it */
.sup .container-xxl { position: relative; z-index: 1; }

.sup__wrap {
  /* the same measure the steps and why grids run on */
  max-width: 1240px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(34px, 5vw, 80px);
  
}

.sup__title { margin-bottom: 22px; }

/* four corner marks drawn as eight thin gradients, so the frame needs no
   markup of its own */
.sup__frame {
  --br: rgba(255,255,255,.34);
  position: relative;
  display: block;
  width: min(330px, 100%);
  margin: 0 0 26px;
  padding: 24px 22px;
  background:
    linear-gradient(var(--br), var(--br))   0    0   / 2px 26px no-repeat,
    linear-gradient(var(--br), var(--br))   0    0   / 26px 2px no-repeat,
    linear-gradient(var(--br), var(--br)) 100%   0   / 2px 26px no-repeat,
    linear-gradient(var(--br), var(--br)) 100%   0   / 26px 2px no-repeat,
    linear-gradient(var(--br), var(--br))   0  100%  / 2px 26px no-repeat,
    linear-gradient(var(--br), var(--br))   0  100%  / 26px 2px no-repeat,
    linear-gradient(var(--br), var(--br)) 100% 100%  / 2px 26px no-repeat,
    linear-gradient(var(--br), var(--br)) 100% 100%  / 26px 2px no-repeat;
}

/* the words are stacked on one another and cycled on a shared keyframe,
   each offset by a quarter of the run */
.sup__rot {
  position: relative;
  display: block;
  height: 1.3em;
  font-size: clamp(1.8rem, 3.4vw, 2.5rem);
  font-weight: 800;
  line-height: 1.3;
  letter-spacing: -.01em;
  color: var(--accent);
}
.sup__rot b {
  position: absolute;
  left: 0;
  top: 0;
  white-space: nowrap;
  opacity: 0;
  animation: supword 12s linear infinite;
}
.sup__rot b:nth-child(2) { animation-delay: 3s; }
.sup__rot b:nth-child(3) { animation-delay: 6s; }
.sup__rot b:nth-child(4) { animation-delay: 9s; }
@keyframes supword {
  /* the tail of one word overlaps the head of the next, so the frame is
     never left empty between them */
  0%       { opacity: 0; transform: translateY(12px); }
  4%, 23%  { opacity: 1; transform: none; }
  27%,100% { opacity: 0; transform: translateY(-12px); }
}

.sup__lede {
  max-width: 42ch;
  margin: 0;
  font-size: 17px;
  line-height: 1.7;
  color: rgba(255,255,255,.62);
}

.sup__cards {
  display: grid;
  gap: clamp(14px, 1.6vw, 22px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.sup__card {
  padding: clamp(22px, 2.4vw, 30px);
  border: 1px solid var(--line);
  border-radius: 18px;
  background: #1b1b1b;
  transition: border-color .25s ease, background .25s ease;
}
.sup__card:hover {
  border-color: rgba(244,129,32,.40);
  background: #212121;
}

.sup__ico {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: clamp(16px, 2vw, 20px);
  border-radius: 50%;
  background: #292929;
  color: #fff;
}
.sup__ico svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sup__name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 700;
}
.sup__live {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 3px 10px;
  border: 1px solid rgba(52,199,123,.30);
  border-radius: 999px;
  background: rgba(52,199,123,.10);
  font-size: 11px;
  font-weight: 500;
  color: #4ad08a;
}
.sup__live i {
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #34c77b;
}
.sup__txt {
  margin: 0 0 16px;
  font-size: 14.5px;
  line-height: 1.6;
  color: rgba(255,255,255,.62);
}

.sup__act {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  font-weight: 600;
  transition: color .25s ease;
}
.sup__act + .sup__act { margin-top: 4px; }
.sup__act svg {
  flex: none;
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transform: rotate(-45deg);
  transition: transform .25s ease;
}
.sup__act:hover { color: var(--accent); }
.sup__act:hover svg { transform: rotate(-45deg) translateX(3px); }

@media (max-width: 991.98px) {
  .sup__wrap { grid-template-columns: 1fr; }
}


/* ============================== MOBILE APP =============================
   The page's last word, on its own light grey rather than the white above
   it - the two sections have to read apart, and grey against white does it
   without another rule across the page.

   No bottom padding: the phones stand on the section's floor, which is what
   the shot was cut for. The copy carries its own instead. */
.mapp {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  position: relative;
  overflow: hidden;
  padding: clamp(52px, 7.5vh, 100px) 0 0;
  background: #f5f5f5;
  color: var(--ink-d);
}

.mapp__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: end;
  gap: clamp(28px, 5vw, 70px);
}

.mapp__copy {
  align-self: center;
  padding-bottom: clamp(52px, 7.5vh, 100px);   /* the floor the section drops */
}
.mapp__title {
  margin: 0 0 16px;
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.02em;
}
.mapp__title em { font-style: normal; color: var(--accent); }
.mapp__lede {
  max-width: 44ch;
  margin: 0 0 clamp(24px, 3vw, 32px);
  font-size: 16.5px;
  line-height: 1.7;
  color: var(--muted-d);
}
.mapp__btn {
  display: inline-flex;
  align-items: center;
  height: 50px;
  padding: 0 32px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 15px;
  font-weight: 700;
  color: #000;
  transition: background .25s ease, transform .25s ease;
}
.mapp__btn:hover { background: var(--accent-hi); transform: translateY(-2px); color: #000; }
.mapp__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

/* the two badges ship as artwork at one ratio, so they are sized on height
   and left to work their own width out */
.mapp__stores {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: clamp(24px, 3vw, 34px) 0 0;
  padding: 0;
  list-style: none;
}
.mapp__stores img {
  width: auto;
  height: clamp(44px, 4vw, 45px);
}

/* Sized off the viewport rather than its column and stood on the floor, so
   the phones run past the right-hand edge and are cut by the section rather
   than shrunk to fit it. */
.mapp__shot {
  margin: 0;
  align-self: end;
}
.mapp__shot img { width: 100%; height: auto; display: block; }

@media (min-width: 992px) {
  .mapp__shot img {
    width: max(100%, 44vw);
    max-width: none;
  }
}

@media (max-width: 991.98px) {
  /* stacked, the shot is last in the column, so the floor is still where it
     lands - only the copy's own padding has to go, or the two are pushed
     apart by a gap meant for a column that is no longer beside it */
  .mapp__in { grid-template-columns: 1fr; gap: 30px; }
  .mapp__copy { padding-bottom: 0; }
  .mapp__lede { max-width: none; }
}
@media (max-width: 575.98px) {
  .mapp__title { font-size: 1.8rem; }
  .mapp__lede { font-size: 15.5px; }
  .mapp__stores img { height: 42px; }
}

/* ================================ FAQ ===============================
   A plain accordion on a light ground: one row open at a time. The panel
   animates on grid rows rather than max-height, so the open height is the
   answer's own and nothing has to be measured. */
.faq {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  /* the ask box picks the ground up from here, so the tail is short */
  padding: clamp(56px, 7.5vh, 100px) 0 clamp(34px, 4.5vh, 56px);
  background: #fff;
  color: var(--ink-d);
}

/* Standing on its own with nothing to hand the white ground on to, it needs
   the floor back that the ask box would otherwise have provided - without
   this the last answer sits a few pixels off the footer. */
.faq--solo { padding-bottom: clamp(56px, 7.5vh, 100px); }

.faq__head {
  max-width: 780px;
  margin: 0 auto clamp(34px, 4.5vh, 56px);
  text-align: center;
}
.faq__title { margin-bottom: 14px; }
.faq__lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: var(--muted-d);
}

/* ---- the page splits its questions into named groups; the home page runs
        one ungrouped list, so this only ever applies where it is used ---- */
.faq__group + .faq__group { margin-top: clamp(46px, 6vh, 78px); }
.faq__gh {
  max-width: 640px;
  margin: 0 auto clamp(20px, 2.6vh, 30px);
  text-align: center;
}
.faq__gt {
  margin: 0 0 8px;
  font-size: clamp(1.45rem, 2.8vw, 1.95rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.01em;
}
.faq__gt em { font-style: normal; color: var(--accent); }
.faq__gp {
  margin: 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted-d);
}

.faq__list {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.faq__item { border-top: 1px solid var(--line-d); }
.faq__item:last-child { border-bottom: 1px solid var(--line-d); }

.faq__q { margin: 0; }
.faq__btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  width: 100%;
  padding: 25px 4px;
  border: 0;
  background: none;
  font-family: var(--font);
  font-size: 16.5px;
  font-weight: 700;
  line-height: 1.45;
  text-align: left;
  color: var(--ink-d);
  cursor: pointer;
  transition: color .25s ease;
}
.faq__btn:hover { color: var(--accent); }
.faq__btn:focus-visible { outline: 0; box-shadow: inset 0 0 0 .2rem var(--bs-focus-ring-color); }
.faq__item.is-on .faq__btn { color: var(--accent); }

/* two bars in a ring - the upright one drops away on open, which turns
   the plus into a minus without swapping any markup */
.faq__sign {
  position: relative;
  flex: none;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line-d);
  border-radius: 50%;
  transition: border-color .25s ease, background .25s ease;
}
.faq__sign::before,
.faq__sign::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 11px;
  height: 1.6px;
  margin: -.8px 0 0 -5.5px;
  border-radius: 2px;
  background: currentColor;
  transition: transform .28s ease, opacity .28s ease;
}
.faq__sign::after { transform: rotate(90deg); }
.faq__item.is-on .faq__sign {
  border-color: var(--accent);
  background: rgba(244,129,32,.10);
}
.faq__item.is-on .faq__sign::after { transform: rotate(0deg); opacity: 0; }

/* 0fr -> 1fr resolves to the row's own content height */
.faq__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .32s ease;
}
.faq__item.is-on .faq__panel { grid-template-rows: 1fr; }
/* the clip has to sit on a wrapper, not on the copy itself: overflow
   clips at the padding edge, so a padding-bottom on the paragraph would
   hold the closed row open by its own height and leak a line of text */
.faq__ans {
  overflow: hidden;
  min-height: 0;
}
.faq__ans p {
  margin: 0;
  padding: 0 44px 24px 4px;
  font-size: 14.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

@media (max-width: 575.98px) {
  .faq__btn { font-size: 14.5px; padding: 19px 2px; gap: 16px; }
  .faq__ans p { padding-right: 4px; }
}

/* ============================== ASK BOX =============================
   Sits on the same white ground the FAQ opens, so the section carries no
   top padding of its own - the box is the whole section. */
.cta {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  position: relative;
  overflow-x: clip;
  padding: 0 0 clamp(72px, 9.5vh, 140px);
  background: #fff;
  color: var(--ink-d);
}

.cta__box {
  max-width: 1240px;
  margin: 0 auto;
  padding: clamp(34px, 4.4vw, 54px) clamp(20px, 4vw, 48px);
  border-radius: 18px;
  background: #f6f6f6;
  text-align: center;
}

/* the three faces overlap, and the middle one is lifted over its
   neighbours rather than left to the painting order */
.cta__faces {
  display: inline-flex;
  align-items: center;
  margin-bottom: 18px;
}
.cta__faces img {
  position: relative;
  z-index: 1;
  width: 52px;
  height: 52px;
  border: 3px solid #fafafa;
  border-radius: 50%;
  object-fit: cover;
}
.cta__faces img + img { margin-left: -15px; }
.cta__faces img:nth-child(2) {
  z-index: 2;
  width: 58px;
  height: 58px;
}

.cta__t {
  margin: 0 0 8px;
  font-size: clamp(18px, 1.8vw, 22px);
  font-weight: 700;
  line-height: 1.3;
}
.cta__p {
  margin: 0 0 24px;
  font-size: 19px;
  line-height: 1.6;
  color: var(--muted-d);
}
.cta__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  padding: 0 30px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 14.5px;
  font-weight: 700;
  color: #000;
  transition: background .25s ease, transform .25s ease;
}
.cta__btn:hover {
  background: var(--accent-hi);
  transform: translateY(-2px);
}

/* =============================== FOOTER ==============================
   Rebuilt on a centre line instead of the old brand-column-plus-five-menu-
   columns grid. Everything stacks down the middle - mark, claim, one rail
   of links, the reach pills - so the eye runs straight down and the last
   thing on the page settles rather than spreading. The link count is the
   point: a rail can only carry what matters, where five columns invited
   twenty-one. True black, so it sits under everything. */
.foot {
  position: relative;
  padding: clamp(54px, 7vh, 92px) 0 0;
  background: #000;
  text-align: center;
}

/* ---- 1. the mark ---- */
.fhead__logo {
  display: inline-block;
  margin-bottom: 26px;
}
.fhead__logo img {
  width: auto;
  height: 48px;
}
.fhead__claim {
  margin: 0 0 16px;
  font-size: clamp(1.65rem, 3.4vw, 2.6rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.02em;
}
.fhead__claim em { font-style: normal; color: var(--accent); }
.fhead__blurb {
  max-width: 68ch;
  margin: 0 auto;
  font-size: 15px;
  line-height: 1.75;
  color: rgba(255,255,255,.55);
}

/* the pair sits with the mark rather than down in the legal bar, so the
   top of the footer carries the brand and the bottom stays fine print */
.fsocial {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}
.fsocial a {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 50%;
  color: rgba(255,255,255,.72);
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.fsocial svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.fsocial a:hover {
  border-color: var(--accent);
  background: rgba(244,129,32,.12);
  color: var(--accent);
}

/* ---- 2. the link rail ----
   One wrapped row, hairline-ruled top and bottom. Seven links is what a
   rail can hold before it reads as a list again, which is the cap doing
   its job: one destination per top-level menu, plus the two company
   pages people actually come here for. */
.frail {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px clamp(22px, 3.2vw, 48px);
  margin-top: clamp(36px, 4.6vh, 56px);
  padding: clamp(22px, 2.8vh, 30px) 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.frail a {
  position: relative;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;
  color: rgba(255,255,255,.74);
  transition: color .25s ease;
}
/* the rule grows from the middle out, to match the centre line the rest
   of the footer is built on */
.frail a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transition: transform .28s ease;
}
.frail a:hover { color: #fff; }
.frail a:hover::after { transform: scaleX(1); }

/* ---- 3. the reach pills ----
   The two numbers and the address ride as pills rather than a stacked
   list: on the centre line a column of three rows would run long and
   pull the footer back into the old shape. */
.freach {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  margin: clamp(30px, 4vh, 44px) 0 0;
  padding: 0;
  list-style: none;
}
.freach li {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 8px 22px 8px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #0b0b0b;
  transition: border-color .25s ease, background .25s ease;
}
.freach li:hover { border-color: rgba(244,129,32,.4); background: #101010; }
.freach__ico {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  background: #262626;
  border-radius: 50%;
  color: #fff;
}
.freach__ico svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.freach__k {
  white-space: nowrap;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(255,255,255,.38);
}
.freach a {
  font-size: 15.5px;
  font-weight: 600;
  transition: color .25s ease;
}
.freach a:hover { color: var(--accent); }

/* ---- 4. the fine print ---- */
.ffine {
  margin-top: clamp(32px, 4.4vh, 48px);
  padding-top: clamp(26px, 3.4vh, 36px);
  border-top: 1px solid var(--line);
}
.fpay {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(20px, 2.6vw, 40px);
  margin: 0 0 clamp(22px, 3vh, 30px);
  padding: 0;
  list-style: none;
}
/* the six marks run from 1.3:1 to 6:1, so they are matched by eye rather
   than on one height - a single height would leave Neteller running half
   the row and Mastercard the size of a stamp. The files are already the
   one grey, so nothing is filtered here. */
.fpay img { width: auto; }
.fpay li:nth-child(1) img { height: 24px; }   /* Visa       */
.fpay li:nth-child(2) img { height: 34px; }   /* Mastercard */
.fpay li:nth-child(3) img { height: 20px; }   /* PayPal     */
.fpay li:nth-child(4) img { height: 14px; }   /* Neteller   */
.fpay li:nth-child(5) img { height: 22px; }   /* Skrill     */
.fpay li:nth-child(6) img { height: 26px; }   /* Apple Pay  */

.foot__risk {
  max-width: 110ch;
  margin: 0 auto;
  font-size: 14.5px;
  line-height: 1.65;
  color: rgba(255,255,255,.34);
}
.foot__risk b { font-weight: 700; color: rgba(255,255,255,.52); }

/* ---- 5. the legal tail ----
   The only row that breaks the centre line: copyright one side, the three
   legal links the other, so the footer closes on a base rather than a
   fourth centred stack. */
.foot__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px clamp(20px, 3vw, 46px);
  margin-top: clamp(26px, 3.4vh, 36px);
  padding: 20px 0 26px;
  border-top: 1px solid var(--line);
  text-align: left;
}
.foot__copy {
  margin: 0;
  font-size: 14.5px;
  color: rgba(255,255,255,.42);
}
.foot__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 8px clamp(16px, 2vw, 28px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.foot__legal a {
  font-size: 14.5px;
  color: rgba(255,255,255,.42);
  transition: color .25s ease;
}
.foot__legal a:hover { color: var(--accent); }

@media (max-width: 767.98px) {
  .frail { gap: 12px 24px; }
  .freach { gap: 12px; }
  .freach li { padding: 7px 18px 7px 7px; }
  .fpay { gap: 18px 26px; }
}
@media (max-width: 575.98px) {
  .foot { padding-top: 46px; }
  .fhead__logo img { height: 40px; }
  .fhead__blurb { font-size: 14.5px; }
  .frail a { font-size: 14.5px; }
  /* the pill turns into a labelled row on a phone: side by side, the US
     label and its number both wrap mid-word inside 360px */
  .freach li {
    display: grid;
    width: 100%;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas: "ico k" "ico v";
    align-items: center;
    column-gap: 12px;
    row-gap: 1px;
    padding: 10px 18px 10px 10px;
    border-radius: 16px;
    text-align: left;
  }
  .freach__ico { grid-area: ico; }
  .freach__k { grid-area: k; }
  .freach a  { grid-area: v; }
  .foot__bar { justify-content: center; text-align: center; }
  .foot__legal { justify-content: center; width: 100%; }
}




/* ============================== PAGE BANNER ============================
   The short banner the inner product pages open on - a name and one line
   over the backdrop, nothing else. Like .ahero it runs to the very top edge
   under the fixed bar and carries its own clearance rather than using .page.

   The backdrop is a variable so a page can swap the art without touching
   the layers on it, and --phero-h is here for the same reason: a page with
   a longer name needs the room, one with a short one should not have to
   carry it. */
.phero {
  --phero-img: url("../img/Hero-banner.png");
  --phero-h: clamp(330px, 44vh, 520px);
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: var(--phero-h);
  padding: calc(var(--nav-h) + clamp(16px, 2.4vh, 32px)) 0 clamp(20px, 3.2vh, 38px);
  /* the art's own black, so nothing shows a joint where the two meet */
  background: #000;
}
/* Edge to edge. The art is 2.21:1 and a desktop banner is wider than that, so
   a cover crop trims the top and bottom, and the shorter the band the more of
   the frame goes - which the shallow --phero-h above spends deliberately: the
   copy is two lines, so the room a taller band bought was dead space under it.
   The pattern is abstract, so what the crop takes costs nothing; a subject
   would need the other treatment.

   Pinned right, not centred. Narrow of about 2.21:1 - which every phone is -
   the crop turns horizontal instead, and everything worth seeing in this
   frame lives on its right-hand side: centred, a phone shows the empty middle
   and throws the whole shape away. */
.phero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--phero-img) right center / cover no-repeat;
}
/* holds the left-hand side down under the copy - struck in the art's own
   black so it darkens without tinting */
.phero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to right, rgba(0,0,0,.85) 0%, rgba(0,0,0,.45) 34%, transparent 62%);
}
.phero > .container-xxl {
  position: relative;
  z-index: 2;
  width: 100%;
}

/* the Core Modules pages take the third banner - same 2560x1157 frame and
   the same shape pinned to its right, so the crop and the gradient above
   carry over untouched and only the art changes */
.phero--mod { --phero-img: url("../img/Hero-banner-3.png"); }

.phero__in { max-width: 720px; }
.phero__title {
  margin: 0 0 14px;
  font-size: clamp(2.2rem, 5.4vw, 3.8rem);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.03em;
}
.phero__title em { font-style: normal; color: var(--accent); }
.phero__p {
  max-width: 56ch;
  margin: 0;
  font-size: clamp(15px, 1.5vw, 17px);
  line-height: 1.7;
  color: rgba(255,255,255,.68);
}

@media (max-width: 575.98px) {
  .phero {
    --phero-h: 230px;
    padding-top: calc(var(--nav-h) + 14px);
  }
  .phero__title { font-size: 1.9rem; }
  /* Still sideways, and lighter. The copy sits left and the shape sits right,
     so darkening the whole band by the same amount - which a top-to-bottom
     ramp does - buys the text nothing and costs the art everything. This
     holds the reading side down and lets the far edge come through. */
  .phero::after {
    background: linear-gradient(to right, rgba(0,0,0,.88) 0%, rgba(0,0,0,.6) 58%, rgba(0,0,0,.18) 100%);
  }
}


/* ========================= ADMIN: WHAT IT DOES ========================
   The claim on the left, the list on the right, and the left half stays put
   while the right runs past it - the heading is what every card underneath
   is an answer to, so it should still be on screen when the last one goes by.

   Like every light section it carries its own ink tokens rather than
   flipping the globals, so the banner above and the footer below stay dark. */
.aops {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(56px, 8vh, 110px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

/* no measure of its own - it takes the container, so the two halves line up
   on the same edges as the bar above and every other section */
.aops__in {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  align-items: start;
  gap: clamp(30px, 5vw, 80px);
}

/* it sticks below the fixed bar, not to the viewport's own top edge - the
   bar would otherwise sit over the heading it is holding in place */
.aops__side {
  position: sticky;
  top: calc(var(--nav-h) + clamp(20px, 4vh, 44px));
}
.aops__title {
  margin: 0 0 18px;
  font-size: clamp(2.1rem, 4.2vw, 3.1rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -.02em;
}
.aops__title em { font-style: normal; color: var(--accent); }
.aops__lede {
  max-width: 40ch;
  margin: 0;
  font-size: 17.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

/* ---- the rail ----
   One line down the gutter with a dot per card. The gutter, the dot and the
   card's own padding are the three measures everything else is worked out
   from - the dot lands on the title's line because it is placed off the same
   padding the title is, not off a number that has to be kept in step by hand. */
.aops__list {
  --rail: clamp(36px, 4.2vw, 62px);
  --dot: 20px;
  --pad: clamp(26px, 3vw, 40px);
  position: relative;
  margin: 0;
  padding: 0 0 0 var(--rail);
  list-style: none;
  display: grid;
  gap: clamp(24px, 3.4vw, 42px);
}
/* it starts on the first dot's centre and stops inside the last card, so it
   reads as joining them rather than running off the section */
.aops__list::before {
  content: "";
  position: absolute;
  top: calc(var(--pad) + var(--dot) / 2);
  bottom: calc(var(--pad) + var(--dot) / 2);
  left: calc(var(--rail) / 2 - 1px);
  width: 2px;
  background: var(--line-d);
}

.aops__item {
  position: relative;
  padding: var(--pad);
  border: 1px solid rgba(20,21,27,.10);
  border-radius: 18px;
  background: #f6f7f9;
  transition: border-color .25s ease, transform .25s ease;
}
.aops__item:hover {
  border-color: rgba(244,129,32,.45);
  transform: translateX(3px);
}
/* the card's own left edge is one --rail in from the list, so the line's
   centre sits at minus half of it */
.aops__item::before {
  content: "";
  position: absolute;
  top: calc(var(--pad) + 4px);
  left: calc(-1 * var(--rail) / 2 - var(--dot) / 2);
  width: var(--dot);
  height: var(--dot);
  border: 2px solid var(--line-d);
  border-radius: 50%;
  background: #fff;
  transition: border-color .25s ease, background .25s ease;
}
.aops__item:hover::before {
  border-color: var(--accent);
  background: var(--accent);
}

.aops__item h3 {
  margin: 0 0 13px;
  font-size: clamp(18.5px, 1.7vw, 21px);
  font-weight: 700;
  line-height: 1.28;
  letter-spacing: -.01em;
}
.aops__item p {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

@media (max-width: 991.98px) {
  /* stacked, there is nothing beside the list for the heading to stay level
     with, so it stops sticking and just sits above it */
  .aops__in { grid-template-columns: 1fr; gap: 32px; }
  .aops__side { position: static; }
  .aops__lede { max-width: none; }
}
@media (max-width: 575.98px) {
  .aops__title { font-size: 1.9rem; }
  .aops__lede { font-size: 16px; }
  .aops__item p { font-size: 15.5px; }
  /* the rail costs more than it gives once the cards are the full width */
  .aops__list { --rail: 0px; }
  .aops__list::before,
  .aops__item::before { display: none; }
}

/* ======================= TRADING PLATFORMS: BANNER ======================
   The page's own banner. Like .ahero it runs to the very top edge under the
   fixed bar and carries its own clearance rather than using .page - but the
   art here is a flat backdrop rather than a photo, so it needs no knocking
   back, only a floor gradient to sit the copy on.

   Claim on the left, the platform hub on the right. The backdrop's own glow
   falls on the right-hand side, which is where the hub lands - the two were
   made to be stacked in that order. */
.thero {
  /* the backdrop is per-page: the modifier below swaps it without touching
     the layers that sit on it */
  --thero-img: url("../img/Hero-banner-2.png");
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  min-height: 78vh;
  min-height: 78dvh;
  padding: calc(var(--nav-h) + clamp(34px, 6vh, 84px)) 0 clamp(40px, 6vh, 90px);
  background: #060607;
}
.thero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--thero-img) center right / cover no-repeat;
}
/* Some shots bring their own glow. Where one does, the backdrop's would only
   sit a second light behind it - and a warm shot over a red backdrop reads as
   two brands rather than one. The modifier drops it and leaves the ground. */
.thero--plain { --thero-img: none; }
/* the copy sits over the darkest part of the art, but the art is a photograph
   of light rather than a flat - this keeps the left edge dependable */
.thero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to right, rgba(6,6,7,.78) 0%, rgba(6,6,7,.42) 42%, transparent 78%);
}
/* no shell of its own - the banner lines its copy up on the same two edges
   as the bar above it and every section below */
.thero > .container-xxl {
  position: relative;
  z-index: 2;
  width: 100%;
}

.thero__in {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 72px);
}

/* No measure of its own - it fills the column, so the rails inside it reach
   all the way to the terminal. The copy that does need holding in sets its
   own width below. */
.thero__copy { min-width: 0; }
.thero__title {
  margin: 0 0 16px;
  font-size: clamp(2.2rem, 5.4vw, 3.8rem);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.03em;
}
.thero__title em { font-style: normal; color: var(--accent); }
.thero__p {
  max-width: 52ch;
  margin: 0 0 clamp(26px, 3.4vw, 38px);
  font-size: 16px;
  line-height: 1.75;
  color: rgba(255,255,255,.68);
}

/* ---- the two running rails ----
   What the integrations actually do, as labels rather than a list. Each rail
   holds identical tracks side by side, each sliding a full track width, so
   the next takes over exactly where the last leaves and the row never breaks.
   The rails run opposite ways, which is what stops the pair reading as one
   block sliding sideways.

   They take the whole column and then the gap after it, so a chip is cut off
   at the headline's left edge on one side and at the terminal on the other -
   they run up to the shot, never across it. The rail's own overflow is the
   crop. */
.thero__rails {
  display: grid;
  gap: 12px;
  margin-bottom: clamp(28px, 3.6vw, 40px);
}
/* A chip does not start or stop at an edge, it dissolves into the ground on
   the way to one - both ends, or the rail reads as a box with things sliding
   in and out of it rather than as type drifting across the banner. The mask
   is the crop at either end; overflow only catches whatever is left past it. */
.thero__rail {
  --fade: clamp(90px, 12vw, 220px);
  display: flex;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right,
              transparent 0,
              #000 var(--fade),
              #000 calc(100% - var(--fade)),
              transparent 100%);
          mask-image: linear-gradient(to right,
              transparent 0,
              #000 var(--fade),
              #000 calc(100% - var(--fade)),
              transparent 100%);
}
.thero__track {
  flex: none;
  display: flex;
  gap: 12px;
  margin: 0;
  padding: 0 6px;
  list-style: none;
  animation: therorun 26s linear infinite;
}
/* the second rail travels the other way - same keyframes read backwards, so
   the two never need separate timing to stay out of step */
.thero__rail--back .thero__track { animation-direction: reverse; }
.thero__rails:hover .thero__track { animation-play-state: paused; }
@keyframes therorun { to { transform: translateX(-100%); } }

.thero__chip {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 10px 20px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  color: rgba(255,255,255,.9);
}
.thero__chip svg {
  flex: none;
  width: 15px;
  height: 15px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.thero__btns { display: flex; flex-wrap: wrap; gap: 12px; }
.thero__btn {
  display: inline-flex;
  align-items: center;
  height: 46px;
  padding: 0 26px;
  border: 1px solid #424242;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.thero__btn:hover { border-color: var(--accent); color: var(--accent); }
.thero__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.thero__btn--solid { border-color: var(--accent); background: var(--accent); color: #000; }
.thero__btn--solid:hover { border-color: var(--accent-hi); background: var(--accent-hi); color: #000; }

/* ---- the terminal ----
   It stands on the banner's floor at every width: bottom of the row, then
   the section's own bottom padding cancelled underneath, so the shot runs
   right down to the edge with nothing between it and the section below.
   Stacked on a phone it is the last thing in the column, so that lands it
   on the floor there too. The section's overflow is the crop. */
.thero__art {
  margin: 0 0 calc(-1 * clamp(40px, 6vh, 90px));   /* the section's own floor */
  align-self: end;
}
.thero__art img { width: 100%; height: auto; }

@media (min-width: 992px) {
  /* off the column and off the page: sized from the viewport, not the track,
     so the terminal stays big enough to read at any screen size */
  .thero__art img {
    width: max(100%, 52vw);
    max-width: none;
  }

  /* The rails reach past their own column: first the grid gap, then the band
     of dark ground the shot carries before the laptop appears - a little
     under a fifth of its 52vw, so 9vw of the 9.7vw that measures. Without it
     a chip is cut a hand's width short of the terminal, with a stripe of
     nothing between the two. */
  .thero__rails {
    margin-right: calc(-1 * clamp(28px, 5vw, 72px) - 9vw);
  }
}

@media (max-width: 991.98px) {
  /* stacked, the banner stops holding a viewport - it is as tall as the two
     halves need, with the terminal under the claim that names it */
  .thero {
    min-height: 0;
    padding-top: calc(var(--nav-h) + 30px);
  }
  .thero__in { grid-template-columns: 1fr; gap: 34px; }
  /* the sideways gradient was holding a left-hand column that no longer
     exists - over a full-width stack it has to come down the page instead */
  .thero::after {
    background: linear-gradient(to bottom, rgba(6,6,7,.72) 0%, rgba(6,6,7,.38) 55%, rgba(6,6,7,.66) 100%);
  }
}
@media (max-width: 575.98px) {
  .thero__title { font-size: 2rem; }
  .thero__p { font-size: 15px; }
  .thero__chip { padding: 9px 16px; font-size: 13.5px; }
  .thero__btns .thero__btn { flex: 1 1 auto; justify-content: center; }
}




/* ==================== PAYMENT GATEWAYS: THE METHODS ====================
   A card per rail on white. Each opens on a plate - a tile a shade up from
   the card, holding either the provider marks that method actually carries
   or, where it has no brand of its own, a glyph struck at the same weight.
   The plate is a fixed height so the six titles land on one baseline
   whatever is standing in it.

   Like .plats and .wall the section carries its own ink tokens rather than
   flipping the globals, so the banner above and the footer below stay dark. */
.pmeth {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(56px, 8vh, 110px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

.pmeth__head {
  max-width: 820px;
  margin: 0 auto clamp(32px, 4.5vh, 56px);
  text-align: center;
}
.pmeth__title {
  margin: 0 0 15px;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.01em;
}
.pmeth__title em { font-style: normal; color: var(--accent); }
.pmeth__lede {
  max-width: 62ch;
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.75;
  color: var(--muted-d);
}

.pmeth__grid {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 1.8vw, 24px);
}

.pmeth__card {
  display: flex;
  flex-direction: column;
  padding: clamp(20px, 2.2vw, 26px);
  border: 1px solid rgba(20,21,27,.10);
  border-radius: 18px;
  background: #f6f7f9;
  transition: border-color .25s ease, transform .25s ease;
}
.pmeth__card:hover {
  border-color: rgba(244,129,32,.45);
  transform: translateY(-3px);
}

/* ---- the plate ---- */
.pmeth__plate {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: clamp(16px, 2vw, 26px);
  height: 104px;
  margin-bottom: clamp(20px, 2.2vw, 26px);
  padding: 0 18px;
  border: 1px solid rgba(20,21,27,.07);
  border-radius: 12px;
  background: #fff;
}

/* the marks are drawn at #828282 on 0.7, which is already the muted-logo
   treatment - nothing is done to them here beyond an optical height each,
   the way the footer sizes the same six */
.pmeth__logo { width: auto; }
.pmeth__logo--visa     { height: 27px; }
.pmeth__logo--mc       { height: 38px; }
.pmeth__logo--apple    { height: 29px; }
.pmeth__logo--paypal   { height: 23px; }
.pmeth__logo--skrill   { height: 25px; }
.pmeth__logo--neteller { height: 16px; }

/* struck at the weight of the marks beside it rather than as an icon: this
   is standing in for a logo, so it has to carry the plate on its own */
.pmeth__glyph {
  width: 42px;
  height: 42px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pmeth__card h3 {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.pmeth__card p {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--muted-d);
}

@media (max-width: 991.98px) {
  .pmeth__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 575.98px) {
  .pmeth__title { font-size: 1.7rem; }
  .pmeth__lede { font-size: 15px; }
  .pmeth__grid { grid-template-columns: 1fr; }
  /* stacked there is nothing beside a card to line its title up with, so the
     plate can come down to what its own contents need */
  .pmeth__plate { height: 88px; gap: 16px; }
  .pmeth__card p { font-size: 14.5px; }
}


/* ==================== PAYMENTS: THE RAILS, AS ROWS =====================
   What .pmeth was on the payments page, rebuilt as a list. Its own block
   rather than a modifier because the KYC page still runs .pmeth as cards
   and the two share nothing but a heading shape.

   Rows because the page already carries three card grids below this one,
   and a fourth turned the whole thing into one long field of tiles. They
   also give the marks somewhere to be big: at a third of a row the six
   logos were shrinking to fit their plate, which is the one thing a
   payments page cannot afford to do to them.

   Three tracks - plate, copy, attributes. The attributes are right-aligned
   so they form a column of their own down the section, which is what lets
   somebody scan for "instant" without reading six paragraphs first.

   One kind of mark in the plates, not two. Brand logos in some rows and a
   line glyph in the rest gave six plates that were each a different weight,
   colour and density, and a column of those does not read as a set. The
   glyph is the one thing all six methods can carry, so the logos move out
   to their own strip under the list, where they are all together and can
   be the same size as each other. */
.prail {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(56px, 8vh, 110px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

/* left, like every other head on this page - the centred version belonged
   to a grid that was itself centred */
.prail__head {
  max-width: 760px;
  margin: 0 0 clamp(28px, 3.6vh, 46px);
}
.prail__title {
  margin: 0 0 15px;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.01em;
}
.prail__title em { font-style: normal; color: var(--accent); }
.prail__lede {
  max-width: 62ch;
  margin: 0;
  font-size: 16px;
  line-height: 1.75;
  color: var(--muted-d);
}

.prail__rows {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line-d);
}
.prail__row {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr) minmax(0, 268px);
  align-items: center;
  gap: clamp(20px, 3vw, 46px);
  padding: clamp(20px, 2.3vw, 28px) clamp(10px, 1.4vw, 20px);
  border-bottom: 1px solid var(--line-d);
  transition: background .25s ease;
}
.prail__row:hover { background: #f7f8fa; }

/* inverted from the card version: the section is white, so the tile holding
   the mark is the grey one. Square, because it holds one glyph now rather
   than a row of logos - the old 232px letterbox left a single icon adrift
   in the middle of a lot of nothing. */
.prail__plate {
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border: 1px solid rgba(20,21,27,.09);
  border-radius: 16px;
  background: #f6f7f9;
  transition: border-color .25s ease, background .25s ease;
}
.prail__row:hover .prail__plate {
  border-color: rgba(244,129,32,.42);
  background: #fff;
}

/* files rather than sprite symbols: these are drawn solid and two-tone, and
   a <use> of the site's line set could not carry that. They are decorative,
   so each <img> is alt="" and the row's own heading names the method. */
.prail__ico {
  width: 46px;
  height: 46px;
}

/* ---- the brand strip ----
   All six marks together under the list, sized against each other rather
   than against whatever else was in their plate. They arrive at #828282 on
   0.7, which is already the muted-logo treatment, so nothing is done to
   them here beyond an optical height each - the way the footer sizes the
   same six. */
.prail__marks {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(20px, 3vw, 46px);
  padding: clamp(26px, 3.2vw, 40px) clamp(10px, 1.4vw, 20px) 0;
}
.prail__marks p {
  flex: none;
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-d);
}
.prail__marks ul {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: clamp(22px, 3.4vw, 50px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.prail__logo { width: auto; }
.prail__logo--visa     { height: 30px; }
.prail__logo--mc       { height: 42px; }
.prail__logo--apple    { height: 32px; }
.prail__logo--paypal   { height: 26px; }
.prail__logo--skrill   { height: 28px; }
.prail__logo--neteller { height: 18px; }

.prail__body h3 {
  margin: 0 0 9px;
  font-size: clamp(1.1rem, 1.7vw, 1.32rem);
  font-weight: 700;
  letter-spacing: -.01em;
}
.prail__body p {
  margin: 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--muted-d);
}

.prail__tags {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.prail__tags li {
  padding: 5px 13px;
  border: 1px solid var(--line-d);
  border-radius: 999px;
  background: #fff;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  color: var(--muted-d);
}

@media (max-width: 1199.98px) {
  /* the third track goes first: a 268px column of chips beside a paragraph
     leaves the paragraph too narrow to be worth setting */
  .prail__row { grid-template-columns: 96px minmax(0, 1fr); }
  .prail__tags { grid-column: 1 / -1; justify-content: flex-start; }
}
@media (max-width: 767.98px) {
  /* the plate stays beside the copy rather than stacking above it - at this
     width a 96px square is small enough to sit in the margin, and stacking
     would give every row a lot of height for one icon */
  .prail__row { gap: 20px 22px; }
  .prail__plate { width: 84px; height: 84px; }
  .prail__ico { width: 40px; height: 40px; }
  .prail__marks { flex-direction: column; align-items: flex-start; gap: 20px; }
}
@media (max-width: 575.98px) {
  .prail__title { font-size: 1.7rem; }
  .prail__lede { font-size: 15px; }
  .prail__plate { width: 72px; height: 72px; border-radius: 14px; }
  .prail__ico { width: 34px; height: 34px; }
  .prail__row { grid-template-columns: 72px minmax(0, 1fr); gap: 16px 18px; }
  .prail__body p { font-size: 14.5px; }
  .prail__tags li { font-size: 12px; padding: 4px 11px; }
  .prail__marks ul { gap: 20px 26px; }
}

/* ==================== TRADING PLATFORMS: THE LAYER =====================
   Dark, between the two white blocks. It needs no ink tokens of its own -
   it is back on the site's own ground, and the sections either side scope
   their light ones rather than flipping the globals. */
.tlayer {
  position: relative;
  overflow-x: clip;
  padding: clamp(60px, 8.5vh, 115px) 0 clamp(64px, 9vh, 120px);
  background: var(--bg);
}

.tlayer__head {
  max-width: 820px;
  margin: 0 auto clamp(34px, 4.5vh, 58px);
  text-align: center;
}
.tlayer__title {
  margin: 0 0 15px;
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.01em;
}
.tlayer__title em { font-style: normal; color: var(--accent); }
.tlayer__lede {
  max-width: 60ch;
  margin: 0 auto;
  font-size: 16px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

.tlayer__grid {
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}
.tlayer__card {
  padding: clamp(24px, 2.6vw, 34px);
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #0f0f0f;
  transition: border-color .25s ease, transform .25s ease;
}
.tlayer__card:hover {
  border-color: rgba(244,129,32,.45);
  transform: translateY(-3px);
}

/* The glyph sits in a rounded tile a shade up from the card, with a hairline
   round it - the same square the card is, one size down, so the two read as
   one object rather than a mark dropped on a panel. It takes the accent with
   the card on hover, which is what stops the tile being a static frame. */
.tlayer__ico {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin-bottom: clamp(22px, 3vw, 34px);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(255,255,255,.04);
  transition: border-color .25s ease, background .25s ease;
}
.tlayer__card:hover .tlayer__ico {
  border-color: rgba(244,129,32,.45);
  background: rgba(244,129,32,.12);
}
.tlayer__ico svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tlayer__card h3 {
  margin: 0 0 10px;
  font-size: 17.5px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.tlayer__card p {
  margin: 0;
  font-size: 15px;
  line-height: 1.72;
  color: rgba(255,255,255,.62);
}

@media (max-width: 991.98px) {
  .tlayer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 575.98px) {
  .tlayer__title { font-size: 1.7rem; }
  .tlayer__lede { font-size: 15px; }
  .tlayer__grid { grid-template-columns: 1fr; }
  .tlayer__card p { font-size: 14.5px; }
  /* the gap under the glyph was holding three cards to one baseline; stacked
     there is nothing beside it to line up with */
  .tlayer__ico { margin-bottom: 16px; }
}

/* ===================== TRADING PLATFORMS: WHAT IT BUYS ==================
   White again after the dark layer above it, which means it opens on a
   colour change rather than continuing a run - so it carries a full top
   padding of its own; without one the heading would sit on the seam.

   A statement beside the hub, then the four things it comes down to. The
   statement runs at reading size rather than as a headline: the sections
   above have already made the claim, this one explains it. */
.tfeat {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.12);
  position: relative;
  overflow-x: clip;
  padding: clamp(60px, 8.5vh, 115px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

.tfeat__top {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 76px);
  margin-bottom: clamp(34px, 5vh, 62px);
}
.tfeat__copy { min-width: 0; }
.tfeat__title {
  margin: 0 0 16px;
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -.01em;
}
.tfeat__title em { font-style: normal; color: var(--accent); }
.tfeat__lead {
  max-width: 46ch;
  margin: 0;
  font-size: clamp(16px, 1.5vw, 18px);
  line-height: 1.72;
  color: var(--muted-d);
}

/* No panel behind it: the hub is cut out on transparency and its own discs
   are light, so it carries itself on the white - a tile would only put a
   second edge round artwork that already has one. */
.tfeat__art {
  margin: 0;
  display: grid;
  place-items: center;
}
.tfeat__art img {
  width: 100%;
  max-width: clamp(300px, 31vw, 440px);
  height: auto;
}

.tfeat__grid {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}
.tfeat__card {
  padding: clamp(22px, 2.4vw, 30px);
  border-radius: 16px;
  background: #f6f7f9;
}

/* a hairline ring round the glyph rather than a filled disc - on this ground
   a solid tile would weigh more than the title under it */
.tfeat__ico {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: clamp(30px, 4vw, 56px);
  border: 1px solid rgba(20,21,27,.18);
  border-radius: 50%;
}
.tfeat__ico svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: var(--ink-d);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.tfeat__card h3 {
  margin: 0 0 8px;
  font-size: 16.5px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.tfeat__card p {
  margin: 0;
  font-size: 15px;
  line-height: 1.62;
  color: var(--muted-d);
}

@media (max-width: 1199.98px) {
  .tfeat__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767.98px) {
  .tfeat__top { grid-template-columns: 1fr; gap: 26px; }
  .tfeat__lead { max-width: none; }
  /* the gap under the glyph is desktop breathing room - it was holding four
     cards to one baseline, and stacked there is nothing to line up with */
  .tfeat__ico { margin-bottom: 18px; }
}
@media (max-width: 575.98px) {
  .tfeat__grid { grid-template-columns: 1fr; }
  .tfeat__title { font-size: 1.55rem; }
  .tfeat__lead { font-size: 15.5px; }
}

/* ============================= ABOUT HERO ============================
   The page's own banner: the skyline runs to the very top edge, under the
   fixed bar, with the section carrying its own clearance instead of .page.
   Two gradients knock the photo back - one across, so the copy has a dark
   side to sit on, one down, so the stats row keeps its footing. */
.ahero {
  /* the photo and how hard it is knocked back are both per-page: the
     modifier below swaps them without touching the layers */
  --ahero-img: url("../img/about.jpg");
  --ahero-dim: .48;
  position: relative;
  overflow: hidden;
  /* the banner holds the viewport whatever the copy runs to */
  min-height: 80vh;
  min-height: 80dvh;
  display: flex;
  padding: calc(var(--nav-h) + clamp(42px, 8.5vh, 110px)) 0 clamp(30px, 5vh, 56px);
  background: #060607;
}

/* The photo is warm daylight, so it is carried on its own layer and stripped
   of colour there - a filter on .ahero itself would take the copy with it. */
.ahero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ahero-img) center / cover no-repeat;
  filter: grayscale(1) brightness(var(--ahero-dim)) contrast(1.08);
}

/* ---- about: the banner is a clip, not a still ----
   The video is carried on the same layer as the photo and painted over it,
   so about.jpg stays underneath as the poster and as the fallback if the
   clip never arrives. Unlike the photos it is left alone - no grey, no
   knock-back - so the clip plays as it was graded. The two gradients over
   the top still give the copy its dark side to sit on. */
.ahero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
}

/* the still underneath stands in for the clip, so it is left alone too -
   otherwise the fallback would read as a different banner */
.ahero--video::before { filter: none; }

/* two gradients over the photo: one across, so the copy has a dark side to
   sit on, one down, so the stats row keeps its footing */
.ahero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
  linear-gradient(to right, rgba(6, 6, 7, 0.37) 0%, rgba(6, 6, 7, 0.17) 46%, rgba(6,6,7,.24) 100%), linear-gradient(to bottom, rgba(6, 6, 7, 0.46) 0%, rgba(6,6,7,.12) 38%, rgba(6, 6, 7, 0.41) 100%)
}

/* The clip carries no knock-back of its own, so the floor of the banner does
   that work instead: a shadow climbing from the bottom edge, run to solid at
   the seam. It starts its climb around two-thirds down so the banner hands
   over to the figures strip below as one dark block, rather than a bright
   frame of video cut off mid-shot. */
.ahero--video::after {
  background:
    linear-gradient(to right, rgba(6,6,7,.66) 0%, rgba(6,6,7,.43) 46%, rgba(6,6,7,.24) 100%),
    linear-gradient(to bottom, rgba(6,6,7,.56) 0%, rgba(6,6,7,.10) 30%, rgba(6,6,7,.50) 62%, rgba(6,6,7,.80) 82%, rgba(6,6,7,.94) 93%, #060607 100%);
}

/* copy to the top, stats to the floor, and the gap between them takes
   whatever height is left over */
.ahero > .container-xxl {
  position: relative;
  z-index: 3;
  width: 100%;
  /* narrower than the site shell - the copy sits alone on the photo here,
     and the full 1472px let the headline drift away from the left edge the
     gradient is holding. The word stays hung off the viewport. */
  max-width: 1240px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

/* With the figures moved out to their own strip, the copy is the only thing
   left in the banner - space-between would pin it to the ceiling and leave
   the whole floor empty, so it sits on the centre line instead. */
.ahero--video > .container-xxl { justify-content: center; }

/* the word sits over the skyline but under the copy, hung off the right
   edge of the viewport rather than centred */
.ahero__word {
  position: absolute;
  right: 0;
  bottom: clamp(78px, 15vh, 180px);
  z-index: 2;
  font-size: clamp(5rem, 17vw, 15rem);
  font-weight: 800;
  line-height: .8;
  letter-spacing: .03em;
  white-space: nowrap;
  color: rgba(255,255,255,.11);
  pointer-events: none;
  user-select: none;
  /* it breathes rather than sits still - opacity, so the pulse stays on the
     compositor and never repaints the text */
  animation: aboutpulse 4.2s ease-in-out infinite;
}

@keyframes aboutpulse {
  0%, 100% { opacity: .40; }
  50%      { opacity: .70; }
}

/* the contact shot is a window-lit office, several stops brighter than the
   skyline - at .48 the glass behind the desk washes the headline out */
.ahero--contact {
  --ahero-img: url("../img/contact.jpg");
  --ahero-dim: .32;
}

/* brighter again: this one has a blown-out window running down its left
   side, which is exactly where the headline sits. The across gradient is
   already at .66 there, but it is knocking back a near-white, so the photo
   layer has to come down further before the two of them are enough. */
.ahero--wl {
  --ahero-img: url("../img/white-label-forex-crm.jpg");
  --ahero-dim: .28;
}

/* ---- the rest of the product banners ----
   Not guessed. Each dim is set from the mean luminance of the left 45% of
   its own photo - the half the headline sits on - held so that luma x dim
   lands near 42, which is where the contact and white-label banners already
   sit and read cleanly. A brighter photo therefore gets a lower number;
   cfd, the darkest of the five, needs the least help. */
.ahero--platform {
  --ahero-img: url("../img/trading-platform.jpg");
  --ahero-dim: .29;
}
.ahero--cfd {
  --ahero-img: url("../img/cfd-brokerage-solution.jpg");
  --ahero-dim: .37;
}
.ahero--exchange {
  --ahero-img: url("../img/exchange-solution.jpg");
  --ahero-dim: .21;
}
.ahero--custom {
  --ahero-img: url("../img/custom-crm.jpg");
  --ahero-dim: .25;
}
.ahero--register {
  --ahero-img: url("../img/register-your-company.jpg");
  --ahero-dim: .28;
}

.ahero__in {
  position: relative;
  max-width: 760px;
}
/* the kicker over the headline. A span, not a p - it is a label, and the
   14.5px floor the body copy runs to would leave it competing with the
   paragraph underneath instead of introducing the title. */
.ahero__k {
  display: block;
  margin: 0 0 16px;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: .40em;
  text-transform: uppercase;
  color: var(--accent);
}
.ahero__title {
  /* broken over two lines from the markup, so it can run large */
  margin: 0 0 18px;
  font-size: clamp(2rem, 4.6vw, 3.5rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.ahero__title em { font-style: normal; color: var(--accent); }
.ahero__p {
  max-width: 70ch;
  margin: 0 0 30px;
  font-size: 15.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.68);
}

.ahero__stats {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 40px);
  margin: clamp(90px, 6vh, 72px) 0 0;
  padding: 0;
  list-style: none;
}
.ahero__stats li {
  display: grid;
  justify-items: center;
  gap: 5px;
  text-align: center;
}
.ahero__stats b {
  font-size: clamp(1.9rem, 3.4vw, 3rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
}
.ahero__stats span {
  font-size: 14.5px;
  line-height: 1.4;
  color: rgba(255,255,255,.62);
}
/* the rule under each figure, as the reference has it */
.ahero__stats li::after {
  content: "";
  width: 34px;
  height: 3px;
  margin-top: 9px;
  border-radius: 2px;
  background: var(--accent);
}

@media (max-width: 767.98px) {
  .ahero__stats { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 30px; }
}
@media (max-width: 575.98px) {
  /* on a phone the bar is the only thing worth clearing - the deep run above
     the headline is desktop breathing room, and the type comes down with it */
  .ahero {
    /* a phone screen is tall and narrow, so a full viewport here is mostly
       photo - the banner keeps a floor but stops eating the whole screen */
    min-height: 68vh;
    min-height: 68dvh;
    padding-top: calc(var(--nav-h) + 26px);
    padding-bottom: 34px;
  }
  .ahero__k { font-size: 12px; letter-spacing: .18em; margin-bottom: 12px; }
  .ahero__title { font-size: 1.65rem; margin-bottom: 14px; }
  .ahero__p { font-size: 14.5px; margin-bottom: 24px; }
  .ahero__word { font-size: 3.4rem; bottom: 58px; }
  .ahero__stats { margin-top: 36px; row-gap: 24px; }
  .ahero__stats b { font-size: 1.5rem; }
  .ahero__stats span { font-size: 13.5px; }
}

/* The video banner carries only the copy now - the figures have their own
   band underneath it - so on a narrow screen it stops holding most of the
   viewport. Below 768 the floor is not what was making it tall: the copy
   plus the deep clearance over it already ran past any floor worth setting,
   so the padding comes in and the paragraph tightens, and the height follows
   from those. These sit after the base rules above: same specificity, so
   source order is what decides them. */
@media (max-width: 767.98px) {
  .ahero--video {
    min-height: 46vh;
    min-height: 46dvh;
    padding-top: calc(var(--nav-h) + 26px);
    padding-bottom: 30px;
  }
}
@media (max-width: 575.98px) {
  .ahero--video {
    /* no floor left to hold - the copy and its clearance are the height */
    min-height: 0;
    padding-top: calc(var(--nav-h) + 14px);
    padding-bottom: 22px;
  }
  .ahero--video .ahero__k { margin-bottom: 10px; }
  .ahero--video .ahero__title { margin-bottom: 10px; }
  /* the paragraph is the tallest single thing on the banner at this width,
     so it is where the height actually comes from */
  .ahero--video .ahero__p {
    font-size: 14px;
    line-height: 1.55;
    margin-bottom: 18px;
  }
}


/* =========================== ABOUT: THE FIGURES ==========================
   The four numbers used to stand on the floor of the banner. They run as
   their own band under it now, on the same near-black the banner's shadow
   lands on, so banner and figures read as one dark block before the white
   story section opens. */
.astats {
  background: #060607;
  padding: clamp(40px, 6vh, 68px) 0 clamp(44px, 7vh, 76px);
}
.astats .container-xxl { max-width: 1240px; }   /* to match the banner above */
/* the band carries its own clearance now, so the gap the row used to hold
   from the copy above it goes - on every width, hence the two classes */
.astats .ahero__stats { margin-top: 0; }

/* ============================== ABOUT: STORY =============================
   What the company is, straight under the banner. Everything is centred on
   one axis - chip, statement, product shot - and only the closing note
   splits in two, so the shot stays the thing the eye lands on.

   The white section of this page: like .plats it carries its own ink tokens
   rather than flipping the globals, so the banner above and the footer below
   stay dark. The ground paints over the fixed backdrop layers on its own -
   those all sit on a negative z-index. */
.astory {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  position: relative;
  overflow-x: clip;                   /* the pool under the shot spills wide */
  padding: clamp(56px, 8vh, 110px) 0 clamp(60px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}
.astory .container-xxl { max-width: 1240px; }   /* to match the hero above */

.astory__head {
  max-width: 820px;
  margin: 0 auto clamp(30px, 4.5vh, 56px);
  text-align: center;
}
/* the chip is inline-flex, so it only centres once the block does */
.astory__title {
  margin: 0 0 18px;
  font-size: clamp(1.8rem, 3.6vw, 2.65rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.01em;
}
.astory__title em { font-style: normal; color: var(--accent); }
.astory__lede {
  max-width: 62ch;
  margin: 0 auto;
  font-size: 15.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

/* ---- the product shot ----
   The PNG is cut out on transparency and the devices are near-black, so on
   white they need grounding or they hang in the air. The pool is a
   pseudo-element behind the group rather than a shadow on the image - a
   shadow would trace each device, and what the shot wants is one soft
   footing under all three. Neutral, not warm: the accent belongs to the
   headline here, and orange under the screens would tint the white. */
.astory__stage {
  position: relative;
  max-width: 934px;
  margin: 0 auto clamp(40px, 6vh, 78px);
}
.astory__stage::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: 50%;
  bottom: -2%;
  width: 96%;
  height: 26%;
  transform: translateX(-50%);
  pointer-events: none;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(20,21,27,.13), transparent 72%);
}
.astory__stage img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: auto;
  margin: 0 auto;
}

/* ---- the closing note ----
   Two panels a shade off the white ground, hairline round them - the same
   flat card the contact form uses, read light. The gap is tight because each
   one now carries its own padding; the wide gutter a bare column needs would
   push them apart into two unrelated blocks.
   They stretch to a shared height, so uneven copy still leaves a level pair. */
.astory__cols {
  max-width: 1080px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 26px);
  align-items: stretch;
}
.astory__col {
  padding: clamp(22px, 2.6vw, 34px);
  border: 1px solid rgba(20,21,27,.10);
  border-radius: 14px;
  background: #f6f7f9;
}
.astory__col h3 {
  margin: 0 0 12px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -.01em;
}
.astory__col p {
  margin: 0;
  font-size: 15px;
  line-height: 1.75;
  color: var(--muted-d);
}

@media (max-width: 767.98px) {
  .astory__cols { grid-template-columns: 1fr; row-gap: 16px; }
}
@media (max-width: 575.98px) {
  .astory__title { font-size: 1.6rem; }
  .astory__lede { font-size: 14.5px; }
  .astory__col p { font-size: 14.5px; }
}


/* ============================== ABOUT: BENTO ============================
   The white run carries on from .astory - that section's bottom padding is
   the gap between the two, so this one opens flush and only pads its floor.

   A split head, then five cards on a 3x2 grid with the middle one spanning
   both rows. Source order is the reading order (top row, then bottom), and
   auto-placement lands them correctly on its own: the tall card fills the
   middle column, so the fourth and fifth cards flow into the outer two. */
.abento {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  position: relative;
  padding: 0 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}


/* ---- the head ----
   Statement left, the note beside it rather than under it. The note starts
   level with the headline rather than the chip, which is what the extra top
   padding buys - it reads as an aside to the title, not a second column. */
.abento__head {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(20px, 4vw, 72px);
  margin-bottom: clamp(30px, 4.5vh, 54px);
}
.abento__title {
  margin: 0;
  font-size: clamp(2.1rem, 4.4vw, 3.2rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.abento__title em { font-style: normal; color: var(--accent); }
.abento__lede {
  margin: 0;
  /* the note drops to sit level with the headline rather than the chip; the
     offset tracks the title, so it grew with it */
  padding-top: clamp(0px, 5vw, 74px);
  max-width: 52ch;
  font-size: 16.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

/* ---- the bento ---- */
.abento__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: minmax(300px, auto);
  gap: clamp(14px, 1.6vw, 22px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.abento__card {
  display: flex;
  flex-direction: column;
  overflow: hidden;                   /* the shot is cropped by the card */
  border: 1px solid rgba(20,21,27,.08);
  border-radius: 16px;
  background: #f6f7f9;
}
/* the one panel that runs the height of the block - it carries the long
   statement, so the copy sits at its floor with the art above */
.abento__card--tall { grid-row: span 2; }

/* the art takes whatever height the copy leaves. The illustrations are
   centred on their own ground with room to spare round the subject, so a
   cover crop trims background rather than the thing being shown. */
.abento__shot {
  display: block;
  position: relative;
  flex: 1 1 auto;
  min-height: 170px;
}
.abento__shot img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.abento__txt {
  flex: none;
  padding: 0 clamp(20px, 2.2vw, 30px) clamp(20px, 2.2vw, 30px);
}
.abento__txt h3 {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -.01em;
}
/* only some cards carry a note under the title - the gap belongs to the
   paragraph, so a title on its own still sits tight to the card floor */
.abento__txt p {
  margin: 9px 0 0;
  font-size: 15.5px;
  line-height: 1.62;
  color: var(--muted-d);
}
.abento__card--tall .abento__txt p { max-width: 40ch; }

@media (max-width: 991.98px) {
  /* two up: the tall card keeps its span and takes the left of the pair */
  .abento__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 767.98px) {
  .abento__head { grid-template-columns: 1fr; gap: 18px; }
  .abento__lede { padding-top: 0; }
}
@media (max-width: 575.98px) {
  .abento__title { font-size: 1.8rem; }
  .abento__lede { font-size: 15px; }
  .abento__txt h3 { font-size: 17.5px; }
  .abento__txt p { font-size: 14.5px; }
  /* one up, and the tall card stops spanning - a single column has no
     second track for it to pair with */
  .abento__grid { grid-template-columns: 1fr; grid-auto-rows: minmax(260px, auto); }
  .abento__card--tall { grid-row: auto; }
}



/* ============================ ABOUT: THE PORTAL =========================
   The claim on the left, the product shot on the right - except the shot is
   not fitted into its column. It is sized off the viewport and runs past the
   right-hand edge, and the section clips it, which is what gives the block
   its depth. Dark, between the panelled "why" block and the white wall. */
.aport {
  position: relative;
  overflow: hidden;                   /* the shot bleeds; this is the crop */
  padding: clamp(60px, 8vh, 112px) 0;
  /* a shade off the site's ground rather than on it - on the admin page this
     follows another dark section, and two blocks at the same value read as
     one long one with a heading dropped into the middle */
  background: #0d0d0e;
}


.aport__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 5vw, 70px);
}

.aport__title {
  margin: 0 0 18px;
  font-size: clamp(2.1rem, 4.4vw, 3.2rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.aport__title em { font-style: normal; color: var(--accent); }
.aport__lede {
  max-width: 46ch;
  margin: 0 0 clamp(24px, 3vw, 34px);
  font-size: 16.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

/* ---- the four claims ----
   Two up rather than a list: they are labels, and a column of four would
   read as copy the eye has to work through. */
.aport__pills {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 0 clamp(26px, 3.4vw, 38px);
  padding: 0;
  list-style: none;
}
.aport__pills li {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 20px 8px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.3;
}
/* the tick sits in its own disc - a bare glyph at this size disappears
   against the pill it is meant to be marking */
.aport__tick {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(244,129,32,.14);
}
.aport__tick svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.aport__btns {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.aport__btn {
  display: inline-flex;
  align-items: center;
  height: 46px;
  padding: 0 26px;
  border: 1px solid #424242;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.aport__btn:hover { border-color: var(--accent); color: var(--accent); }
.aport__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.aport__btn--solid {
  border-color: var(--accent);
  background: var(--accent);
  color: #000;
}
.aport__btn--solid:hover {
  border-color: var(--accent-hi);
  background: var(--accent-hi);
  color: #000;
}

/* ---- the shot ---- */
.aport__shot { margin: 0; }
.aport__shot img { width: 100%; height: auto; }

@media (min-width: 992px) {
  /* Off the column and off the page: the width is taken from the viewport,
     not the track, so the laptop stays big enough to read at any screen
     size and the overshoot is cropped by the section. max-width has to go
     with it - the global img rule would otherwise pull it back in. */
  .aport__shot img {
    width: max(100%, 56vw);
    max-width: none;
  }
  /* It stands on the section's floor rather than floating in the middle of
     it: bottom of the row, then the section's own bottom padding cancelled
     underneath, so the pedestal runs right down to the edge. The copy is
     left on center - only the shot drops. */
  .aport__shot {
    align-self: end;
    margin-bottom: calc(-1 * clamp(60px, 8vh, 112px));
  }
}

@media (max-width: 991.98px) {
  /* stacked, the shot has the full column and nothing to run past, so it
     goes back to behaving like an ordinary image - under the copy, because
     the claim is what the reader came for */
  .aport__in { grid-template-columns: 1fr; gap: 34px; }
}
@media (max-width: 575.98px) {
  .aport__title { font-size: 1.8rem; }
  .aport__lede { font-size: 15px; }
  /* one up: two pills to a row leaves the longer labels wrapping to three
     lines inside a shape built for one */
  .aport__pills { grid-template-columns: 1fr; }
  .aport__btns .aport__btn { flex: 1 1 auto; justify-content: center; }
}

/* ============================== ABOUT: ROAD MAP ==========================
   Dark again after the white run above, which is what marks it off as its
   own chapter rather than more of the same page.

   One milestone at a time: the year on a card, the copy beside it, and the
   whole run on a rail underneath that scrolls sideways when the years
   outgrow the shell. The chips are a tablist and the copy blocks are their
   panels - .is-on is the only state, and it is set from main.js. */
.road {
  position: relative;
  padding: clamp(64px, 9vh, 120px) 0 clamp(56px, 8vh, 100px);
  background: var(--bg);
}
.road .container-xxl { max-width: 1240px; }

.road__head {
  max-width: 820px;
  margin: 0 auto clamp(38px, 5.5vh, 68px);
  text-align: center;
}
.road__title {
  margin: 0 0 16px;
  font-size: clamp(2.1rem, 4.4vw, 3.2rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.road__title em { font-style: normal; color: var(--accent); }
.road__lede {
  max-width: 62ch;
  margin: 0 auto;
  font-size: 16.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

/* ---- the panel pair ---- */
.road__stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(26px, 4vw, 68px);
  margin-bottom: clamp(42px, 6vh, 80px);
}

/* Both halves stack every milestone in one grid cell and show the live one,
   so the block is as tall as its longest entry from the start and nothing
   jumps as the years are clicked through. Hidden ones are visibility:hidden
   rather than transparent, which keeps them out of the tab order and off
   the screen reader. */
.road__figs,
.road__copies { display: grid; }
.road__fig,
.road__copy {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition: opacity .45s ease;
}
.road__fig.is-on,
.road__copy.is-on { visibility: visible; opacity: 1; }

/* ---- the year card ---- */
.road__fig {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  min-height: clamp(230px, 27vw, 340px);
  border: 1px solid var(--line);
  border-radius: 18px;
  background:
    radial-gradient(ellipse 62% 46% at 50% 116%, rgba(244,129,32,.26), transparent 70%),
    #101012;
}
/* a dot grid rising off the floor of the card, faded out before it reaches
   the year so it stays texture rather than pattern */
.road__fig::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  height: 52%;
  background-image: radial-gradient(rgba(255,255,255,.11) 1px, transparent 1px);
  background-size: 13px 13px;
  -webkit-mask-image: linear-gradient(to top, #000, transparent);
          mask-image: linear-gradient(to top, #000, transparent);
  pointer-events: none;
}
.road__fig b {
  position: relative;
  z-index: 1;
  font-size: clamp(3.4rem, 8.4vw, 6.6rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.04em;
  color: rgba(244,129,32,.86);
}

/* ---- the copy, and the arrows under it ---- */
.road__side {
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 4vh, 44px);
}
/* The copy takes the space the arrows leave and rides the middle of it, so
   it sits level with the year beside it however short the entry runs - the
   arrows stay anchored at the floor rather than travelling with it. */
.road__copies {
  flex: 1 1 auto;
  align-content: center;
}
.road__copy h3 {
  margin: 0 0 14px;
  font-size: clamp(1.35rem, 2.4vw, 1.8rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.01em;
}
.road__copy p {
  max-width: 46ch;
  margin: 0;
  font-size: 15.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.62);
}

.road__nav {
  flex: none;
  display: flex;
  gap: 12px;
}
.road__arrow {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: border-color .25s ease, color .25s ease, background .25s ease;
}
.road__arrow:hover:not(:disabled) {
  border-color: rgba(244,129,32,.6);
  background: rgba(244,129,32,.10);
  color: var(--accent);
}
.road__arrow:disabled { opacity: .3; cursor: default; }
.road__arrow svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* one arrow symbol, turned round for the way back */
.road__arrow--prev svg { transform: rotate(180deg); }

/* ---- the rail ----
   It sits outside the shell in the markup and runs the full width of the
   viewport, and it scrolls sideways on its own once the years outrun that,
   so the page never grows a horizontal scrollbar of its own. */
.road__rail {
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 4px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.road__rail::-webkit-scrollbar { display: none; }

.road__track {
  position: relative;
  display: flex;
  align-items: end;
  min-width: max-content;
  margin: 0;
  /* the rail is full-bleed but the chips are not: they keep the page's own
     gutter, and the line runs on past them to the edge */
  padding: 0 var(--gutter);
  list-style: none;
}
/* The two ends of the line the steps cannot own. Absolute, so neither
   becomes a flex item. The lead-in is always behind the live dot, so it is
   always filled; the tail is always ahead of it, so it never is. Both
   belong to the track rather than the rail, which is what carries them off
   with the chips as it scrolls. */
.road__track::before,
.road__track::after {
  content: "";
  position: absolute;
  bottom: 4px;
  width: var(--gutter);
  height: 2px;
}
.road__track::before { left: 0; background: var(--accent); }
.road__track::after { right: 0; background: var(--line); }

/* Each step owns the piece of line under it, so the run joins up without a
   separate track element to measure: the steps before the live one are
   accent throughout, and the live one is accent only as far as its own dot
   - which is what the half-and-half gradient buys, no JS width maths. */
.road__step {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 16px;
  padding: 0 clamp(9px, 1.1vw, 17px);
}
.road__step::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 4px;                 /* the line runs through the dots' centre */
  height: 2px;
  background: var(--line);
}
.road__step.is-done::before { background: var(--accent); }
.road__step.is-on::before {
  background: linear-gradient(to right, var(--accent) 50%, var(--line) 50%);
}

.road__chip {
  display: inline-flex;
  align-items: center;
  padding: 9px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  color: rgba(255,255,255,.7);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
/* only the first chip carries a label; the dot separator belongs to it
   rather than to the markup */
.road__chip span { font-weight: 500; color: rgba(255,255,255,.5); }
.road__chip span::before { content: "\00b7"; margin: 0 7px; }
.road__chip:hover { border-color: rgba(244,129,32,.45); color: var(--ink); }
.road__step.is-on .road__chip {
  border-color: rgba(244,129,32,.55);
  background: rgba(244,129,32,.12);
  color: var(--ink);
}
.road__step.is-on .road__chip span { color: rgba(255,255,255,.72); }

.road__dot {
  position: relative;
  z-index: 1;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #2b2c31;
  transition: background .25s ease, box-shadow .25s ease, transform .25s ease;
}
.road__step.is-done .road__dot { background: var(--accent); }
.road__step.is-on .road__dot {
  background: var(--accent);
  box-shadow: 0 0 0 4px rgba(244,129,32,.18);
  transform: scale(1.15);
}

@media (max-width: 991.98px) {
  /* the year card over the copy - side by side, neither half has the width
     the big numeral or the paragraph needs */
  .road__stage { grid-template-columns: 1fr; gap: 26px; }
  /* stacked, the copy has nothing beside it to line up with - it reads
     better sitting straight under the card than floating in its column */
  .road__copies { align-content: start; }
  .road__fig { min-height: 190px; }
}
@media (max-width: 575.98px) {
  .road__title { font-size: 1.8rem; }
  .road__lede { font-size: 15px; }
  .road__fig b { font-size: 3rem; }
  .road__copy p { font-size: 14.5px; }
  .road__arrow { width: 42px; height: 42px; }
}
/* =========================== CONTACT: GET IN TOUCH ===========================
   Dark, like the two sections above it: the statement on the left, the form in
   a panel on the right. The panel is a shade off the ground with a hairline
   round it, and the fields a shade off the panel again - three flat tones and
   no shadows, so the only bright thing in the block is the button. 1240px to
   match the hero. */
.cget {
  padding: clamp(56px, 8vh, 104px) 0;
  background: #151515;
}
.cget .container-xxl { max-width: 1240px; }

/* ---- the statement, over the form rather than beside it ---- */
.cget__head {
  max-width: 720px;
  margin: 0 auto clamp(30px, 4.5vh, 54px);
  text-align: center;
}
.cget__title {
  margin: 0 0 20px;
  font-size: clamp(1.7rem, 3vw, 2.15rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.01em;
}
.cget__title em { font-style: normal; color: var(--accent); }
.cget__lede {
  max-width: 70ch;
  margin: 0 auto;
  font-size: 15.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

/* ---- the panel ---- */
.cget__card {
  max-width: 790px;
  margin: 0 auto;
  padding: clamp(24px, 3.2vw, 42px);
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #1b1b1b;
}
.cget__ct {
  margin: 0 0 8px;
  text-align: center;
  font-size: clamp(1.25rem, 2.1vw, 1.5rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.01em;
}
.cget__cp {
  margin: 0 0 26px;
  text-align: center;
  font-size: 14.5px;
  line-height: 1.65;
  color: rgba(255,255,255,.52);
}

.cform__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* bottom-aligned, so a label that wraps to two lines - "How did you hear
     about us?" does at this width - lifts its own label instead of dropping
     its input a line below the one beside it */
  align-items: end;
  gap: 0 20px;
}
/* the field is a <p> so label and control stay one block in the flow; the
   grid inside is what stacks the label over its input */
.cform__f {
  display: grid;
  gap: 7px;
  margin: 0 0 15px;
}
.cform__f label {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255,255,255,.5);
}
.cform__f label i { font-style: normal; color: var(--accent); }

.cform input,
.cform select,
.cform textarea {
  width: 100%;
  height: 42px;
  padding: 0 14px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: #262626;
  font-family: var(--font);
  font-size: 15px;
  color: #fff;
  transition: border-color .2s ease, background .2s ease;
}
.cform textarea {
  height: auto;
  min-height: 96px;
  padding: 11px 14px;
  line-height: 1.6;
  resize: vertical;
}
/* focus is a grey ring, not an accent one - the orange in this block is the
   button's alone */
.cform input:focus,
.cform select:focus,
.cform textarea:focus {
  outline: 0;
  background: #2e2e2e;
  border-color: #4a4a4a;
}

/* the native select arrow is switched off so the site chevron can take its
   place - the same drawing as the menu carets */
.cform__sel { position: relative; display: block; }
.cform select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 42px;
  cursor: pointer;
}
.cform select option { background: #262626; color: #fff; }
.cform__caret {
  position: absolute;
  right: 15px;
  top: 50%;
  width: 13px;
  height: 13px;
  margin-top: -6px;
  fill: none;
  stroke: rgba(255,255,255,.45);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.cform__send {
  margin: 5px auto 0;
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 11px;
  height: 46px;
  padding: 0 26px;
  border: 0;
  border-radius: 8px;
  background: var(--accent);
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  color: #000;
  cursor: pointer;
  transition: background .25s ease;
}
.cform__send:hover { background: var(--accent-hi); }
.cform__send svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 991.98px) {
  .cget__lede { max-width: none; }
}
@media (max-width: 575.98px) {
  .cform__row { grid-template-columns: 1fr; }
}



/* ================================ PRICING ==============================
   The blog page's head over a plan comparison. Like every light section it
   carries its own ink tokens rather than flipping the globals, so the bar
   above and the footer below stay dark. */
.pricing {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20,21,27,.12);
  padding: clamp(52px, 7vh, 92px) 0 clamp(60px, 8vh, 104px);
  background: #fff;
  color: var(--ink-d);
}
.pricing__head {
  max-width: 780px;
  margin: 0 auto clamp(34px, 4.5vh, 56px);
  text-align: center;
}
.pricing__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4.6vw, 2.8rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.01em;
}
.pricing__title em { font-style: normal; color: var(--accent); }
.pricing__lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: var(--muted-d);
}

/* ---- the picker ----
   Panel on the left, the plans to choose from on the right. The picks are a
   tablist and the panels are their tabpanels; .is-on is the only state, set
   from main.js. Reading one plan at a time is what lets this hold every
   feature - a four-column table has to be scrolled sideways on a phone, and
   a comparison you scroll stops being one. */
.pplan {
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  align-items: start;
  gap: clamp(30px, 5vw, 76px);
}

/* the panels stack in one cell and only the live one shows, so the block is
   as tall as its longest plan from the start and nothing jumps on a switch.
   Hidden ones are visibility:hidden rather than transparent, which keeps
   them out of the tab order and off the screen reader. */
.pplan__detail { display: grid; }
.pplan__panel {
  grid-area: 1 / 1;
  visibility: hidden;
  opacity: 0;
  transition: opacity .35s ease;
}
.pplan__panel.is-on { visibility: visible; opacity: 1; }

.pplan__name {
  margin: 0 0 clamp(20px, 2.6vw, 30px);
  font-size: clamp(1.7rem, 3.2vw, 2.35rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.02em;
}

.pplan__list {
  margin: 0 0 clamp(26px, 3.4vw, 38px);
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 17px clamp(18px, 2.4vw, 34px);
}
.pplan__list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink-d);
}
.pplan__list li.is-off { color: #9aa0ad; }

/* Bare glyphs rather than discs. At list weight a filled circle is heavier
   than the line it marks, and a column of them reads before the words do. */
.pplan__yes,
.pplan__no {
  flex: none;
  display: block;
  margin-top: 2px;              /* down onto the cap height of the line */
}
.pplan__yes svg,
.pplan__no svg {
  width: 19px;
  height: 19px;
  fill: none;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.pplan__yes svg { stroke: var(--accent); }
.pplan__no svg { stroke: #b6bbc4; }

.pplan__btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 50px;
  padding: 0 30px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 14.5px;
  font-weight: 700;
  color: #000;
  transition: background .25s ease, transform .25s ease;
}
.pplan__btn svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .3s ease;
}
.pplan__btn:hover { background: var(--accent-hi); transform: translateY(-2px); color: #000; }
.pplan__btn:hover svg { transform: translateX(3px); }
.pplan__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

/* ---- the plans to pick from ---- */
.pplan__picks {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: clamp(12px, 1.4vw, 18px);
}
.ppick {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(18px, 2.4vw, 34px);
  padding: clamp(20px, 2.2vw, 28px) clamp(20px, 2.4vw, 30px);
  border: 1px solid rgba(20,21,27,.12);
  border-radius: 16px;
  background: #fff;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .25s ease, box-shadow .25s ease, transform .25s ease;
}
.ppick:hover { border-color: rgba(244,129,32,.45); }
/* the live one is outlined rather than filled - it sits beside three others
   and a filled card would read as the only one worth having */
.ppick.is-on {
  border-color: var(--accent);
  box-shadow: 0 14px 34px rgba(20,21,27,.08);
}
.ppick:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

/* The flag rides beside the plan name rather than above it or off the card's
   edge, so it reads as part of the name instead of a sticker on the card.
   Only the popular plan carries the row; the other three leave their <b> as
   a plain grid child, which lays out identically. It wraps, because at the
   narrow end the name and the chip together outrun the column. */
.ppick__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 11px;
}
.ppick__flag {
  padding: 4px 11px;
  border-radius: 6px;
  background: rgba(244,129,32,.14);
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent);
}

.ppick__txt { display: grid; gap: 7px; min-width: 0; }
.ppick__txt b {
  font-size: clamp(17px, 1.7vw, 21px);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -.01em;
  color: var(--ink-d);
}
.ppick__txt > span {
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted-d);
}

.ppick__fig {
  display: grid;
  justify-items: end;
  gap: 2px;
  text-align: right;
}
.ppick__fig i {
  font-style: normal;
  font-size: 13px;
  font-weight: 500;
  color: var(--muted-d);
}
.ppick__fig b {
  font-size: clamp(24px, 2.6vw, 34px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--ink-d);
  transition: color .25s ease;
}
.ppick.is-on .ppick__fig b { color: var(--accent); }

@media (max-width: 991.98px) {
  /* the picks come first stacked: choosing is the job, and the panel is the
     answer to it */
  .pplan { grid-template-columns: 1fr; gap: 34px; }
  .pplan__picks { order: -1; }
}
@media (max-width: 479.98px) {
  .pplan__list { grid-template-columns: 1fr; }
  /* the figure drops under the name rather than squeezing beside it */
  .ppick { grid-template-columns: 1fr; gap: 14px; }
  .ppick__fig { justify-items: start; text-align: left; }
}
/* ---- the close ---- */
.pricing__foot {
  max-width: 760px;
  margin: clamp(30px, 4vh, 46px) auto 0;
  text-align: center;
}
.pricing__note {
  margin: 0 0 24px;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--muted-d);
}
.pricing__btn {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 30px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 14.5px;
  font-weight: 700;
  color: #000;
  transition: background .25s ease, transform .25s ease;
}
.pricing__btn:hover { background: var(--accent-hi); transform: translateY(-2px); }
.pricing__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }

@media (max-width: 575.98px) {
  .pricing__title { font-size: 1.75rem; }
  .pricing__lede { font-size: 15px; }
  .pplan__name { font-size: 1.55rem; }
}

/* ============================== BLOG LISTING ==============================
   Header, then straight into the cards - no banner, the same way the faq
   page opens. Nothing follows the grid, so the section carries its own tail
   down to the footer rather than the short one a following box would fill. */
.blog {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20,21,27,.12);
  padding: clamp(52px, 7vh, 92px) 0;
  background: #fff;
  color: var(--ink-d);
}
.blog__head {
  max-width: 780px;
  margin: 0 auto clamp(34px, 4.5vh, 56px);
  text-align: center;
}
.blog__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4.6vw, 2.8rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.01em;
}
.blog__title em { font-style: normal; color: var(--accent); }
.blog__lede {
  margin: 0;
  font-size: 16px;
  line-height: 1.7;
  color: var(--muted-d);
}

/* ---- the lead post ----
   The banners are 1.9:1 with their own headline text baked in, so at a third
   of the shell that text is unreadable furniture. The newest post gets the
   width to actually show it, and the rest run as an archive under it - which
   is also what stops the page reading as six identical cards. */
.blead {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  /* the copy runs taller than the picture at this ratio, so centring left the
     image floating with 30px of dead space over and under it while the copy
     filled the box edge to edge. Stretching squares the two halves off. */
  align-items: stretch;
  gap: clamp(24px, 3vw, 46px);
  max-width: 1240px;
  margin: 0 auto clamp(38px, 5vh, 62px);
  padding: clamp(20px, 2vw, 26px);
  border: 1px solid var(--line-d);
  border-radius: 18px;
  background: #fafafa;
  transition: border-color .25s ease, box-shadow .25s ease;
}
.blead:hover {
  border-color: rgba(20,21,27,.2);
  box-shadow: 0 26px 54px -32px rgba(20,21,27,.4);
}
.blead__shot {
  display: block;
  overflow: hidden;
  border-radius: 12px;
  background: #f2f3f5;
}
/* filling the half means a crop, and it comes off the right - this banner
   carries its headline down the left, and the artwork is what can go */
.blead__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
  transition: transform .5s ease;
}
.blead:hover .blead__shot img { transform: scale(1.03); }

.blead__body { padding: clamp(4px, 1vw, 14px) clamp(4px, 1.4vw, 18px) clamp(4px, 1vw, 14px) 0; }
.blead__tag {
  display: inline-flex;
  align-items: center;
  margin-bottom: 16px;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #fff;
}
.blead__t {
  margin: 0 0 14px;
  font-size: clamp(1.35rem, 2.5vw, 1.1rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.015em;
}
.blead__t a { transition: color .25s ease; }
.blead__t a::after { content: ""; position: absolute; inset: 0; }

.blead__x {
  margin: 0 0 18px;

  line-height: 1.75;
  color: var(--muted-d);
}
/* date and reading time on one line, split by a dot */
.blead__meta,
.brow__read {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted-d);
}
.blead__meta i {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--accent);
}
.blead__more {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-d);
}
.blead__more svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .25s ease;
}
.blead:hover .blead__more { color: var(--accent); }
.blead:hover .blead__more svg { transform: translateX(4px); }

/* ---- the archive rows ----
   A date rail, a thumbnail and the copy, ruled off from each other. No card
   borders - the rules do that job, and the row lights up rather than lifts. */
.brows {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.brow {
  position: relative;
  display: grid;
  grid-template-columns: 74px 250px minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(18px, 2.4vw, 34px);
  padding: clamp(20px, 2.4vh, 28px) clamp(12px, 1.4vw, 20px);
  border-top: 1px solid var(--line-d);
  border-radius: 12px;
  transition: background .25s ease;
}
.brow:last-child { border-bottom: 1px solid var(--line-d); }
.brow:hover { background: #fafafa; }

/* the rail carries the date as a stacked block, so the rows scan by date
   down the left edge instead of repeating a label inside every card */
.brow__day {
  display: grid;
  justify-items: center;
  gap: 1px;
  padding-right: clamp(14px, 1.6vw, 22px);
  border-right: 1px solid var(--line-d);
  text-align: center;
}
.brow__day b {
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--ink-d);
}
.brow__day span {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.brow__day i {
  font-style: normal;
  font-size: 12px;
  color: rgba(20,21,27,.4);
}

.brow__shot {
  display: block;
  overflow: hidden;
  border-radius: 10px;
  background: #f2f3f5;
  aspect-ratio: 1800 / 942;
}
.brow__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .5s ease;
}
.brow:hover .brow__shot img { transform: scale(1.05); }

.brow__t {
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: -.01em;
}
.brow__t a { transition: color .25s ease; }
.brow__t a::after { content: ""; position: absolute; inset: 0; }
.brow:hover .brow__t a { color: var(--accent); }
.brow__x {
  margin: 0 0 10px;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted-d);
}

.brow__go {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line-d);
  border-radius: 50%;
  color: var(--ink-d);
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.brow__go svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.brow:hover .brow__go {
  border-color: var(--accent);
  background: var(--accent);
  color: #000;
}

@media (max-width: 991.98px) {
  .blead { grid-template-columns: 1fr; }
  /* stacked, the picture has the full width and no height to match, so it
     goes back to its own ratio and nothing is cropped */
  .blead__shot { aspect-ratio: 1800 / 942; }
  .blead__body { padding: 0 6px 6px; }
  .brow { grid-template-columns: 68px 200px minmax(0, 1fr); }
  .brow__go { display: none; }
}

/* a row waiting its turn. display:none rather than the hidden attribute so
   the script owns one class and the markup stays plain. */
.brow.is-hid { display: none; }

.bmore {
  display: flex;
  justify-content: center;
  margin-top: clamp(30px, 4vh, 46px);
}
.bmore__btn {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  height: 48px;
  padding: 0 28px;
  border: 1px solid var(--line-d);
  border-radius: 999px;
  background: #fff;
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-d);
  cursor: pointer;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.bmore__btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform .25s ease;
}
.bmore__btn:hover {
  border-color: var(--accent);
  background: var(--accent);
  color: #000;
}
.bmore__btn:hover svg { transform: translateY(2px); }

@media (max-width: 575.98px) {
  /* two bands on a phone: the date beside the picture, then the words under
     both - a single column would put the thumbnail between the date and the
     headline it belongs to */
  .brow {
    grid-template-columns: 62px minmax(0, 1fr);
    grid-template-areas:
      "day  shot"
      "body body";
    align-items: center;
    gap: 15px 16px;
  }
  .brow__day  { grid-area: day; padding-right: 14px; }
  .brow__shot { grid-area: shot; }
  .brow__body { grid-area: body; }
  .brow__day b { font-size: 1.35rem; }
}


/* ============================== BLOG POST ==============================
   One column on a reading measure, on white. No banner - the crumb and the
   headline open the page directly under the bar, the same way the blog and
   faq pages do. */
.post {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20,21,27,.12);
  padding: clamp(30px, 4vh, 52px) 0 clamp(52px, 7vh, 92px);
  background: #fff;
  color: var(--ink-d);
}
.post .container-xxl { max-width: 1250px; }

.post__crumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  margin-bottom: clamp(22px, 3vh, 34px);
  font-size: 14px;
  color: var(--muted-d);
}
.post__crumb a { transition: color .25s ease; }
.post__crumb a:hover { color: var(--accent); }
.post__crumb span[aria-hidden] { color: rgba(20,21,27,.28); }
.post__crumb [aria-current] { color: var(--ink-d); font-weight: 600; }

.post__date {
  display: block;
  margin-bottom: 14px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.post__title {
  margin: 0 0 18px;
  font-size: clamp(1.85rem, 4.2vw, 2.6rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.015em;
}
.post__lede {
  margin: 0;
  font-size: 17px;
  line-height: 1.7;
  color: var(--muted-d);
}

.post__shot {
  margin: clamp(28px, 4vh, 44px) 0;
  overflow: hidden;
  border-radius: 14px;
  background: #f2f3f5;
}
.post__shot img { width: 100%; height: auto; }

/* the body sets its own rhythm rather than leaning on the global one - a
   long read needs more air between a heading and the paragraph it opens
   than a marketing section does */
.post__body p {
  margin: 0 0 20px;
  font-size: 16.5px;
  line-height: 1.8;
  color: #2b2e39;
}
.post__body h2 {
  margin: clamp(34px, 4.5vh, 48px) 0 14px;
  font-size: clamp(1.35rem, 2.6vw, 1.7rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -.01em;
}
.post__body h3 {
  margin: 28px 0 12px;
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.3;
}
.post__body strong { font-weight: 700; color: var(--ink-d); }

.post__list {
  margin: 0 0 20px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
}
.post__list li {
  position: relative;
  padding-left: 26px;
  font-size: 16.5px;
  line-height: 1.75;
  color: #2b2e39;
}
.post__list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 12px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.post__list b { font-weight: 700; color: var(--ink-d); }

/* the three claims pulled out of the prose, so they read as the article's
   own figures rather than as another sentence */
.post__stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
  margin: clamp(26px, 3.4vh, 36px) 0;
  padding: clamp(20px, 2.6vw, 28px);
  border: 1px solid var(--line-d);
  border-radius: 14px;
  background: #fafafa;
  list-style: none;
  text-align: center;
}
.post__stats li { display: grid; gap: 5px; }
.post__stats b {
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--accent);
}
.post__stats span { font-size: 14.5px; line-height: 1.4; color: var(--muted-d); }

/* nine rows will not fit a phone, so the table scrolls inside its own box
   rather than pushing the page sideways */
.post__tablewrap {
  overflow-x: auto;
  margin: 0 0 24px;
  border: 1px solid var(--line-d);
  border-radius: 12px;
}
.post__table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  font-size: 15px;
}
.post__table th,
.post__table td {
  padding: 13px 16px;
  text-align: left;
  vertical-align: top;
  line-height: 1.55;
  border-bottom: 1px solid var(--line-d);
}
.post__table thead th {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted-d);
  background: #fafafa;
}
.post__table tbody th { font-weight: 700; color: var(--ink-d); }
.post__table td { color: var(--muted-d); }
.post__table tbody td:last-child { color: var(--ink-d); }
.post__table tr:last-child th,
.post__table tr:last-child td { border-bottom: 0; }

.post__cta {
  margin-top: clamp(30px, 4vh, 42px);
  padding-top: clamp(24px, 3vh, 32px);
  border-top: 1px solid var(--line-d);
}
.post__cta a {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.post__back {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: clamp(30px, 4vh, 44px);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-d);
  transition: color .25s ease;
}
.post__back svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  transform: rotate(180deg);
  transition: transform .25s ease;
}
.post__back:hover { color: var(--accent); }
.post__back:hover svg { transform: rotate(180deg) translateX(4px); }

@media (max-width: 575.98px) {
  .post__stats { grid-template-columns: 1fr; gap: 16px; text-align: left; }
  .post__stats li { grid-template-columns: auto minmax(0, 1fr); align-items: baseline; gap: 12px; }
}


/* =========================== responsive =========================== */

/* The column stacking is Bootstrap's now: the hero and about rows are
   col-lg-6, so they break at 992px, and the about stage is ordered first
   on small screens from the markup. Only the trim is left here. */

/* the panels need the full bar, so the navbar collapses at xl (1200px) */
@media (max-width: 1199.98px) {
  /* The drawer is a child of .vast-nav, and .fixed-top makes a stacking
     context - so the bar itself has to clear the offcanvas backdrop (1040),
     otherwise the backdrop paints straight over the open drawer. */
  .vast-nav { z-index: 1046; }
  /* and because it is above the backdrop, it dims itself to match. The drawer
     is positioned with a z-index, so this overlay never covers it. Both states
     are matched: Bootstrap only swaps .showing for .show once the slide ends,
     and drops both on the way out, so this fades in step with the backdrop. */
  .vast-nav::before {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,.5);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .3s ease, visibility .3s;
  }
  .vast-nav:has(.offcanvas.showing)::before,
  .vast-nav:has(.offcanvas.show)::before { opacity: 1; visibility: visible; }

  .vast-nav .offcanvas {
    --bs-offcanvas-width: min(380px, 88vw);
    --bs-offcanvas-bg: #0f0f0f;
    --bs-offcanvas-border-width: 0;
    --bs-offcanvas-padding-x: var(--gutter);
    --bs-offcanvas-padding-y: 16px;
    /* .vast-nav is the containing block for this fixed panel, so Bootstrap
       height:100% would only be as tall as the bar */
    height: 100vh;
    height: 100dvh;
    box-shadow: -26px 0 60px -22px rgba(0,0,0,.95);
  }
  .vast-nav .offcanvas-header {
    min-height: var(--nav-h);
    border-bottom: 1px solid var(--line);
  }
  .vast-nav .offcanvas-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: rgba(255,255,255,.5);
  }
  .vast-nav .btn-close { opacity: .75; }
  .vast-nav .btn-close:hover { opacity: 1; }
  .vast-nav .navbar-nav { gap: 2px; }
  .vast-nav .nav-link { justify-content: space-between; height: 46px; display: flex; align-items: center; }
  .vast-nav .dropdown-menu {
    min-width: 0;
    padding: 0 0 6px 10px;
    background: none;
    box-shadow: none;
  }
  .vast-nav .dropdown-item { margin: 0; padding: 12px 14px; }
  /* the drawer is the full height of the screen, so the two buttons go to the
     foot of it rather than trailing the list. The body is the column that
     holds them there; the list keeps its own height and the body scrolls when
     a panel is opened, which carries the buttons below the fold with it. */
  .vast-nav .offcanvas-body { display: flex; flex-direction: column; }
  /* width: 100% leaves .mx-auto nothing to centre with — as a flex item the
     list would otherwise shrink to its text and pull off the right edge, and
     the chevrons with it. */
  .vast-nav .offcanvas-body > .navbar-nav { flex: 0 0 auto; width: 100%; }
  .navbar-actions { display: grid; gap: 10px; margin: auto 0 0; padding-top: 22px; }

  /* inside the drawer the panels flatten: no card, no descriptions, just
     the list. .offcanvas-body scrolls on its own. */
  .vast-nav .navbar-nav .mm__panel { padding: 2px 0 10px 6px; border: 0; border-radius: 0; }
  .mm__cols { padding: 0; }
  .mm__promo { display: none; }
  .mm__head { margin: 14px 0 6px; font-size: 14.5px; }
  .mm__head--span, .mm__cols > .mm__group:first-child .mm__head { margin-top: 6px; }
  .mm__head--gap { margin-top: 20px; }
  .mm__item { margin: 0; padding: 9px 10px; gap: 11px; }
  .mm__ico { width: 19px; height: 19px; }
  .mm__txt b { font-size: 14.5px; }
  .mm__txt > span { display: none; }
}

@media (max-width: 991.98px) {
  .hero__r { text-align: left; }
  .about__stage { min-height: clamp(320px, 62vw, 460px); }
  /* gx-5 pulls the row 24px wider than the container gutter on each side; the
     columns are stacked here anyway, so the horizontal gutter has no job. */
  .about .row { --bs-gutter-x: 0; }
}

@media (max-width: 720px) {
  :root { --nav-h: 72px; }
  .vast-nav .navbar-brand img { height: 30px; }
  .stats { padding: 18px 20px; gap: 16px 26px; }
  .hero__note { font-size: 14.5px; }
}


/* ========================= LIQUIDITY: BANNER ===========================
   A different opening from .thero and .phero, and on purpose: this page has
   no product shot worth showing, so the right-hand column carries a book
   instead. It is drawn rather than photographed, which means it costs one
   request less and stays sharp at any width. */
.lhero {
  position: relative;
  overflow: hidden;
  padding: calc(var(--nav-h) + clamp(34px, 6vh, 84px)) 0 clamp(48px, 7vh, 100px);
  background: #060607;
}
/* the warm bloom the rest of the site opens on, kept far enough right that
   it sits behind the book rather than under the reading column */
.lhero::before {
  content: "";
  position: absolute;
  top: -22%;
  right: -14%;
  width: min(760px, 82vw);
  aspect-ratio: 1;
  z-index: 0;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(244,129,32,.20) 0%, rgba(244,129,32,.06) 46%, transparent 70%);
  pointer-events: none;
}
.lhero > .container-xxl { position: relative; z-index: 1; }

.lhero__in {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  align-items: center;
  gap: clamp(32px, 5vw, 76px);
}

.lhero__title {
  margin: 0 0 18px;
  font-size: clamp(2.2rem, 5vw, 3.5rem);
  font-weight: 800;
  line-height: 1.07;
  letter-spacing: -.03em;
}
.lhero__title em { font-style: normal; color: var(--accent); }
.lhero__p {
  max-width: 52ch;
  margin: 0 0 clamp(26px, 3.4vw, 36px);
  font-size: clamp(15.5px, 1.5vw, 17px);
  line-height: 1.72;
  color: rgba(255,255,255,.62);
}

/* four claims as a strip rather than a marquee - the rails on the other
   integration pages move, and a page whose whole subject is a number that
   changes does not need a second thing sliding about on it */
.lhero__facts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  margin: 0 0 clamp(26px, 3.4vw, 36px);
  padding: 0;
  list-style: none;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--line);
  overflow: hidden;
}
.lhero__facts li {
  padding: 16px 14px;
  background: #0b0b0d;
}
.lhero__facts b {
  display: block;
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--accent);
}
.lhero__facts span {
  display: block;
  margin-top: 4px;
  font-size: 12.5px;
  line-height: 1.4;
  color: rgba(255,255,255,.5);
}

.lhero__btns { display: flex; flex-wrap: wrap; gap: 12px; }
.lhero__btn {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 28px;
  border: 1px solid #424242;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.lhero__btn:hover { border-color: var(--accent); color: var(--accent); }
.lhero__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.lhero__btn--solid { border-color: var(--accent); background: var(--accent); color: #000; }
.lhero__btn--solid:hover { border-color: var(--accent-hi); background: var(--accent-hi); color: #000; }

/* ---- the book ----
   Two sides around a mid price. Each row carries its own --w, and the bar is
   a ::before pinned to the right edge, so depth reads as weight leaning in
   from the size column rather than as a chart that has to be explained. */
.lbook {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(11,11,13,.86);
  box-shadow: 0 30px 70px rgba(0,0,0,.5);
  overflow: hidden;
}
.lbook__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
}
.lbook__sym { font-size: 14px; font-weight: 700; letter-spacing: .01em; }
.lbook__sp {
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(244,129,32,.14);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--accent);
}

.lbook__side { margin: 0; padding: 8px 0; list-style: none; }
.lbook__side li {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 18px;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.lbook__side li::before {
  content: "";
  position: absolute;
  top: 2px;
  bottom: 2px;
  right: 0;
  z-index: 0;
  width: var(--w, 30%);
  border-radius: 3px 0 0 3px;
}
.lbook__side b,
.lbook__side span { position: relative; z-index: 1; }
.lbook__side b { font-weight: 700; }
.lbook__side span { color: rgba(255,255,255,.46); font-weight: 600; }

.lbook__side--ask li::before { background: rgba(255,255,255,.10); }
.lbook__side--ask b { color: rgba(255,255,255,.82); }
.lbook__side--bid li::before { background: rgba(244,129,32,.20); }
.lbook__side--bid b { color: var(--accent-hi); }

.lbook__mid {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 0;
  padding: 12px 18px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: rgba(255,255,255,.03);
}
.lbook__mid span {
  font-size: 17px;
  font-weight: 800;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}
.lbook__mid i {
  font-style: normal;
  font-size: 11.5px;
  font-weight: 600;
  color: rgba(255,255,255,.42);
}

@media (max-width: 991.98px) {
  .lhero__in { grid-template-columns: 1fr; gap: 34px; }
  .lhero__p { max-width: none; }
}
@media (max-width: 575.98px) {
  .lhero__title { font-size: 2rem; }
  /* two up: four cells across a phone leaves each number on its own line
     with the label broken under it in three pieces */
  .lhero__facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lhero__btns .lhero__btn { flex: 1 1 auto; justify-content: center; }
  .lbook__side li { font-size: 12px; padding: 6px 14px; }
}


/* ======================== LIQUIDITY: THE ROUTE =========================
   Four stops on one line. The line is drawn once behind the row and the
   discs sit on it with the section's own background, which is what makes
   them read as stops rather than as four cards that happen to be in a row. */
.flow {
  padding: clamp(56px, 8vh, 110px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);

  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  #e3e5ea;
}

.flow__head {
  max-width: 720px;
  margin: 0 0 clamp(38px, 5vw, 62px);
}
.flow__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.flow__title em { font-style: normal; color: var(--accent); }
.flow__lede {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

.flow__list {
  /* both are read by the connector below, so neither can be written twice */
  --gap: clamp(20px, 2.6vw, 38px);
  --dot: 54px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap);
  margin: 0;
  padding: 0;
  list-style: none;
}

.flow__step { position: relative; }

/* Drawn per step - from the right edge of this disc to the left edge of the
   next one - rather than as one rail across the row.

   A single rail cannot be placed: it would have to know where the discs are,
   and they are not where a percentage says. The disc is a fixed 54px block,
   so it sits at the LEFT of its column, not centred in it; with four columns
   and three gaps the first disc's centre lands at (100% - 3gap)/8, never at
   12.5%. That is the offset in the screenshot - the rail starting clear of
   the first disc and running out past the last.

   Per step there is nothing to guess. 100% is the column, + gap reaches the
   next column's left edge, - dot skips this disc, and the 20px is the air
   either side. */
.flow__step::before {
  content: "";
  position: absolute;
  top: calc(var(--dot) / 2 - 1px);
  left: calc(var(--dot) + 10px);
  width: calc(100% + var(--gap) - var(--dot) - 20px);
  height: 2px;
  background: var(--line-d);
}
/* nothing to reach for */
.flow__step:last-child::before { content: none; }
.flow__dot {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  /* off the same token the connector measures from, or the two drift apart
     the moment either is changed */
  width: var(--dot);
  height: var(--dot);
  margin: 0 0 20px;
  border: 2px solid var(--line-d);
  border-radius: 50%;
  background: #fff;
  transition: border-color .25s ease, background .25s ease;
}
.flow__dot svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--ink-d);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* the middle two are ours - the accent marks which part of the chain the
   broker is actually buying, without a caption saying so */
.flow__step--own .flow__dot { border-color: var(--accent); background: rgba(244,129,32,.10); }
.flow__step--own .flow__dot svg { stroke: var(--accent); }

.flow__n {
  display: block;
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--accent);
}
.flow__step h3 {
  margin: 0 0 10px;
  font-size: clamp(1.02rem, 1.5vw, 1.2rem);
  font-weight: 700;
  letter-spacing: -.01em;
}
.flow__step p {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted-d);
}

@media (max-width: 991.98px) {
  .flow__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 34px 28px; }
  /* the connectors only ever described one row; across two, the one leaving
     step 2 would run off the right edge towards a step that is now below it.
     They go, and the stage numbers carry the order instead. */
  .flow__step::before { content: none; }
}
@media (max-width: 575.98px) {
  .flow__list { --dot: 46px; grid-template-columns: 1fr; gap: 28px; }
  .flow__dot { width: var(--dot); height: var(--dot); margin-bottom: 16px; }
  .flow__dot svg { width: 19px; height: 19px; }
}


/* ========================= LIQUIDITY: THE BOOK =========================
   Three ways to run a book, one of them marked. The marked one is raised
   rather than recoloured - a broker reading this is choosing, and a panel
   that shouts wins the eye before the copy has made the case. */
.book {
  padding: clamp(60px, 8.5vh, 115px) 0 clamp(64px, 9vh, 120px);
  background: #0d0d0e;
}
.book__head {
  max-width: 760px;
  margin: 0 0 clamp(34px, 4.4vw, 56px);
}
.book__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.book__title em { font-style: normal; color: var(--accent); }
.book__lede {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

.book__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  gap: clamp(18px, 2.2vw, 28px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.book__card {
  position: relative;
  padding: clamp(26px, 2.8vw, 38px);
  border: 1px solid var(--line);
  border-radius: 20px;
  background: rgba(255,255,255,.02);
  transition: border-color .25s ease, transform .25s ease;
}
.book__card:hover { border-color: rgba(255,255,255,.2); transform: translateY(-4px); }
.book__card--on {
  border-color: rgba(244,129,32,.42);
  background: linear-gradient(180deg, rgba(244,129,32,.09) 0%, rgba(244,129,32,.02) 100%);
}
.book__flag {
  position: absolute;
  top: 18px;
  right: 18px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--accent);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #000;
}
.book__card h3 {
  margin: 0 0 12px;
  font-size: clamp(1.2rem, 1.9vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -.02em;
}
.book__card > p {
  margin: 0 0 22px;
  font-size: 15px;
  line-height: 1.7;
  color: rgba(255,255,255,.58);
}
.book__pts {
  margin: 0;
  padding: 22px 0 0;
  border-top: 1px solid var(--line);
  list-style: none;
}
.book__pts li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 14.5px;
  line-height: 1.55;
  color: rgba(255,255,255,.78);
}
.book__pts li + li { margin-top: 13px; }
.book__pts svg {
  flex: none;
  width: 15px;
  height: 15px;
  margin-top: 4px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 991.98px) {
  .book__grid { grid-template-columns: 1fr; }
  .book__card:hover { transform: none; }
}


/* ============================== CODE CARD ==============================
   Shared by the API banner and the webhook block. A window rather than a
   plain <pre>: the bar is what tells a reader at a glance that the thing
   below it is a request and not a paragraph set in the wrong face.

   overflow-x on the body, not the card - a long line has to scroll inside
   its own frame or it takes the whole page sideways with it. */
.code {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: #0b0b0d;
  box-shadow: 0 30px 70px rgba(0,0,0,.5);
  overflow: hidden;
}
.code__bar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(255,255,255,.03);
}
.code__dots { display: flex; gap: 6px; }
.code__dots i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(255,255,255,.16);
}
.code__name {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  font-weight: 600;
  color: rgba(255,255,255,.55);
}
.code__body {
  margin: 0;
  padding: 18px;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.85;
  color: rgba(255,255,255,.72);
  tab-size: 2;
}
.code__body code { font: inherit; color: inherit; }
.code__k { color: #8fb3ff; }
.code__s { color: var(--accent-hi); }
.code__n { color: #7fd6a5; }
.code__c { color: rgba(255,255,255,.32); }
.code__v { color: #fff; font-weight: 600; }

@media (max-width: 575.98px) {
  .code__body { padding: 14px; font-size: 11.5px; }
}


/* ============================ API: BANNER ==============================
   The copy on the left and a request on the right. A developer page that
   opens on a photograph of a laptop is asking to be believed; one that
   opens on the actual call is showing the thing itself. */
.dhero {
  position: relative;
  overflow: hidden;
  padding: calc(var(--nav-h) + clamp(34px, 6vh, 84px)) 0 clamp(48px, 7vh, 100px);
  background: #060607;
}
/* a faint grid, so the block reads as a developer surface without another
   image to load - masked out towards the bottom so it never meets the edge
   as a hard line */
.dhero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image:
    linear-gradient(rgba(255,255,255,.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.035) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(120% 90% at 70% 10%, #000 0%, transparent 72%);
  pointer-events: none;
}
.dhero > .container-xxl { position: relative; z-index: 1; }

.dhero__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(32px, 5vw, 72px);
}
.dhero__title {
  margin: 0 0 18px;
  font-size: clamp(2.2rem, 5vw, 3.5rem);
  font-weight: 800;
  line-height: 1.07;
  letter-spacing: -.03em;
}
.dhero__title em { font-style: normal; color: var(--accent); }
.dhero__p {
  max-width: 50ch;
  margin: 0 0 clamp(24px, 3vw, 32px);
  font-size: clamp(15.5px, 1.5vw, 17px);
  line-height: 1.72;
  color: rgba(255,255,255,.62);
}

/* the three words a developer scans for before reading anything else */
.dhero__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  margin: 0 0 clamp(26px, 3.4vw, 36px);
  padding: 0;
  list-style: none;
}
.dhero__tags li {
  padding: 7px 15px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  font-weight: 600;
  color: rgba(255,255,255,.7);
}

.dhero__btns { display: flex; flex-wrap: wrap; gap: 12px; }
.dhero__btn {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 28px;
  border: 1px solid #424242;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color .25s ease, background .25s ease, color .25s ease;
}
.dhero__btn:hover { border-color: var(--accent); color: var(--accent); }
.dhero__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.dhero__btn--solid { border-color: var(--accent); background: var(--accent); color: #000; }
.dhero__btn--solid:hover { border-color: var(--accent-hi); background: var(--accent-hi); color: #000; }

@media (max-width: 991.98px) {
  .dhero__in { grid-template-columns: 1fr; gap: 34px; }
  .dhero__p { max-width: none; }
}
@media (max-width: 575.98px) {
  .dhero__title { font-size: 2rem; }
  .dhero__btns .dhero__btn { flex: 1 1 auto; justify-content: center; }
}


/* =========================== API: ENDPOINTS ============================
   A reference rather than a feature grid: four groups, each a short list of
   real paths. The method is a chip because that is the first thing anyone
   looks at, and the path is set in mono because it is meant to be copied. */
.endp {
  padding: clamp(56px, 8vh, 110px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);

  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  #e3e5ea;
}
.endp__head {
  max-width: 740px;
  margin: 0 0 clamp(34px, 4.4vw, 56px);
}
.endp__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.endp__title em { font-style: normal; color: var(--accent); }
.endp__lede {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.75;
  color: var(--muted-d);
}

.endp__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(18px, 2.2vw, 28px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.endp__card {
  padding: clamp(24px, 2.6vw, 34px);
  border: 1px solid var(--line-d);
  border-radius: 20px;
  background: #fafbfc;
}
.endp__card h3 {
  margin: 0 0 6px;
  font-size: clamp(1.1rem, 1.7vw, 1.35rem);
  font-weight: 700;
  letter-spacing: -.02em;
}
.endp__card > p {
  margin: 0 0 20px;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--muted-d);
}

.endp__rows { margin: 0; padding: 0; list-style: none; }
.endp__rows li {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr);
  align-items: baseline;
  gap: 12px;
  padding: 13px 0;
  border-top: 1px solid var(--line-d);
}
.endp__m {
  justify-self: start;
  padding: 3px 8px;
  border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .04em;
}
.endp__m--get { background: #eceef3; color: #14151b; }
.endp__m--post { background: var(--accent); color: #000; }
.endp__m--patch { background: rgba(244,129,32,.16); color: #a9540d; }
.endp__m--del { background: rgba(192,57,43,.12); color: #8a1f12; }
/* the path and its line live in their own wrapper rather than as two more
   grid children - the method chip is a <span> too, and a bare
   ".endp__rows span" rule would out-specify .endp__m and flatten it */
.endp__d { min-width: 0; }
.endp__d code {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-d);
  overflow-wrap: anywhere;
}
.endp__d span {
  display: block;
  margin-top: 3px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted-d);
}

@media (max-width: 767.98px) {
  .endp__grid { grid-template-columns: 1fr; }
}
@media (max-width: 575.98px) {
  /* the chip drops above the path: 62px plus a path plus a sentence does not
     fit a phone, and shrinking the chip is what makes it stop reading as one */
  .endp__rows li { grid-template-columns: 1fr; gap: 7px; }
}


/* ============================ API: WEBHOOKS ============================
   The events on the left, one payload on the right. Pairing them is the
   point: a list of event names tells a developer what exists, and the body
   beside it tells them what they will actually be handed. */
.hooks {
  padding: clamp(60px, 8.5vh, 115px) 0 clamp(64px, 9vh, 120px);
  background: #0d0d0e;
}
.hooks__in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(32px, 4.6vw, 68px);
}
.hooks__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.hooks__title em { font-style: normal; color: var(--accent); }
.hooks__lede {
  max-width: 46ch;
  margin: 0 0 clamp(26px, 3vw, 34px);
  font-size: 16.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

.hooks__list { margin: 0; padding: 0; list-style: none; }
.hooks__list li {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  align-items: baseline;
  gap: 8px 14px;
  padding: 14px 0;
  border-top: 1px solid var(--line);
}
.hooks__list li:last-child { border-bottom: 1px solid var(--line); }
.hooks__list b {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-hi);
  overflow-wrap: anywhere;
}
.hooks__list span {
  font-size: 14.5px;
  line-height: 1.55;
  color: rgba(255,255,255,.58);
}

/* the card follows the reader down the list rather than sitting at the top
   of a column twice its height */
.hooks__side { position: sticky; top: calc(var(--nav-h) + clamp(20px, 4vh, 44px)); }

@media (max-width: 991.98px) {
  .hooks__in { grid-template-columns: 1fr; gap: 34px; }
  .hooks__lede { max-width: none; }
  .hooks__side { position: static; }
}
@media (max-width: 575.98px) {
  .hooks__list li { grid-template-columns: 1fr; gap: 5px; }
}


/* ========================== PAYMENTS: COVERAGE =========================
   The map is a watermark, not a picture: it is here to say "everywhere"
   before the copy does, and then to get out of the way. Same trick as
   .sup__map - absolutely placed, aspect ratio taken from the file so it can
   never stretch, and the container lifted above it.

   The cards carry their own near-solid ground rather than being transparent
   over it. A watermark behind body copy is the fastest way to make a section
   look designed and read badly. */
.pmap {
  position: relative;
  overflow: hidden;
  padding: clamp(60px, 8.5vh, 115px) 0 clamp(64px, 9vh, 120px);
  background: #0d0d0e;
}
.pmap__art {
  position: absolute;
  left: 50%;
  top: 52%;
  transform: translate(-50%, -50%);
  width: min(1240px, 116%);
  aspect-ratio: 1280 / 641;
  z-index: 0;
  background: url("../img/world-map.png") center / contain no-repeat;
  opacity: .17;
  pointer-events: none;
}
.pmap > .container-xxl { position: relative; z-index: 1; }

.pmap__head {
  max-width: 720px;
  margin: 0 0 clamp(34px, 4.4vw, 56px);
}
.pmap__title {
  margin: 0 0 14px;
  font-size: clamp(2rem, 4vw, 2.9rem);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -.02em;
}
.pmap__title em { font-style: normal; color: var(--accent); }
.pmap__lede {
  margin: 0;
  font-size: 16.5px;
  line-height: 1.75;
  color: rgba(255,255,255,.6);
}

.pmap__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(16px, 2vw, 24px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.pmap__card {
  padding: clamp(22px, 2.4vw, 30px);
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(9,9,11,.82);
  transition: border-color .25s ease, transform .25s ease;
}
.pmap__card:hover { border-color: rgba(244,129,32,.35); transform: translateY(-4px); }
.pmap__card h3 {
  margin: 0 0 14px;
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  font-weight: 700;
  letter-spacing: -.01em;
}
/* the methods are labels, so they are set as chips - a comma list reads as a
   sentence the eye has to finish before it learns anything */
.pmap__ways {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pmap__ways li {
  padding: 6px 13px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255,255,255,.03);
  font-size: 13px;
  font-weight: 600;
  color: rgba(255,255,255,.72);
}

@media (max-width: 991.98px) {
  .pmap__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pmap__card:hover { transform: none; }
}
@media (max-width: 575.98px) {
  .pmap__grid { grid-template-columns: 1fr; }
  /* the map is wider than the phone by then, so it stops being a watermark
     and becomes noise behind the cards */
  .pmap__art { opacity: .1; width: 200%; }
}


/* ================== LEAD & SALES: WHAT GOES WRONG =====================
   An editorial run rather than a grid of cards. Each entry is a failure
   set in display type with its answer beside it in body copy, and the jump
   between those two sizes is the whole design - a card round either of
   them would say they were the same kind of statement, which is the one
   thing this section needs them not to be.

   Three tracks: the number, the problem, the answer. Only a hairline
   between rows, so the page reads as one column of argument instead of
   five panels that happen to be stacked. */
.lprob {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.13);
  position: relative;
  overflow-x: clip;
  padding: clamp(58px, 8.5vh, 118px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}

.lprob__head { max-width: 760px; margin: 0 0 clamp(34px, 5vh, 64px); }
.lprob__title {
  margin: 0 0 16px;
  font-size: clamp(2.1rem, 4.6vw, 3.3rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.03em;
}
.lprob__title em { font-style: normal; color: var(--accent); }
/* the lede is the one line that has to land, so it is set nearer the
   headline's weight than the answers' - not body copy with a bigger size */
.lprob__lede {
  max-width: 42ch;
  margin: 0;
  font-size: clamp(16px, 1.7vw, 18.5px);
  font-weight: 500;
  line-height: 1.6;
  color: var(--muted-d);
}

/* The standfirst - the paragraphs that set the argument up before the list
   starts making it. Two columns because a single measure this long reads as
   the page's main text, and it is not: the entries below are. Splitting it
   keeps it looking like the preamble it is. */
.lprob__stand {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(14px, 3vw, 54px);
  max-width: 1020px;
  margin: clamp(24px, 3.4vh, 40px) 0 clamp(34px, 5vh, 62px);
}
.lprob__stand p {
  margin: 0;
  font-size: 15.5px;
  line-height: 1.82;
  color: var(--muted-d);
}
@media (max-width: 767.98px) {
  .lprob__stand { grid-template-columns: 1fr; gap: 14px; }
}

.lprob__list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line-d);
}
.lprob__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1.12fr) minmax(0, 1fr);
  align-items: start;
  gap: clamp(18px, 3.4vw, 58px);
  padding: clamp(26px, 3.6vw, 46px) 0;
  border-bottom: 1px solid var(--line-d);
}
/* Big and nearly out - it is a position in a list, not a value, and at full
   ink it would be competing with the sentence it is only numbering. The
   accent is held back for the hover, which is the one moment the row is
   being singled out. */
.lprob__n {
  font-size: clamp(1.9rem, 3.2vw, 2.9rem);
  font-weight: 800;
  line-height: .9;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
  color: rgba(20,21,27,.14);
  transition: color .3s ease;
}
.lprob__row:hover .lprob__n { color: rgba(244,129,32,.55); }

.lprob__q {
  margin: 0;
  font-size: clamp(1.3rem, 2.5vw, 2rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.025em;
  text-wrap: balance;
}
/* raised off the baseline of the problem rather than level with it: the
   answer is a reply, and a reply that starts on the same line reads as the
   second half of the sentence instead */
.lprob__a {
  margin: 0;
  padding-top: clamp(2px, .6vw, 8px);
  font-size: 15.5px;
  line-height: 1.8;

}

@media (max-width: 991.98px) {
  /* the number keeps its own column and the two halves stack under the
     problem, so the hanging figures still run down the left edge */
  .lprob__row {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 14px clamp(16px, 3vw, 26px);
  }
  .lprob__a { grid-column: 2; padding-top: 0; }
  .lprob__head { max-width: 440px; }
}
@media (max-width: 575.98px) {
  .lprob__title { font-size: 2rem; }
  .lprob__lede { font-size: 15.5px; }
  .lprob__q { font-size: 1.22rem; }
  .lprob__a { font-size: 15px; }
  .lprob__n { font-size: 1.6rem; }
}



/* ==================== LEAD & SALES: WHAT IS IN IT =====================
   The specifics, after five hundred words of argument. Two tracks rather
   than .lprob's three, and the stage name carried in display type on the
   left instead of a figure - same editorial grammar, a different rhythm,
   so the two runs are not mistaken for one long list.

   The detail lands as a dotted run of names rather than ticks in a grid.
   A buyer checking whether their dialler or their import format is in
   there is scanning for one word, and a word is found faster in a line of
   them than in twenty boxes with a mark in the corner of each. */
.lcap {
  position: relative;
  overflow-x: clip;
  padding: clamp(58px, 8.5vh, 118px) 0 clamp(64px, 9vh, 120px);
  background: var(--bg);
}
.lcap__head { max-width: 640px; margin: 0 0 clamp(30px, 4.5vh, 56px); }
.lcap__title {
  margin: 0 0 16px;
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -.03em;
}
.lcap__title em { font-style: normal; color: var(--accent); }
.lcap__lede {
  max-width: 52ch;
  margin: 0;
  font-size: clamp(15.5px, 1.6vw, 17.5px);
  line-height: 1.72;
  color: rgba(255,255,255,.6);
}

.lcap__list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--line);
}
.lcap__row {
  display: grid;
  grid-template-columns: minmax(0, .52fr) minmax(0, 1.48fr);
  align-items: start;
  gap: clamp(16px, 3.4vw, 54px);
  padding: clamp(26px, 3.6vw, 44px) 0;
  border-bottom: 1px solid var(--line);
}
.lcap__label {
  display: block;
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}
.lcap__h {
  margin: 0;
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  font-weight: 700;
  line-height: 1.22;
  letter-spacing: -.025em;
  text-wrap: balance;
}
.lcap__body p {
  margin: 0 0 16px;
  font-size: 15.5px;
  line-height: 1.8;
  color: rgba(255,255,255,.62);
}
/* The separators are drawn rather than typed. A middot in the markup would
   take the text's own colour and sit on its baseline; this one carries the
   accent at a fraction of the weight and centres on the x-height, which is
   what lets a run this long stay quiet enough to scan. */
.lcap__specs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 0;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 13.5px;
  line-height: 1.7;
  color: rgba(255,255,255,.5);
}
.lcap__specs li:not(:last-child)::after {
  content: "";
  display: inline-block;
  width: 3px;
  height: 3px;
  margin: 0 10px;
  border-radius: 50%;
  background: rgba(244,129,32,.55);
  vertical-align: middle;
}

@media (max-width: 767.98px) {
  .lcap__row { grid-template-columns: 1fr; gap: 14px; }
}
@media (max-width: 575.98px) {
  .lcap__title { font-size: 1.9rem; }
  .lcap__lede { font-size: 15px; }
  .lcap__h { font-size: 1.2rem; }
  .lcap__specs { font-size: 13px; }
}


/* ===================== LEAD & SALES: WHO SIGNS IN =====================
   Five short entries with the role as a lead-in rather than a heading -
   a glossary, essentially. Nobody reads this section top to bottom; they
   look for their own job, read four lines and move on, and a run of bold
   lead-ins is the fastest shape there is for finding one word.

   Two columns, and the entries flow down the first before the second so
   the reading order survives when the grid collapses. */
.lwho {
  --ink-d:   #14151b;
  --muted-d: #5c6170;
  --line-d:  rgba(20,21,27,.13);
  position: relative;
  overflow-x: clip;
  padding: clamp(58px, 8.5vh, 118px) 0 clamp(64px, 9vh, 120px);
  background: #fff;
  color: var(--ink-d);
}
.lwho__head { max-width: 620px; margin: 0 0 clamp(28px, 4vh, 50px); }
.lwho__title {
  margin: 0 0 16px;
  font-size: clamp(2rem, 4.4vw, 3.1rem);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -.03em;
}
.lwho__title em { font-style: normal; color: var(--accent); }
.lwho__lede {
  max-width: 52ch;
  margin: 0;
  font-size: clamp(15.5px, 1.6vw, 17.5px);
  line-height: 1.72;
  color: var(--muted-d);
}

/* A grid, not CSS columns. Column flow would give the two halves their own
   run of heights and the rules across the top of each entry would then line
   up with nothing on the other side - on a page whose only structure is
   hairlines, that is the one thing they cannot be allowed to do. */
.lwho__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(20px, 2.8vw, 34px) clamp(24px, 4.5vw, 76px);
  margin: 0;
  padding: 0;
  list-style: none;
}
.lwho__list li {
  margin: 0;
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid var(--line-d);
  font-size: 15.5px;
  line-height: 1.8;
  color: var(--muted-d);
}
.lwho__list b {
  color: var(--ink-d);
  font-weight: 700;
}

@media (max-width: 767.98px) {
  .lwho__list { grid-template-columns: 1fr; }
}
@media (max-width: 575.98px) {
  .lwho__title { font-size: 1.9rem; }
  .lwho__lede { font-size: 15px; }
  .lwho__list li { font-size: 15px; }
}

/* ===================== LEAD & SALES: THE CLOSING LINE ==================
   One sentence at headline size and the two buttons under it. No panel,
   no shot, no list of ticks - the page has just spent five entries being
   specific, and the thing that closes it should be the only claim on the
   page that is allowed to be broad.

   It sits on the site's own ground rather than a shade off it: there is
   nothing above it to be told apart from, and a band here would put a box
   back into a page built on not having any. */
.lline {
  position: relative;
  overflow-x: clip;
  padding: clamp(66px, 11vh, 150px) 0;
  background: var(--bg);
}

.lline__say {
  margin: 0 0 clamp(30px, 4.5vh, 52px);
  font-size: clamp(1.8rem, 4.4vw, 3.4rem);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -.03em;
  text-wrap: balance;
}
.lline__say em { font-style: normal; color: var(--accent); }

.lline__btns {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.lline__btn {
  display: inline-flex;
  align-items: center;
  padding: 13px 26px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink);
  transition: border-color .25s ease, color .25s ease, background .25s ease;
}
.lline__btn:hover { border-color: var(--accent); color: var(--accent); }
.lline__btn:focus-visible { outline: 0; box-shadow: 0 0 0 .25rem var(--bs-focus-ring-color); }
.lline__btn--solid {
  border-color: var(--accent);
  background: var(--accent);
  color: #140d05;
}
.lline__btn--solid:hover {
  border-color: var(--accent-hi);
  background: var(--accent-hi);
  color: #140d05;
}

@media (max-width: 991.98px) { .lline__in { max-width: 620px; } }
@media (max-width: 575.98px) {
  .lline__in { max-width: none; }
  .lline__say { font-size: 1.75rem; }
  .lline__btn { flex: 1 1 100%; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  [data-rise] { opacity: 1; transform: none; transition: none; }
  .gbtn { transition: none; }
  .fund__track { animation: none; }
  .sup__rot b { animation: none; }
  .sup__rot b:not(:first-child) { display: none; }
  .sup__rot b:first-child { opacity: 1; transform: none; }
  .faq__panel { transition: none; }
  .ahero__word { animation: none; opacity: .5; }
  /* the clip is the biggest movement on the page - drop it and the still
     underneath carries the banner on its own */
  .ahero__media { display: none; }
}

/* =================================================================
   Stub pages (CMS)
   The menu destinations exist as CMS pages before their copy does.
   They sit on plain ground under the fixed bar and borrow the hero's
   type scale so a half-written site still reads as the same site.
   ================================================================= */
.vast-stub {
  padding: calc(var(--nav-h) + clamp(48px, 9vh, 120px)) 0 clamp(56px, 10vh, 140px);
}
.vast-stub__title {
  margin: 0 0 .6em;
  font-size: clamp(2rem, 1.2rem + 3.2vw, 3.6rem);
  font-weight: 800;
  line-height: 1.06;
  letter-spacing: -.02em;
}
.vast-stub__lead {
  max-width: 62ch;
  margin: 0 0 1.2em;
  font-size: clamp(1.02rem, .96rem + .4vw, 1.22rem);
  line-height: 1.62;
  opacity: .9;
}
.vast-stub__note {
  max-width: 62ch;
  margin: 0;
  font-size: .98rem;
  line-height: 1.7;
  opacity: .66;
}
.vast-stub__note a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: .18em;
}
.vast-stub__note a:hover { color: var(--accent-hi); }

/* The CMS holds its public <main> to `calc(100vh - 60px)` (Blazor CSS
   isolation, `.public-main[b-...]`) so its own short footer still lands at
   the bottom of the screen. This theme's footer is ~850px on its own, so
   every page already runs past the fold, and that floor only shows up as a
   band of dead ground between a short page and the footer. Scoped to
   .vast-ready — the class the theme JS sets once it has installed — so it
   applies only where this chrome is actually in place, and outranks the
   isolation rule by one element. */
html.vast-ready .public-main { min-height: 0; }

/* =================================================================
   Block previews in /admin/pages/designer
   Each block is previewed in a srcdoc iframe that loads this file but
   runs no JavaScript, so the dark ground and Bootstrap's dark palette —
   both set by the theme's JS on the real site — never arrive, and the
   iframe's own inline rule paints the page white. Sections then preview
   as pale-on-white and read as broken.

   The real site always carries data-bs-theme (the theme JS sets it before
   first paint), so :not([data-bs-theme]) targets the preview alone.
   !important is needed only because the iframe's white background is
   declared in a <style> after every <link>.
   ================================================================= */
html:not([data-bs-theme]) {
  color-scheme: dark;
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--ink);
  --bs-emphasis-color: #fff;
}
html:not([data-bs-theme]),
html:not([data-bs-theme]) body {
  background: var(--bg) !important;
  color: var(--ink) !important;
}

/* =================================================================
   CMS blocks on interior pages
   A page assembled from the designer's own palette renders as generic
   Bootstrap inside <article class="article-content">. The homepage is
   exempt — it renders in .article-content-home and carries its own
   section styles — so everything here is scoped to the interior wrapper
   and re-skins those blocks in the theme's tokens, which means anything
   added in /admin/pages/designer lands on-brand without further work.
   ================================================================= */

/* the column the CMS does not provide: clear the fixed bar, then centre
   on the same shell width and gutter the themed sections use */
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) {
  padding: calc(var(--nav-h) + clamp(48px, 9vh, 120px)) 0 clamp(56px, 10vh, 140px);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) > .page-content {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h1,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h2,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h3,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h4 {
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.08;
  margin: 0 0 .6em;
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h1 { font-size: clamp(2rem, 1.2rem + 3.2vw, 3.6rem); }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h2 { font-size: clamp(1.6rem, 1.1rem + 2.2vw, 2.6rem); }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) h3 { font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem); }

html.vast-ready .page-block-paragraph p,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) li {
  max-width: 72ch;
  line-height: 1.68;
  color: rgba(238, 241, 248, .88);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) a { color: var(--accent); }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) a:hover { color: var(--accent-hi); }

/* surfaces borrow the theme's hairline and a barely-there lift, the same
   treatment the homepage cards use */
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .card,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .accordion-item,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-control,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-select {
  background: rgba(255, 255, 255, .04);
  border-color: var(--line);
  color: var(--ink);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .table {
  --bs-table-color: var(--ink);
  --bs-table-bg: transparent;
  --bs-table-border-color: var(--line);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) hr { border-color: var(--line); opacity: 1; }

/* Stats counters and the CTA banner ship `style="background:#0d6efd"` on the
   element itself, so a stylesheet only reaches them with !important. */
html.vast-ready .page-block-stats,
html.vast-ready .page-block-cta-banner {
  background: linear-gradient(135deg, rgba(244,129,32,.16), rgba(244,129,32,.04)) !important;
  border: 1px solid var(--line);
  color: var(--ink) !important;
}
html.vast-ready .page-block-stats h1,
html.vast-ready .page-block-stats h2,
html.vast-ready .page-block-cta-banner h1,
html.vast-ready .page-block-cta-banner h2 { color: #fff; }

/* =================================================================
   Suppress the CMS's own chrome before it can paint
   The server always renders <header class="st-header"> (and its stock
   footer) into the document; the theme JS reads the menu out of that
   header, then replaces both with the VAST CRM navbar and footer. Until
   that runs, the stock header painted for a frame or two — a flash of
   "CMS Demo" on every page load.

   Hiding it here means it never paints, while staying in the DOM for the
   JS to read: display:none does not hide an element's text or attributes
   from script. The navbar that replaces it is position:fixed, so nothing
   reflows when it arrives.
   ================================================================= */
header.st-header,
/* The footer is no longer injected by the theme JS — it lives in the CMS,
   on the Footer layout page (admin: More > Footer), so it can be edited
   there. The CMS wraps those blocks in `footer.st-footer > .container-fluid`
   (plus its own `.page-content` > `.page-block-rawhtml`), and the stored
   markup opens with `div.foot`, so the wrappers are flattened and the
   theme’s own .foot rules take over unchanged. */
footer.st-footer { padding: 0; margin: 0; background: transparent; border: 0; }
footer.st-footer > .container-fluid { padding: 0; margin: 0; max-width: none; width: 100%; }
/* The CMS appends its own `site.footer.copyright` line, and a rule above it,
   AFTER the footer blocks — having blocks does not suppress them. The stored
   footer already ends with its own .foot__bar, so the CMS pair is hidden here
   rather than blanked, which keeps the text in the admin field. */
footer.st-footer > .container-fluid > hr,
footer.st-footer > .container-fluid > .small.text-secondary { display: none; }

/* Bootstrap's own primary leaks through the blocks — icon-list bullets use
   .text-primary, buttons use .btn-primary — and lands Bootstrap blue on an
   orange site. Rebinding the variable inside the interior wrapper recolours
   every one of them at once. */
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) {
  --bs-primary: var(--accent);
  --bs-primary-rgb: 244, 129, 32;
  --bs-link-color: var(--accent);
  --bs-link-hover-color: var(--accent-hi);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .text-primary { color: var(--accent) !important; }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #1a1205;
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .btn-primary:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
}

/* accordion: Bootstrap's dark default is a flat slab; give it the theme's
   hairline and let the open row carry a hint of the accent */
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .accordion {
  --bs-accordion-bg: transparent;
  --bs-accordion-border-color: var(--line);
  --bs-accordion-color: var(--ink);
  --bs-accordion-btn-color: var(--ink);
  --bs-accordion-btn-bg: rgba(255,255,255,.03);
  --bs-accordion-active-bg: rgba(244,129,32,.10);
  --bs-accordion-active-color: #fff;
  --bs-accordion-btn-focus-box-shadow: 0 0 0 .2rem rgba(244,129,32,.25);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .accordion-button { font-weight: 600; }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .accordion-body { color: rgba(238,241,248,.85); }

/* icon-list rows: give the bullet and its text a little more air */
html.vast-ready .page-block-icon-list .row > .col { margin-bottom: .35rem; }
html.vast-ready .page-block-icon-list .bi { color: var(--accent); }

/* The contact block's heading and field labels inherit Bootstrap's light-mode
   ink, which on this ground reads as barely-there grey. */
html.vast-ready .page-block-contact h2,
html.vast-ready .page-block-contact h3,
html.vast-ready .page-block-contact .h2,
html.vast-ready .page-block-contact .h3 { color: var(--ink); }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-label {
  color: rgba(238, 241, 248, .82);
  font-weight: 600;
  font-size: .92rem;
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-control::placeholder { color: rgba(238, 241, 248, .38); }
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-control:focus,
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-select:focus {
  background: rgba(255, 255, 255, .06);
  border-color: var(--accent);
  color: var(--ink);
  box-shadow: 0 0 0 .2rem rgba(244, 129, 32, .22);
}
html.vast-ready .article-content:not(:has(> .page-content > .page-block-rawhtml)) .form-text { color: rgba(238, 241, 248, .6); }



/* =================================================================
   Native designer blocks wearing the theme's own section classes
   Each block carries the original section class through its CssClass
   prop, so the block below is `.phero > .page-block-hero`. The theme's
   own .phero rules then apply to the box; only the inner element
   names differ (the block emits .hero-title where the hand-written
   markup had .phero__title), so this layer maps one onto the other
   rather than restating the design.
   ================================================================= */

/* the block paints its background into a .hero-bg div instead of ::before,
   so the theme's own backdrop is switched off and the div takes the crop */
.phero > .page-block-hero::before,
.phero > .page-block-hero::after { content: none; }
.page-content > .phero { position: relative; }
.phero > .page-block-hero {
  padding: calc(var(--nav-h) + clamp(16px, 2.4vh, 32px)) 0 clamp(20px, 3.2vh, 38px);
  border-radius: 0;
}
.phero > .page-block-hero .hero-bg { background-position: right center; z-index: 0; }
.phero > .page-block-hero .hero-overlay {
  z-index: 1;
  background: linear-gradient(to right, rgba(0,0,0,.85) 0%, rgba(0,0,0,.45) 34%, transparent 62%) !important;
}
/* .hero-inner is the block's answer to `.phero > .container-xxl > .phero__in`,
   so it takes the page gutter and the copy's own 720px ceiling at once */
.phero > .page-block-hero .hero-inner {
  max-width: calc(720px + var(--gutter) * 2);
  margin: 0;
  padding-inline: var(--gutter);
  align-items: flex-start;
  text-align: left;
}
.phero > .page-block-hero .hero-title {
  margin: 0 0 14px;
  font-size: clamp(2.2rem, 5.4vw, 3.8rem);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -.03em;
}
.phero > .page-block-hero .hero-title em { font-style: normal; color: var(--accent); }
.phero > .page-block-hero .hero-subtitle {
  max-width: 56ch;
  margin: 0;
  font-size: clamp(15px, 1.5vw, 17px);
  line-height: 1.7;
  color: rgba(255, 255, 255, .68);
  opacity: 1;
}
.phero > .page-block-hero .hero-eyebrow:empty { display: none; }
.phero > .page-block-hero .hero-actions:empty { display: none; }

/* =================================================================
   Interior pages that open without a hero
   The source marked these with `class="page"` on <main>, whose one job
   was `padding-top: var(--nav-h)` — it holds the content clear of the
   fixed bar. The port keeps only what was inside <main>, so that class
   went with the wrapper and these pages slid up under the navbar: blog,
   blog-details, faq, pricing and the two legal pages, every one of them
   opening on white, so the white logo landed on white.

   Hero sections carry their own `calc(var(--nav-h) + …)` padding, and
   every hero class here contains "hero" (ahero, phero, thero, dhero,
   lhero) — so keying on its absence in the first block restores the
   spacing for exactly the pages that lost it.
   ================================================================= */
html.vast-ready .article-content:has(> .page-content > .page-block-rawhtml:first-child > :not([class*="hero"])) {
  padding-top: var(--nav-h);
}

/* =================================================================
   Block previews in the page designer: show the design, not a blank box
   The designer previews each block in a srcdoc iframe that loads this
   stylesheet but runs NO JavaScript. The theme reveals content on scroll
   — `[data-rise]` starts at opacity 0 and waits for the `.is-in` class
   that main.js adds — so in the preview every one of those stayed
   invisible and the block read as an empty box. Every ported section
   uses data-rise, so that was all of them.

   The preview drops the block's own markup straight into <body>, while
   the live page always nests it under main > article > .page-content.
   Keying on that keeps these rules out of the real site entirely, so the
   scroll reveal there is untouched — important, because a rule that also
   matched the live page before its JS ran would flash the content in and
   then animate it back.

   Motion that would otherwise sit mid-animation forever is settled the
   same way the theme's own prefers-reduced-motion block settles it.
   ================================================================= */
body > section [data-rise],
body > article [data-rise],
body > div [data-rise],
body > section[data-rise],
body > article[data-rise],
body > div[data-rise] {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}
body > section .fund__track,
body > article .fund__track { animation: none; }
body > section .sup__rot b,
body > article .sup__rot b { animation: none; }
body > section .sup__rot b:not(:first-child),
body > article .sup__rot b:not(:first-child) { display: none; }
body > section .sup__rot b:first-child,
body > article .sup__rot b:first-child { opacity: 1; transform: none; }

/* =================================================================
   The CMS's own blog, in the theme's clothes
   Posts now live in the Blogs module, so three surfaces are the CMS's
   markup rather than ported sections: the BlogList block on
   /company/blog, the full listing at /listblogs, and each post at
   /blogs/<slug>. All three ship Bootstrap defaults, which read as a
   different site on this dark ground. Both listings use the same
   .blog-card* classes, so one card rule covers them.
   ================================================================= */

/* Neither CMS route sits inside .article-content, so the interior padding
   rule never reaches them. The detail page brings a .banner-padding spacer
   the theme does not style; the listing brings nothing at all. */
html.vast-ready .blogs-page { padding-top: calc(var(--nav-h) + clamp(28px, 5vh, 64px)); }
html.vast-ready .banner-padding { height: var(--nav-h); }

/* ---- listing header + toolbar ---- */
html.vast-ready .blogs-header { text-align: left; margin-bottom: clamp(24px, 4vh, 44px); }
html.vast-ready .blogs-eyebrow {
  display: inline-block;
  color: var(--accent);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin-bottom: .6rem;
}
html.vast-ready .blogs-title {
  font-size: clamp(2rem, 1.2rem + 3.2vw, 3.4rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.08;
  margin: 0 0 .5rem;
}
html.vast-ready .blogs-title .bi { display: none; }          /* the stock journal icon is off-brand */
html.vast-ready .blogs-subtitle { color: rgba(238,241,248,.7); max-width: 62ch; margin: 0; }
html.vast-ready .blogs-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  align-items: center;
  justify-content: space-between;
  padding: .9rem 0 1.4rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(20px, 3vh, 34px);
}
html.vast-ready .blogs-toolbar-categories { display: flex; flex-wrap: wrap; gap: .5rem; }
html.vast-ready .blogs-chip {
  display: inline-flex;
  align-items: center;
  padding: .38rem .9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  color: rgba(238,241,248,.8);
  font-size: .86rem;
  font-weight: 600;
  text-decoration: none;
}
html.vast-ready .blogs-chip:hover { border-color: var(--accent); color: var(--accent); }
html.vast-ready .blogs-chip.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #1a1205;
}
html.vast-ready .blogs-sort-label { color: rgba(238,241,248,.6); font-size: .86rem; margin-right: .5rem; }
html.vast-ready .blogs-sort-select {
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  padding: .35rem .6rem;
  font-size: .88rem;
}

/* ---- cards: shared by the BlogList block and the full listing ---- */
html.vast-ready .blog-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  background: rgba(255,255,255,.035);
  transition: border-color .25s, transform .25s;
}
html.vast-ready .blog-card:hover { border-color: var(--accent); transform: translateY(-3px); }
html.vast-ready .blog-card-media { aspect-ratio: 16 / 9; overflow: hidden; }
html.vast-ready .blog-card-media_image { width: 100%; height: 100%; object-fit: cover; display: block; }
html.vast-ready .blog-card-body { padding: 1.1rem 1.15rem 1.3rem; display: flex; flex-direction: column; gap: .5rem; }
html.vast-ready .blog-card-date {
  color: #000;
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.blog-card-date {
    display: inline-block;
    background: var(--accent);
    color: #fff;
    padding: .4rem 1rem;
    border-radius: 999px;
    font-size: .82rem;
    font-weight: 600;
    margin-bottom: .9rem;
}
html.vast-ready .blog-card-title {
  margin: 0;
  font-size: 1.06rem;
  font-weight: 700;
  line-height: 1.34;
  letter-spacing: -.01em;
}
html.vast-ready .blog-card-excerpt {
  margin: 0;
  font-size: .92rem;
  line-height: 1.6;
  color: rgba(238,241,248,.7);
}
/* the stock grey category pill */
html.vast-ready .blog-card .badge,
html.vast-ready .blog-card-category {
  align-self: flex-start;
  background: rgba(244,129,32,.14) !important;
  color: var(--accent) !important;
  border: 1px solid rgba(244,129,32,.3);
  font-weight: 600;
}
html.vast-ready .blogs-empty { text-align: center; padding: clamp(40px, 8vh, 90px) 0; color: rgba(238,241,248,.7); }
html.vast-ready .blogs-empty-icon .bi { font-size: 2.4rem; color: var(--accent); opacity: .5; }
html.vast-ready .blogs-empty-title { font-weight: 700; margin-top: .8rem; }

/* ---- a single post ---- */
html.vast-ready .blog-detail { max-width: 820px; margin-inline: auto; }
html.vast-ready .blog-hero { border-radius: 16px; overflow: hidden; margin-bottom: clamp(20px, 3vh, 34px); }
html.vast-ready .blog-hero img { width: 100%; max-height: 460px; object-fit: cover; display: block; }
html.vast-ready .blog-title {
  font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3rem);
  font-weight: 800;
  letter-spacing: -.02em;
  line-height: 1.12;
}
html.vast-ready .blog-detail .breadcrumb { --bs-breadcrumb-divider-color: rgba(238,241,248,.4); }
html.vast-ready .blog-detail .breadcrumb a { color: rgba(238,241,248,.7); }
html.vast-ready .blog-detail .breadcrumb a:hover { color: var(--accent); }
html.vast-ready .blog-detail .breadcrumb-item.active { color: rgba(238,241,248,.55); }
html.vast-ready .blog-body { font-size: 1.02rem; line-height: 1.75; color: rgba(238,241,248,.88); }
html.vast-ready .blog-body h2 { font-size: clamp(1.4rem, 1.1rem + 1.2vw, 1.9rem); font-weight: 800; margin: 2em 0 .6em; }
html.vast-ready .blog-body h3 { font-size: 1.22rem; font-weight: 700; margin: 1.7em 0 .5em; }
html.vast-ready .blog-body a { color: var(--accent); }
html.vast-ready .blog-body img { border-radius: 12px; margin: 1.4em 0; }
html.vast-ready .blog-body blockquote {
  border-left: 3px solid var(--accent);
  padding-left: 1.1rem;
  margin: 1.6em 0;
  color: var(--ink);
}
html.vast-ready .bd-side-card { background: rgba(255,255,255,.04); border-color: var(--line); }
html.vast-ready .bd-side-title { color: rgba(238,241,248,.6); }

/* ---- blog text colours -------------------------------------------
   The CMS renders these two surfaces with Bootstrap's own ink, which on
   this dark ground reads as grey-on-grey or disappears. A base colour on
   the wrappers catches anything not named below, so a future CMS update
   that adds an element still lands readable rather than invisible. */
html.vast-ready .bd,
html.vast-ready .blog-detail,
html.vast-ready .blogs-page { color: var(--ink); }

/* the date beside the post title */
html.vast-ready .blog-date {
  color: var(--accent);
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* the category pill: Bootstrap ships it as bg-secondary-subtle +
   text-secondary-emphasis, both of which are light-mode values */
html.vast-ready .blog-category,
html.vast-ready .blog-detail .badge {
  background: rgba(244, 129, 32, .14) !important;
  color: var(--accent) !important;
  border: 1px solid rgba(244, 129, 32, .3);
  font-weight: 600;
}

/* buttons on the post page follow the theme's accent, not Bootstrap blue */
html.vast-ready .bd .btn-outline-primary,
html.vast-ready .blog-detail .btn-outline-primary {
  --bs-btn-color: var(--accent);
  --bs-btn-border-color: rgba(244, 129, 32, .5);
  --bs-btn-hover-bg: var(--accent);
  --bs-btn-hover-border-color: var(--accent);
  --bs-btn-hover-color: #1a1205;
}
/* `btn_style` is the CMS's own back-link class and the theme does not
   define it, so it would otherwise inherit whatever Bootstrap last set */
html.vast-ready .blog-detail .btn_style,
html.vast-ready .bd .btn_style {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: var(--accent);
  font-weight: 600;
  text-decoration: none;
}
html.vast-ready .blog-detail .btn_style:hover,
html.vast-ready .bd .btn_style:hover { color: var(--accent-hi); }

html.vast-ready .bd hr,
html.vast-ready .blog-detail hr { border-color: var(--line); opacity: 1; }

/* the post title also carries the CMS's .page-title, which the theme has
   no rule for; keep it on the theme's heading scale */
html.vast-ready .blog-title.page-title { color: var(--ink); }

/* the BlogList block's own heading */
html.vast-ready .page-block-blog-list > .h4,
html.vast-ready .page-block-blog-list > h3 {
  color: var(--ink);
  font-weight: 800;
  letter-spacing: -.01em;
}
/* Removed 2026-09-16: five unscoped `color: #fff` rules (.blog-body h1/h2,
   .blog-body h3, .post__list li, .blog-body strong, .post__list b) that were
   added while the blog rendered as `article.post` on the dark ground. Two of
   them were never blog-specific — `.post__list` is the bullet list on every
   white legal/article page, so its text was white on white and simply did
   not appear. The blog is now the CMS Blogs module on a white ground, so all
   five were wrong in both places. The source rules further up this file
   (.post__list li { color: #2b2e39 }) are correct on their own. */
/* ---- tables inside a blog post -----------------------------------
   `.post__table` was written for the site's white article sections, so it
   reaches for the light-section tokens: `--line-d` is a near-black hairline
   and `--muted-d` a dark grey. The blog detail page is not a `.post`
   section — it renders in `.bd > .blog-detail` on the dark ground — so
   those tokens fall back to their :root values and the table came out with
   an invisible border and grey-on-grey cells.

   Head goes accent with black ink, every rule accent, and the cell text
   back to the theme's own. Plain <table> is covered alongside the themed
   class so a table pasted into the editor gets the same treatment.
   ================================================================= */
html.vast-ready .blog-body .post__tablewrap,
html.vast-ready .blog-body table {
  border: 1px solid var(--accent);
  border-radius: 12px;
}
html.vast-ready .blog-body .post__tablewrap > table { border: 0; border-radius: 0; }
html.vast-ready .blog-body table { border-collapse: collapse; width: 100%; }

html.vast-ready .blog-body .post__table thead th,
html.vast-ready .blog-body table thead th {
  background: var(--accent);
  color: #000;
  border-color: var(--accent);
}
html.vast-ready .blog-body .post__table th,
html.vast-ready .blog-body .post__table td,
html.vast-ready .blog-body table th,
html.vast-ready .blog-body table td { border: 1px solid var(--accent); }

/* the cells themselves: light-section ink would be unreadable here */
html.vast-ready .blog-body .post__table td,
html.vast-ready .blog-body table td { color: rgba(238, 241, 248, .88); }
html.vast-ready .blog-body .post__table tbody th,
html.vast-ready .blog-body table tbody th { color: var(--ink); }

/* ---- blog headings: white by default, accent on hover -------------
   The card titles sit inside the card's own <a>, so they were taking
   whatever colour that link resolved to rather than a colour of their
   own. Stating it here means they no longer depend on inheritance —
   and the hover lives on the card, so pointing anywhere on a card
   lights its title, not just the words themselves. */
html.vast-ready .blog-card-title,
html.vast-ready .blog-card .blog-card-title,
html.vast-ready .blog-title,
html.vast-ready .blog-title.page-title { color: #fff; }

html.vast-ready .blog-card:hover .blog-card-title,
html.vast-ready .blog-card:focus-visible .blog-card-title { color: #f48120; }

/* headings written inside a post body follow the same default */
html.vast-ready .blog-body h1,
html.vast-ready .blog-body h2,
html.vast-ready .blog-body h3,
html.vast-ready .blog-body h4,
html.vast-ready .blog-body h5,
html.vast-ready .blog-body h6 { color: #fff; }

/* a heading that is itself a link (some article markup wraps them) */
html.vast-ready .blog-body :is(h1,h2,h3,h4,h5,h6) a { color: #fff; }
html.vast-ready .blog-body :is(h1,h2,h3,h4,h5,h6) a:hover { color: #f48120; }

/* ---- the frame around a post's hero image -------------------------
   default.css (the CMS's own public stylesheet) frames the hero in a
   light card: `background:#f6f6f6` with 20px of padding and a rounded
   corner. On this dark ground that reads as a white slab around the
   artwork, so the frame keeps its shape and takes the accent instead. */
html.vast-ready .blog-hero {
  background: #f48120;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .25);
}

/* the one blog string default.css styles that the theme had not reached:
   shown only when a category has no posts in it */
html.vast-ready .blogs-empty-body { color: rgba(238, 241, 248, .7); }

/* =================================================================
   Pasted blog bodies
   Content written or pasted through the editor arrives carrying inline
   styles — its own colours, and a table built from <div>s with
   display:table / table-row / table-cell rather than a real <table>.
   Inline styles beat any stylesheet, so everything here needs
   !important. It is scoped to .blog-body, so only post content is
   touched, and it keys on the shape of the markup rather than on
   classes (there are none) — which means the next post pasted the same
   way is styled on arrival, without anyone editing CSS again.
   ================================================================= */

/* 1. hand every inline text colour back to the theme's cascade */
html.vast-ready .blog-body [style*="color"] { color: inherit !important; }

/* 2. then restate the theme's own, which step 1 cleared the way for */
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6),
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6) * { color: #fff !important; }
html.vast-ready .blog-body a,
html.vast-ready .blog-body a * { color: var(--accent) !important; }
html.vast-ready .blog-body a:hover,
html.vast-ready .blog-body a:hover * { color: var(--accent-hi) !important; }

/* 3. the div-table. `display: table;` carries the semicolon, so it picks
      out the container without also matching table-row / table-cell. */
html.vast-ready .blog-body [style*="display: table;"] {
  background: transparent !important;
  border: 1px solid var(--accent) !important;
  border-radius: 12px;
  overflow: hidden;
  margin: 1.6em 0;
}
html.vast-ready .blog-body [style*="display: table-cell"] {
  border-color: var(--accent) !important;
  vertical-align: top;
}
/* a row that brought its own background is the header row */
html.vast-ready .blog-body [style*="display: table-row"][style*="background"] {
  background: var(--accent) !important;
}
html.vast-ready .blog-body [style*="display: table-row"][style*="background"],
html.vast-ready .blog-body [style*="display: table-row"][style*="background"] * {
  color: #000 !important;
}

/* 4. real <table> markup gets the same treatment, so it does not matter
      which of the two the editor happens to produce */
html.vast-ready .blog-body table {
  background: transparent !important;
  border: 1px solid var(--accent) !important;
  border-collapse: collapse;
  width: 100%;
  margin: 1.6em 0;
}
html.vast-ready .blog-body table :is(th, td) { border: 1px solid var(--accent) !important; padding: 14px; }
html.vast-ready .blog-body table thead th,
html.vast-ready .blog-body table thead th * {
  background: var(--accent) !important;
  color: #000 !important;
}

/* 5. lists and plain copy keep the theme's reading colour */
html.vast-ready .blog-body :is(p, li, span, div):not([style*="display: table"]) { color: inherit; }
html.vast-ready .blog-body :is(ul, ol) { padding-left: 1.3rem; }
html.vast-ready .blog-body li { margin-bottom: .4em; }

/* ---- pasted bodies: font, weight and reading colour ---------------
   Pasted content brings its own typeface (Poppins on this post, Arial
   on the table) and leans heavy — `bolder`, `700` and `bold` across
   most of the copy. All of it is inline, so the theme's own face never
   got a look in. Same approach as the colours above: key on the markup,
   not on classes, so the next paste is handled too. */

/* the project's own face, everywhere in a post body */
html.vast-ready .blog-body,
html.vast-ready .blog-body * { font-family: var(--font) !important; }

/* lighter overall: body copy back to a normal weight, and the inline
   bold/bolder/700 eased to a semibold that still reads as emphasis */
html.vast-ready .blog-body :is(p, li, span, div, td, th) { font-weight: 400 !important; }
html.vast-ready .blog-body :is(b, strong),
html.vast-ready .blog-body [style*="font-weight: bold"],
html.vast-ready .blog-body [style*="font-weight: bolder"],
html.vast-ready .blog-body [style*="font-weight: 700"],
html.vast-ready .blog-body [style*="font-weight: 800"],
html.vast-ready .blog-body [style*="font-weight: 900"] { font-weight: 600 !important; }

/* headings come down a step too, so the page stops shouting */
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6) { font-weight: 700 !important; }
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6) :is(span, b, strong) { font-weight: inherit !important; }

/* the table header keeps its emphasis against the accent band */
html.vast-ready .blog-body [style*="display: table-row"][style*="background"],
html.vast-ready .blog-body [style*="display: table-row"][style*="background"] * { font-weight: 600 !important; }

/* reading colour: off-white rather than the near-white it was */
html.vast-ready .blog-body { color: #d8dde6; }
html.vast-ready .blog-body :is(p, li, span, div):not([style*="display: table-row"]):not([style*="display: table;"]) { color: inherit; }

/* the blanket font rule above would also flatten a code block, so give
   those back their monospace face if a post ever carries one */
html.vast-ready .blog-body :is(code, pre, kbd, samp),
html.vast-ready .blog-body :is(code, pre, kbd, samp) * {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace !important;
}

/* ---- pasted bodies: stray backgrounds and the table's outer edge --- */

/* Pasted links and spans sometimes carry a background of their own — the
   contact link in this post came through with `background-color: #fff`,
   a white slab on a dark page. Anything that is part of the table keeps
   its background (handled above); everything else gives it up. */
html.vast-ready .blog-body [style*="background"]:not([style*="display: table"]) {
  background: transparent !important;
}

/* The container carries `border-collapse: collapse` inline, which folds its
   own border into the edge cells, so the table had no outer edge of its
   own. A ring drawn with box-shadow sits outside that mechanism entirely —
   it follows the rounded corner and does not double the inner gridlines
   the way switching to `separate` would. */
html.vast-ready .blog-body [style*="display: table;"] {
  box-shadow: 0 0 0 1px var(--accent);
}


/* =================================================================
   Blog surfaces on white
   The blog listing and a post sit on white, the same treatment the site's
   own article and legal sections use (`.post` — a #fff ground with the
   --ink-d / --muted-d / --line-d tokens). Everything here flips the dark
   rules set above, and comes last so it wins at equal specificity.

   Both wrappers are already full-width (`section.container-fluid` on the
   listing, a plain `div` on a post), so the white needs no bleed trick.

   Post bodies are still matched by the SHAPE of the pasted markup rather
   than by class, so a post written later lands on this without anyone
   touching CSS.
   ================================================================= */
html.vast-ready .bd,
html.vast-ready .blogs-page {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20, 21, 27, .12);
  color: var(--ink-d);
}
html.vast-ready .bd { background: #fff; }
/* The listing has no .banner-padding spacer — its own padding-top runs up
   under the fixed navbar, and the navbar is only 72% opaque, so a plain
   white background would show through it as mid-grey behind the white
   logo. Keep the first --nav-h of the ground dark, exactly as the spacer
   does on a post. */
html.vast-ready .blogs-page {
  background: linear-gradient(var(--bg) 0, var(--bg) var(--nav-h), #fff var(--nav-h));
}
html.vast-ready .blog-detail { color: var(--ink-d); }

/* ---- reading copy ---- */
html.vast-ready .blog-body { color: #2b3040; }
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6),
html.vast-ready .blog-body :is(h1, h2, h3, h4, h5, h6) * { color: var(--ink-d) !important; }
html.vast-ready .blog-body blockquote { color: var(--ink-d); }
html.vast-ready .blog-title,
html.vast-ready .blog-title.page-title { color: var(--ink-d); }
html.vast-ready .blog-date { color: #a25a10; }
html.vast-ready .blog-detail .breadcrumb { --bs-breadcrumb-divider-color: rgba(20, 21, 27, .35); }
html.vast-ready .blog-detail .breadcrumb a { color: var(--muted-d); }
html.vast-ready .blog-detail .breadcrumb a:hover { color: #a25a10; }
html.vast-ready .blog-detail .breadcrumb-item.active { color: var(--muted-d); }
html.vast-ready .bd hr,
html.vast-ready .blog-detail hr { border-color: var(--line-d); }

/* The accent itself is too light to read as text on white, so links and
   accent-coloured controls step down to a darker shade of the same hue. */
html.vast-ready .blog-body a,
html.vast-ready .blog-body a * { color: #b4620f !important; }
html.vast-ready .blog-body a:hover,
html.vast-ready .blog-body a:hover * { color: var(--accent) !important; }
html.vast-ready .blog-detail .btn_style,
html.vast-ready .bd .btn_style { color: #b4620f; }
html.vast-ready .blog-detail .btn_style:hover,
html.vast-ready .bd .btn_style:hover { color: var(--accent); }
html.vast-ready .bd .btn-outline-primary,
html.vast-ready .blog-detail .btn-outline-primary { --bs-btn-color: #b4620f; }
html.vast-ready .blog-category,
html.vast-ready .blog-detail .badge { color: #a25a10 !important; }
html.vast-ready .bd-side-card { background: #fafafb; border-color: var(--line-d); }
html.vast-ready .bd-side-title { color: var(--muted-d); }

/* ---- the table, on white ---- */
/* The container keeps its accent ring and the header row its accent band;
   only the cell ground and ink change. Both the pasted div-table and real
   <table> markup are covered, as above. */
html.vast-ready .blog-body [style*="display: table;"],
html.vast-ready .blog-body table { background: #fff !important; }
html.vast-ready .blog-body [style*="display: table-cell"],
html.vast-ready .blog-body table :is(th, td) { color: var(--ink-d) !important; }
html.vast-ready .blog-body [style*="display: table-row"][style*="background"],
html.vast-ready .blog-body [style*="display: table-row"][style*="background"] *,
html.vast-ready .blog-body table thead th,
html.vast-ready .blog-body table thead th * { color: #000 !important; }

/* ---- listing chrome ---- */
html.vast-ready .blogs-eyebrow { color: #a25a10; }
html.vast-ready .blogs-title { color: var(--ink-d); }
html.vast-ready .blogs-subtitle,
html.vast-ready .blogs-sort-label,
html.vast-ready .blogs-empty,
html.vast-ready .blogs-empty-body { color: var(--muted-d); }
html.vast-ready .blogs-toolbar { border-bottom-color: var(--line-d); }
html.vast-ready .blogs-chip { border-color: var(--line-d); color: var(--muted-d); }
html.vast-ready .blogs-chip:hover { border-color: var(--accent); color: #a25a10; }
html.vast-ready .blogs-chip.is-active { background: var(--accent); border-color: var(--accent); color: #1a1205; }
html.vast-ready .blogs-sort-select { background: #fff; border-color: var(--line-d); color: var(--ink-d); }

/* ---- cards ---- */
/* .blog-card is shared by the built-in listing and the BlogList block, and
   the block can be dropped on any page — so the light treatment is tied to
   a wrapper that is actually a blog surface, not to .blog-card itself. */
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card { background: #fff; border-color: var(--line-d); }
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card:hover { border-color: var(--accent); }
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card-title { color: var(--ink-d); }
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card:hover .blog-card-title,
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card:focus-visible .blog-card-title { color: #b4620f; }
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card-excerpt { color: var(--muted-d); }
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card .badge,
html.vast-ready :is(.blogs-page, .article-content:has(.page-block-blog-list)) .blog-card-category { color: #a25a10 !important; }

/* ---- two layout faults the white ground made obvious ---- */
/* The listing carries Bootstrap's `py-4`, and Bootstrap spacing utilities
   ship with !important — so the nav clearance set further up this file was
   never winning and the header sat under the fixed navbar. */
html.vast-ready .blogs-page { padding-top: calc(var(--nav-h) + clamp(28px, 5vh, 64px)) !important; }
/* default.css makes the title an inline-flex (to sit beside the journal
   icon the theme hides), which put it on the same line as the eyebrow. */
html.vast-ready .blogs-title { display: block; }

/* ---- the hand-built blog page ---- */
/* The user's own /blog page is an ordinary CMS page carrying a BlogList
   block, so it renders in `.article-content`, not in `.blogs-page`. Give it
   the same white ground and the same ink. Keyed on the block being present
   rather than on a path, so moving or renaming the page changes nothing. */
html.vast-ready .article-content:has(.page-block-blog-list) {
  --ink-d:   #14151b;
  --muted-d: #474b58;
  --line-d:  rgba(20, 21, 27, .12);
  background: #fff;
  color: var(--ink-d);
  padding-bottom: clamp(48px, 7vh, 96px);
}
/* `.article-content` runs up under the fixed navbar the way `.blogs-page`
   does, and the navbar is only 72% opaque — so hold the first --nav-h of
   the ground dark, or white shows through behind the white logo. */
html.vast-ready .article-content:has(.page-block-blog-list) {
  background: linear-gradient(var(--bg) 0, var(--bg) var(--nav-h), #fff var(--nav-h));
}
html.vast-ready .article-content:has(.page-block-blog-list) :is(h1, h2, h3, h4, h5, h6) { color: var(--ink-d); }
html.vast-ready .page-block-blog-list > .h4,
html.vast-ready .page-block-blog-list > h3 { color: var(--ink-d); }
/* the block's own inline <style> hardcodes light-mode greys for these */
html.vast-ready .article-content:has(.page-block-blog-list) .pbl-excerpt,
html.vast-ready .article-content:has(.page-block-blog-list) .pbl-meta { color: var(--muted-d); }
html.vast-ready .article-content:has(.page-block-blog-list) .pbl-cat { background: var(--accent); color: #1a1205; }
/* interior body copy and links are set for the dark ground further up */
html.vast-ready .article-content:has(.page-block-blog-list) .page-block-paragraph p,
html.vast-ready .article-content:has(.page-block-blog-list) li { color: #2b3040; }
html.vast-ready .article-content:has(.page-block-blog-list) a:not(.blog-card) { color: #b4620f; }
html.vast-ready .article-content:has(.page-block-blog-list) a:not(.blog-card):hover { color: var(--accent); }
/* the footer blocks arrive inside the CMS's own block wrappers */
footer.st-footer > .container-fluid > .page-content,
footer.st-footer .page-block-rawhtml { padding: 0; margin: 0; }

/* ---- First paint: no flash of the CMS header ------------------------------
   The CMS renders header.st-header (oversized logo + the whole menu as nested
   bullet lists). vastcrm.js only reads it for the menu data, then removes it,
   installs #vast-header and sets html.vast-ready. Until that runs — which is
   after first paint, because the theme JS is deferred — the raw header was
   visible for a moment on a cold load.

   So: collapse it (hidden AND zero height, or the page would paint with a tall
   blank band and then jump). The themed header is 64px and .page already
   reserves that space, so nothing moves when the swap happens.

   The animation is the safety net. If the theme JS never runs — blocked, 404,
   an error — the CMS header comes back after 2.5s and the site is still
   navigable, rather than leaving a site with no menu at all. */
html:not(.vast-ready) header.st-header {
    visibility: hidden;
    max-height: 0;
    overflow: hidden;
    animation: vast-header-fallback 0s linear 2.5s forwards;
}

@keyframes vast-header-fallback {
    to {
        visibility: visible;
        max-height: 2000px;
    }
}

@media (prefers-reduced-motion: reduce) {
    /* The fallback is a delay, not motion: keep it. */
    html:not(.vast-ready) header.st-header {
        animation: vast-header-fallback 0s linear 2.5s forwards;
    }
}
