/* Finapolis — base styles */

:root {
  /* ---- Finapolis (Asha) design system — LIGHT ----
     Tokens lifted 1:1 from the Figma "Copy as CSS" export. */
  --bg: #ffffff;
  --bg-soft: #f4f2fe;   /* lavender section / footer wash */
  --bg-muted: #fafafa;
  --bg-dim: #f4f2fe;
  --bg-shape: #ece8fb;
  --ink: #161129;       /* headlines + primary text  (p3 .082 .067 .153) */
  --ink-2: #1d1232;     /* nav / button labels        (p3 .106 .071 .188) */
  --ink-3: #2d2547;     /* softened body for long-form paragraphs */
  --muted: rgba(29, 18, 50, 0.62);  /* captions, legal, placeholders */
  --muted-2: rgba(29, 18, 50, 0.45);
  --line: #e7e3f6;      /* light lavender hairline */
  --line-2: #f0edfa;
  --purple: #4f32c9;    /* primary accent (p3 .294 .200 .757) */
  --purple-2: #a696e9;  /* lavender accent (p3 .639 .588 .890) */
  --blue: #0082ff;      /* decorative glow only */
  --accent: #161129;    /* dark pill primary on light surfaces */
  --accent-ink: #ffffff;
  --cta-bg: #030209;    /* near-black CTA band (p3 .012 .008 .031) */
  --feature-card: #161129;  /* featured pricing card surface */
  --success: #4f32c9;
  --danger: #4f32c9;
  --radius-s: 12px;
  --radius: 20px;
  --radius-l: 30px;     /* cards, CTA band, feature surfaces */
  --radius-pill: 9999px;
  --shadow-sm: 4px 4px 25px -3px rgba(0, 0, 0, 0.03);
  --shadow: 4px 10px 65px -5px rgba(0, 0, 0, 0.1), 4px 8px 10px -6px rgba(0, 0, 0, 0.1);
  /* Content column = 1160px (the Figma 1440 frame minus its 140px side
     margins). Centered, so at a 1440 viewport the margins land at exactly
     140px — matching the design. */
  --container: 1160px;
  --gutter: clamp(24px, 5vw, 40px);
  --font-sans: var(--font-dm-sans), "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-serif: var(--font-amethysta), "Amethysta", Georgia, "Times New Roman", serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;

  /* Resources page pill tab label typography.
     Centralized as variables so the design system can tune all three
     pills in one place without touching the .resources-tab rule. */
  --pill-tab-font-family: var(--font-sans);
  --pill-tab-font-size: 18px;
  --pill-tab-font-weight: 400;
  --pill-tab-line-height: 1.2;

  /* Resources page hero — H1 + lead paragraph typography. */
  --resources-hero-h1-font-family: var(--font-serif);
  --resources-hero-h1-font-size: 48px;
  --resources-hero-h1-font-weight: 400;
  --resources-hero-h1-line-height: 1.1;

  --resources-hero-lead-font-family: var(--font-sans);
  --resources-hero-lead-font-size: 20px;
  --resources-hero-lead-font-weight: 400;
  --resources-hero-lead-line-height: 1.5;

  /* "Step-by-step tutorials..." subtitle under the pill row. Same
     spec as the hero lead (DM Sans Regular 20) — re-declared as its
     own variable so the two can diverge later if needed. */
  --resources-tab-blurb-font-family: var(--font-sans);
  --resources-tab-blurb-font-size: 20px;
  --resources-tab-blurb-font-weight: 400;
  --resources-tab-blurb-line-height: 1.5;
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }
/* Desktop frame: 1366–1920px design width.
   - <html> is white so any area outside the centered body (viewport >1920)
     reads as white margins.
   - <body> stays as the design canvas; centered horizontally so wide
     viewports get equal left/right margins.
   - On narrow viewports (<1366) the body still measures 1366 and the
     user can scroll horizontally to see partial content. */
html { background: #ffffff; overflow-x: auto; }
/* Was: html, body { overflow-x: clip; } — that prevented horizontal
   scroll site-wide, which would hide the 1366-wide design on narrow
   viewports. Off-screen decorative transforms (Napoli walk-in) are
   contained inside their own .napoli-stage so the page itself never
   needs site-wide overflow clipping. */

/* Smooth in-page anchor scrolling, with offset so the sticky header doesn't cover the target. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
section[id], div[id], article[id] { scroll-margin-top: 88px; }

body {
  font-family: var(--font-sans);
  color: var(--ink);
  line-height: 1.55;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  position: relative;
  min-height: 100vh;

  /* Desktop-only design frame, 1366–1920 px.
     - Below 1366: page content stays at the 1366 design width; the
       viewport horizontally scrolls if needed via html's overflow-x.
     - 1366–1920: page fills the viewport fluidly.
     - Above 1920: page caps at 1920 and centers (white margins via
       margin auto).
     overflow-x: clip on body itself prevents stray inner elements
     (decorative SVGs with negative offsets) from pushing the page
     wider than its own measured min-width and creating an extra
     scrollbar inside the body. The html-level overflow handles the
     real <1366 case.
  */
  min-width: 1366px;
  max-width: 1920px;
  margin-left: auto;
  margin-right: auto;
  overflow-x: clip;

  /* ---- Sitewide background (Figma "bg-gradients") = a WHITE base with opaque
         #F4F2FE lavender wash BANDS anchored by section, and white in the gaps
         between them (matching the design's banded layout, not a continuous
         wash). Band 1 (bg-wash.svg) covers hero + companion; band 2
         (bg-wash-mid.svg) covers trust / pricing. Each band carries its exact
         blue (#1F7FFB) + purple (#4B33C1) blooms. The grain (noise.png) overlays
         via body::before; the prominent per-section balls (hero blue-ball +
         grid, trust white-ball, footer blue-ellipse) sit on top. ---- */
  /* The BASE is the lavender wash (#F4F2FE), so the background is edge-to-edge
     lavender at ANY screen width — there is no white border anywhere. The
     bloom-carrying bg-wash SVGs are capped at the Figma design width (1444px)
     and centred on top, so the blue/purple blooms stay Figma-proportional (no
     left-edge over-saturation on wide screens) while the lavender they sit on
     runs full-bleed. */
  background-color: #F4F2FE;
  background-image:
    url("/images/bg-wash.svg"),        /* band 1 blooms — hero + companion */
    url("/images/bg-wash-mid.svg");    /* band 2 blooms — trust / pricing */
  background-repeat: no-repeat, no-repeat;
  background-position: center top, center 52%;
  /* `100% auto` scales the SVG to viewport width and lets the browser
     keep its native aspect ratio — so on wider screens the bloom band
     grows taller along with growing wider, eliminating the white gap
     that appeared when height was hard-pinned at 2240/2100 px. */
  background-size: 100% auto, 100% auto;
  background-attachment: scroll;
}

/* Figma "Noise & Texture" grain — the exact tile extracted from the SVG
   (public/images/noise.png), tiled and held at the design's effective opacity
   (rect 0.4 x pattern 0.15 ~= 0.06). Fixed so it never seams on the tall page,
   and sits behind the content (z-index -1, above the body wash). */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: url("/images/noise.png") repeat;
  background-size: 360px 360px;
  opacity: 0.06;
}

/* ============================================================================
   RESPONSIVE STAGE  (.page-frame wraps Header + main + Footer)
   ----------------------------------------------------------------------------
   • ≥ 1920px : the page is capped at 1920 and centred; the body's plain white
     shows in the side margins — a hard white cutoff on ultrawide / zoomed-out.
   • 1366–1920px : renders natively (the tuned range).
   • 1024–1366px : laid out at 1366 and uniformly scaled down with `zoom` so
     nothing overflows (the exact ratio = viewport/1366 is set by the inline
     "page-frame-scale" script in layout.tsx; the CSS value is a safe fallback).
   • < 1024px : scale released — the normal mobile breakpoints reflow as before.
   The lavender wash + blooms live here (moved off body) so they cap at 1920 too.
   ============================================================================ */
.page-frame {
  position: relative;
  width: 100%;
  max-width: 1920px;
  margin-inline: auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overflow-x: clip; /* clip the hero glow/grid bleed at the 1920 frame edge */
  /* Own stacking context so the z-index:-1 hero glows (blue balls) paint ABOVE
     this frame's wash background instead of behind it. Without this they vanish
     once the wash moved off <body> onto .page-frame. */
  isolation: isolate;

  /* Band 2 is no longer a fixed-pixel page band — a fixed offset drifted relative
     to the live sections. It is now the section-anchored `.bloom-band` wrapper
     (below), which starts at the audience section (above trust) and ends after the
     trust section; pricing and everything below it sit on white. */
  background-image: url("/images/bg-wash.svg?v=2"); /* band 1 — hero + companion */
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 100% 2136px;
}
.page-frame > main { flex: 1 0 auto; }

/* Band 2, section-anchored: a lavender wash + soft blue/purple blooms wrapping the
   audience + trust run (applied by RenderBlocks). Starts at the audience section
   (the one above "Trust, but verify") and ends after the trust section; pricing
   and everything below render on white. */
.bloom-band {
  position: relative;
  /* flow-root so the first/last child's vertical margins stay INSIDE the lavender
     wash instead of collapsing through and leaving a white strip at the band's
     top or bottom edge. */
  display: flow-root;
  background-color: #f4f2fe;
  background-image:
    radial-gradient(58% 48% at 16% 14%, rgba(31, 127, 251, 0.14), transparent 70%),
    radial-gradient(55% 46% at 88% 80%, rgba(79, 50, 201, 0.12), transparent 72%);
  background-repeat: no-repeat;
}
/* If a page ever ENDS in the lavender bloom-band, drop the article's white bottom
   padding so the wash runs straight into the lavender footer with no white seam.
   Scoped to :last-child so it only fires when the band is the final block — on the
   home page the band now ends after trust and is followed by white sections
   (pricing -> CTA), so this no longer matches and the normal bottom spacing is kept. */
/* Figma: the audience grid and the trust section sit close together inside the bloom-band, not split by two full section paddings. Tighten just that one boundary (last audience card row -> the "Built on institutional foundations" eyebrow). */
.bloom-band > section:first-child { padding-bottom: clamp(24px, 3vw, 40px); }
.bloom-band > .trust-section { padding-top: clamp(16px, 2vw, 32px); }

.page-frame > main > article:has(> .bloom-band:last-child) {
  padding-bottom: 0;
}

/* Home (Figma): the page is BANDED — only two lavender bands, white everywhere
   else. Band 1 (hero → data-sources → companion) is painted by .page-frame's
   opaque bg-wash.svg (top 2136px); band 2 (the audience + "Trust, but verify"
   run) is the self-contained .bloom-band wrapper above. The "modules" section
   between them already paints its own white, and the sections BELOW "Trust, but
   verify" (pricing, resources, FAQ) are transparent. The legacy body lavender
   (#F4F2FE) + bg-wash/bg-wash-mid leaked through those transparent sections,
   tinting pricing/resources/FAQ lavender instead of white (Leo's red line: below
   it should be white, per Figma). White out the body on Home so only the two
   self-contained bands carry lavender — band 1, band 2, the price-glow behind the
   pricing cards, the dark CTA and the lavender footer all paint their own
   backgrounds and are unaffected. Home-only via .price-glow-host (the home pricing
   case; /pricing shows the billing toggle and has no such host, other pages have
   no pricing cards). Grain (body::before) stays sitewide. Mirrors the
   About/Resources white-page approach. */
body:has(.price-glow-host) {
  background-color: #fff;
  background-image: none;
}

/* ============================================================================
   ABOUT PAGE background. The `statSplit` "problem we're solving" block is unique
   to the About layout, so `.bloom-band-about` (RenderBlocks wraps the hero +
   statSplit in it) scopes these rules to About only.

   Design (Figma): the left-aligned hero and the problem/stat section share ONE
   continuous lavender wash; everything below sits on WHITE. The band runs
   unbroken across the hero + problem run, so there is no seam at the hero's old
   488px bottom edge ("the cut"); below the band the page is white.
   ============================================================================ */

/* White base — drop the homepage-tuned body lavender + bloom SVGs and the
   page-frame band so About is white except where a section paints itself. The
   hero + problem lavender now comes ONLY from the bloom-band. (Same white-page
   approach the Resources page uses via body:has().) */
body:has(.bloom-band-about) {
  background-color: #ffffff;
  background-image: none;
}
body:has(.bloom-band-about) .page-frame {
  background-image: none;
}

/* The About band carries the continuous lavender + Figma corner blooms across
   the whole hero + problem run (overrides the home band's blooms above).
   Faithfully reproduces the Figma "bg-gradients" frame (Ellipses 819–823) on the
   lavender base: 2 blue (#1F7FFB) top-left + bottom-right, 3 purple (#4F32C9)
   top-right + bottom-left + a faint centre. Centres are each ellipse's box centre
   (computed from its Figma left/right/top/bottom); sizes are blur-expanded radii.
   This is the SAME 5-bloom stack as .bloom-band-about-lower ("How we built it"),
   so the wash reads continuously down the page — the only difference is this band
   keeps its lavender base (Figma) where band 2 sits on white. Opacities are nudged
   from Figma's 0.1/0.05 to 0.12/0.06 so the blooms register on the near-white
   lavender (matching band 2). Grain comes from the global body::before noise. */
.bloom-band-about {
  background-color: #f4f2fe;
  background-image:
    radial-gradient(48% 42% at 0% 9%, rgba(31, 127, 251, 0.12), transparent 70%),
    radial-gradient(48% 42% at 85% 87%, rgba(31, 127, 251, 0.12), transparent 70%),
    radial-gradient(62% 38% at 97% 19%, rgba(79, 50, 201, 0.12), transparent 70%),
    radial-gradient(44% 36% at 5% 80%, rgba(79, 50, 201, 0.12), transparent 70%),
    radial-gradient(38% 24% at 37% 50%, rgba(79, 50, 201, 0.06), transparent 72%);
  background-repeat: no-repeat;
}

/* The hero now sits ON the band wash: drop its own opaque 488px band + internal
   corner blooms so the band shows through continuously (kills the "cut"). Its
   grid lattice + headline stay.

   overflow:visible lets the grid lattice (hero-grid.svg, native 749x1092) show
   its FULL shape down into the problem section instead of being hard-clipped at
   the hero's 488px bottom edge. It fades out via its own radial mask and is cut
   only by the page's right edge (.page-frame overflow-x: clip). Same position +
   size — we only remove the vertical clip. */
.bloom-band-about .hero-centered.hero-centered-decor {
  background-color: transparent;
  overflow: visible;
  /* Push the whole hero DOWN so it clears the fixed 156px header with a comfortable
     gap. The header is position:fixed (overlays the page), and the hero starts at the
     page top behind it, so the headline was sitting ~31px ABOVE the header's bottom
     edge — it nearly touched the nav (Leo's red line: this gap needs to be bigger).
     margin-top moves the hero as a single unit (headline + its grid lattice together);
     the lavender band (flow-root) fills the new space behind the transparent header.
     The hero's own 488px box, its centered content, and the hero→problem gap (0px) are
     all unchanged, so nothing inside the hero or below it shifts relative to anything
     else — the page just starts lower. Single tunable value. */
  margin-top: 100px;
}
.bloom-band-about .hero-decor-bloom {
  display: none;
}

/* Hero text box width — match the Figma hero frame (Frame 1000005689: 959px
   wide). The shared `.hero-centered-left h1` rule uses max-width:none, so the
   headline fills the full 1440 container and wraps to 2 lines; constraining it
   to the Figma frame's 959px wraps the headline to 3 lines like the design.
   Scoped to About via .bloom-band-about so the Resources/Contact left-heroes
   are untouched (they keep their own full-width headline). The lead keeps its
   own narrower readable maxLeadWidth (set inline by the block). */
.bloom-band-about .hero-centered.hero-centered-left h1 {
  max-width: 959px;
  /* Greedy (first-fit) line wrapping, to match Figma's break. The shared
     `.hero h1` rule applies text-wrap:balance, which evens out the line widths
     and drops "who" to line 3 ("for the professionals / who need it most").
     Figma fills each line greedily — "for the professionals who / need it
     most" — so override balance back to greedy here. Scoped to About only. */
  text-wrap: wrap;
}

/* Lead / sub-header width — match the SAME 959px Figma text frame as the headline
   (Frame 1000005689 is 959×341 "Hug": the headline and the lead both stretch to
   959px). The block sets maxLeadWidth:'640', which the component emits as an inline
   max-width:640px on the <p>, so the lead wraps too early. The select offers no 959
   option, so the exact frame width is set here in About-scoped CSS. !important is
   required to beat the block's inline style; scoped to .bloom-band-about so the
   other pages' heroes keep their own lead widths. */
.bloom-band-about .hero-centered.hero-centered-left p.lead {
  max-width: 959px !important;
}

/* Grid lattice repositioned per Leo's Figma "Group 1000005669" — moved UP and to
   the RIGHT (left 691, top -98 in the 1440 design frame; the group is ~1333×1092).
   The grid SVG is natively 749×1092, so we keep it at native size (NOT stretched
   to 1333 — that would distort the square lattice into wide rectangles) and let
   its mirrored ::after copy continue the lattice rightward, exactly as the
   original wide-grid mechanism does. Both anchored to the centered 1440 region so
   they hold on wider viewports; together they bleed up (top -98) and past the
   right edge (cut by the page's right side via .page-frame overflow-x: clip). */
.bloom-band-about .hero-decor-resources {
  left: calc((100% - 1440px) / 2 + 841px); /* Leo's Figma 691, nudged further right */
  right: auto;
  top: -98px;
}
/* Mirror copy continues the lattice to the right of the grid (grid-left + 749 −
   68px seam overlap = +681px), so the wide grid fills toward the frame edge on
   wider screens without distortion. */
.bloom-band-about .hero-centered.hero-centered-decor::after {
  left: calc((100% - 1440px) / 2 + 1522px); /* grid-left (841) + 681 seam offset */
  right: auto;
  top: -98px;
}

/* The grid is a BACKGROUND element — lift the problem section's content (stat
   cards + copy) above it so the cards sit ON TOP of the lattice, not under it.
   (The hero is position:relative, so its absolutely-positioned grid would
   otherwise paint above the later, non-positioned statSplit section.) */
/* About — ONE shared content column for every body section (Leo: "even left/right
   margins, lined up down the page; like the Figma"). The hero indents its headline
   + lead 83px so they start under the "f" of the finapolis logo (a centered 1440
   frame + an 83px inset). Anchor EVERY content section to that SAME column —
   "The problem we're solving", the audience grid ("Who we built it for"), "How we
   built it", "Data and methodology", and the team grid — now made SYMMETRIC: equal
   (clamp + 83px) padding on BOTH sides. So every left edge lines up under the hero
   and every right margin mirrors the left, at every width. The hero keeps its own
   headline-indent rule; the CTA band stays its own narrow centered card — both
   excluded.
   Was: only the problem shared the hero's column, and only on the LEFT (its right
   padding lacked the 83px, so its right margin ran ~94px wider — the asymmetry Leo
   flagged), while who/how/data/team sat in the narrower, centered default 1160
   container — two systems whose edges never lined up down the page. */
body:has(.bloom-band-about) article section:not(.hero):not(.cta-band) > .container {
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: calc(clamp(24px, 3.5vw, 50px) + 83px);
  padding-right: calc(clamp(24px, 3.5vw, 50px) + 83px);
}
.bloom-band-about .stat-split {
  position: relative;
  z-index: 1;
  /* Fill the shared content column (defined above) so the stat cards' right edge
     mirrors the copy column's left edge — i.e. the right margin equals the left.
     (Was capped at max-width:1080px + margin-right:auto, which left the whole block
     left-aligned with a wider right margin — the asymmetry Leo flagged.) */
  /* Figma: the left copy column is vertically centered against the taller
     stat-card stack. The base .stat-split rule top-aligns it (align-items:
     start); this more-specific, About-only rule overrides that to center. */
  align-items: center;
}

/* About band 2 (Figma "How we built it" frame, 1440×673): a WHITE section
   carrying the Figma "bg-gradients" wash — 5 Gaussian-blurred ellipses (819–823)
   over white. It wraps the "How we built it" cards ONLY: the strip between the
   white "Who we built it for" audience grid above and the white "Data and
   methodology" + team sections below (RenderBlocks stops the band at the
   dataMethodology block). Standalone class (NOT `.bloom-band`) so the homepage
   band's first-child / trust spacing tweaks never apply here. */
.bloom-band-about-lower {
  position: relative;
  display: flow-root;
  /* WHITE base — the Figma "How we built it" bg-gradients frame is #FFFFFF. */
  background-color: #ffffff;
  /* The wash is the 5 Figma ellipses (819–823) transcribed VERBATIM into
     bg-wash-about-howbuilt.svg — same exact colours/opacities (0.1 / 0.05) and
     Gaussian blurs (101/113/125) as bg-wash-mid.svg, just re-laid-out for this
     1440×673 frame. It MUST be the real blurred-ellipse SVG, NOT CSS
     radial-gradients: a blurred ellipse holds its ~0.1 tint across a broad area
     (the soft blue/purple wash you see in Figma), whereas a radial-gradient peaks
     at one point and washes out to near-white — which made the section look plain
     white (Leo: "it should not have a white background, it should look like the
     figma"). Stretched to fill the band (SVG preserveAspectRatio=none +
     background-size 100% 100%). Grain comes from the global body::before noise. */
  background-image: url('/images/bg-wash-about-howbuilt.svg');
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* About: tighten the WHITE lower-page section breaks (Leo, annotated). The global
   `section { padding: clamp(56px,8vw,110px) 0 }` stacks to ~220px between the Data
   & methodology disclaimer and "Our team", and ~190px between the team grid and
   the CTA. Halve just these About boundaries — Data & methodology's bottom, the
   team section's top + bottom, and the CTA's top margin. `.data-methodology +
   section` is the bare-`<section>` team grid that immediately follows it. */
body:has(.bloom-band-about) .data-methodology {
  padding-bottom: clamp(32px, 4vw, 48px);
}
body:has(.bloom-band-about) .data-methodology + section {
  padding-top: clamp(32px, 4vw, 48px);
  padding-bottom: clamp(32px, 4vw, 48px);
}
body:has(.bloom-band-about) .cta-band {
  margin-top: clamp(24px, 3vw, 40px);
}

@media (min-width: 1024px) and (max-width: 1365.98px) {
  .page-frame {
    width: 1366px;
    max-width: none;
    zoom: 0.75; /* safe fallback (= 1024/1366); the script refines to exact fit */
  }
}

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

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

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

/* H1/H2 = Amethysta serif (Figma headlines). H3–H5 = DM Sans medium
   (Figma module/card sub-headers are sans, not serif). */
h1, h2 { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.05em; line-height: 1.1; margin: 0; color: var(--ink); }
h3, h4, h5 { font-family: var(--font-sans); font-weight: 500; letter-spacing: -0.01em; line-height: 1.2; margin: 0; color: var(--ink); }
h1 { font-size: clamp(40px, 5vw, 72px); line-height: 1.1; }
h2 { font-size: clamp(30px, 3.4vw, 48px); line-height: 1.2; }
h3 { font-size: clamp(22px, 2.1vw, 30px); }
h4 { font-size: 20px; }

p { margin: 0; color: var(--ink-3); }
.muted { color: var(--muted); }

ul { padding: 0; margin: 0; list-style: none; }

.container {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ---------- Header ---------- */

/* Pinned header. At the very top it's transparent (Figma: the marketing/header
   frame has no fill — the page's glow + grid show straight through behind the
   nav). Once the page starts scrolling, the .is-scrolled class (toggled by the
   header client on scroll) turns it into a translucent "white glass" bar: a
   backdrop blur + saturation frosts whatever scrolls underneath so the nav
   stays readable. This is Apple's sticky-nav pattern in a light variant.
   position:fixed keeps it in view the whole way down the page. */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color .3s ease, -webkit-backdrop-filter .3s ease,
    backdrop-filter .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.site-header.is-scrolled {
  background: rgba(255, 255, 255, 0.7);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: rgba(20, 17, 39, 0.08);
  box-shadow: 0 1px 12px rgba(20, 17, 39, 0.06);
}
/* Older browsers without backdrop-filter (e.g. some Firefox): fall back to a
   near-opaque white so the nav is still legible over scrolling content. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .site-header.is-scrolled { background: rgba(255, 255, 255, 0.95); }
}
/* Slim the bar once scrolling starts (the full-height branded header is only
   needed at the top of the page). Lands at ~88px, matching the
   scroll-margin-top used for in-page anchors. */
.site-header.is-scrolled .nav { min-height: 0; padding-top: 16px; padding-bottom: 16px; }
.site-header.is-scrolled .brand > img { height: 56px; }
@media (prefers-reduced-motion: reduce) {
  .site-header,
  .site-header .nav,
  .site-header .brand > img { transition: none; }
}
/* Header is capped at 1440px and centered, so on wider viewports
   left and right side margins ("garmin") appear. Padding scales with
   viewport so the logo and nav don't crash into the edges below 1440. */
.site-header > .container {
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(24px, 3.5vw, 50px);
  padding-right: clamp(24px, 3.5vw, 50px);
}

/* Figma marketing/header: padding 32px 50px, height 139px, gap 24px.
   Extra top padding gives the logo + nav breathing room above the
   viewport edge (per Figma reference, the logo sits well below the
   top of the page, not flush). */
.nav {
  display: flex;
  align-items: center;
  min-height: 139px;
  padding: 48px 0 32px;
  gap: 24px;
  transition: min-height .3s ease, padding .3s ease;
}
.nav .nav-actions { margin-left: auto; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-size: 26px;
}
/* Logo = the exact Figma lockup (sparkle mark + "finapolis" wordmark) in
   /images/finapolis-logo-lockup.svg — no CSS mark needed. */
.brand .brand-mark,
.brand > svg,
.brand > img { flex: none; height: 75px; width: auto; transition: height .3s ease; }

.nav-links {
  display: flex; gap: 0; align-items: center;
}

/* Nav items are ghost pills (Figma: padding 10px 28px, radius 9999px,
   DM Sans 500 16px, #1D1232 — adjacent with no gap). */
.nav-links a {
  color: var(--ink-2);
  font-size: 18px;
  font-weight: 500;
  padding: 10px 28px;
  border-radius: var(--radius-pill);
  transition: background-color .15s ease, color .15s ease;
}
.nav-links a:hover { color: var(--ink); background: var(--bg-soft); text-decoration: none; }
.nav-links a.is-active {
  color: var(--ink);
  background: var(--bg-soft);
  font-weight: 500;
}

.nav-actions { display: flex; gap: 12px; align-items: center; }

/* Mobile menu toggle — hidden on desktop, shown ≤1024 (where the inline nav
   links collapse into a dropdown panel). */
.menu-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border-radius: var(--radius-pill);
  color: var(--ink);
  background: transparent;
  cursor: pointer;
}
.menu-toggle:hover { background: var(--bg-soft); }

@media (max-width: 1024px) {
  /* Compact the header on tablet/mobile — the 139px desktop height + 75px
     logo are too tall here. */
  .nav { min-height: auto; padding: 18px 0; }
  .brand > img { height: 40px; }
  .nav-links { display: none; }
  .menu-toggle { display: inline-flex; }
  /* Nav links become a dropdown panel under the header when the toggle is open. */
  .site-header.is-open .nav-links {
    display: flex; flex-direction: column;
    position: absolute; top: 100%; left: 0; right: 0;
    background: #fff; border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 28px rgba(20, 17, 39, 0.10);
    padding: 12px clamp(20px, 4vw, 40px) 16px; gap: 2px; align-items: stretch;
  }
  .site-header.is-open .nav-links a { width: 100%; padding: 12px 14px; border-radius: var(--radius-s); }
}
@media (max-width: 600px) {
  .brand > img { height: 34px; }
  /* Keep logo + primary CTA + menu on small phones; Login moves into reach
     via the signup flow rather than crowding the bar. */
  .login-link { display: none; }
}

/* ---------- Buttons ---------- */

/* Figma buttons are pills: radius 9999px, DM Sans 500 16px.
   Default (header/nav scale) = padding 10px 28px. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 10px 28px;
  font-size: 16px; font-weight: 500;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  transition: transform .04s ease, background-color .15s ease, border-color .15s ease, color .15s ease, box-shadow .15s ease;
  white-space: nowrap;
  cursor: pointer;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

/* Primary = dark navy pill on light surfaces (#161129, white text). */
.btn-primary { background: var(--ink); color: var(--accent-ink); }
.btn-primary:hover { background: #241a40; }

/* Secondary = white pill, purple hairline border (Figma "See how it works"). */
.btn-secondary { background: #fff; color: var(--ink); border-color: var(--purple); }
.btn-secondary:hover { background: var(--bg-soft); }

/* Accent = solid purple pill — used on the dark CTA band. */
.btn-accent { background: var(--purple); color: #fff; }
.btn-accent:hover { background: #5d3fe0; }

.btn-ghost { background: transparent; color: var(--ink-2); }
.btn-ghost:hover { background: var(--bg-soft); }

/* Large hero scale (Figma: padding 16px 56px, height 60px). */
.btn-lg { padding: 16px 48px; font-size: 16px; min-height: 60px; }

.btn-link {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--purple); font-weight: 500; font-size: 16px;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.btn-link:hover { gap: 12px; }
.btn-link.no-underline { text-decoration: none; }
.btn-link.no-underline:hover { text-decoration: underline; }

.login-link {
  color: var(--ink-2);
  font-weight: 500;
  font-size: 18px;
  padding: 10px 28px;
}
.login-link:hover { color: var(--ink); text-decoration: none; }

/* ---------- Sections ---------- */

section { padding: clamp(56px, 8vw, 110px) 0; }
.section-tight { padding: clamp(40px, 6vw, 80px) 0; }
.section-soft { background: var(--bg-soft); }
.section-dark { background: var(--cta-bg); color: #ededed; }
.section-dark h1, .section-dark h2, .section-dark h3, .section-dark h4 { color: #ffffff; }
.section-dark p { color: rgba(255, 255, 255, 0.72); }

/* Eyebrow (Figma): DM Sans 700, 16px, letter-spacing 3px, uppercase,
   #161129 — a plain bold label, no box. */
.eyebrow {
  display: inline-block;
  font-family: var(--font-sans);
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--ink);
  margin-bottom: 18px;
}
.eyebrow.flush { margin-bottom: 24px; }

/* Section titles default to LEFT-aligned (Figma: audience, pricing,
   resources, trust). Add `.center` for the centred sections
   (workflow intro, FAQ). */
.section-title {
  text-align: left;
  max-width: 720px;
  margin: 0 0 56px;
}
.section-title.center {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
.section-title h2 { margin-bottom: 16px; }
.section-title p { color: var(--ink-3); font-size: 20px; line-height: 1.4; }

/* ---------- Cards ---------- */

.card {
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-l);
  padding: 32px;
  box-shadow: var(--shadow);
}
.card-soft { background: var(--bg-soft); border-color: var(--line); box-shadow: none; }

/* Top "media slot" inside a card — applies whether it's the
   real illustration (`.card-illustration`) or the grey placeholder
   (`.visual.short`). Forcing the same height here is what keeps
   the three card titles aligned across the row. */
.card > .card-illustration,
.card > .visual.short:first-child {
  height: clamp(220px, 22vw, 300px);
  min-height: 0;
  margin-bottom: 20px;
}
.card-illustration {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0;
}
.card-illustration img {
  max-width: 100%;
  max-height: 100%;
  height: auto;
  width: auto;
  filter: drop-shadow(0 10px 22px rgba(10, 10, 10, 0.10));
  user-select: none;
  -webkit-user-drag: none;
}

.feature-icon {
  width: 48px; height: 48px;
  background: #d8d8dc;
  border-radius: 8px;
  display: inline-grid; place-items: center;
  margin-bottom: 22px;
  color: var(--ink);
  font-size: 18px;
}
.feature-icon.dark {
  background: var(--ink); color: #fff;
}
/* Tile-less icon image (exact Figma vectors that carry their own fill/shape,
   e.g. the home "Built for professionals" audience icons). */
.feature-icon-img {
  display: block;
  width: 44px; height: 44px;
  margin-bottom: 14px;
}

/* ---------- "Who we built it for" audience panel (About) ----------
   Exact Figma spec (1160-wide row of three 370.67×540 panels at 24px gap —
   served by .grid-3): soft #F6F6F9 surface, 30px radius. Each panel stacks a
   48px icon → uppercase title → "The challenge" label+body → "How Finapolis
   Helps" label+body, at the Figma insets (24px sides, 32px top/bottom; 8px
   icon→title; 32px title→challenge and challenge→help; 8px label→body).
   Colours are the Figma literals, which equal tokens: title + sub-labels
   #1d1232 = --ink-2, body #161129 = --ink. Type is DM Sans (--font-sans). */
/* Compound `.card.card-audience` (not just `.card-audience`) so the soft flat
   surface wins over BOTH `.card` rules — including the later translucent/glassy
   `.card` override (rgba white + backdrop blur + shadow) further down the file,
   which has equal specificity and would otherwise win on source order. */
.card.card-audience {
  background: #f6f6f9;
  background: color(display-p3 0.965 0.965 0.976);
  border: 0;
  box-shadow: none;
  backdrop-filter: none;                      /* kill the glassy `.card` blur */
  border-radius: var(--radius-l);            /* 30px */
  padding: 32px 24px;
  min-height: 540px;
  display: flex;
  flex-direction: column;
}
.card-audience > .feature-icon-img {
  width: 48px; height: 48px;
  margin: 0 0 8px;                            /* 8px icon → title (Figma) */
}
.card-audience > h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 20px;
  line-height: 28px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--ink-2);                        /* #1d1232 */
  margin: 0;
}
.card-audience-body {
  margin-top: 32px;                           /* title → "The challenge" */
}
.card-audience-body h4 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 20px;
  line-height: 28px;
  letter-spacing: 0;
  color: var(--ink-2);                        /* #1d1232 */
  margin: 0 0 8px;                            /* label → its body (Figma 8px) */
}
.card-audience-body p {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.3;                           /* Figma 130% */
  color: var(--ink);                          /* #161129 */
  margin: 0;
}
/* 32px gap between the "The challenge" block and "How Finapolis Helps" */
.card-audience-body p + h4 {
  margin-top: 32px;
}
/* Paragraph break inside an audience card body (the Figma 2-paragraph layout):
   a blank-line gap between consecutive paragraphs (base p margin is 0). */
.card-audience-body p + p {
  margin-top: 16px;
}
@media (max-width: 700px) {
  .card-audience { min-height: 0; }
}

/* ---------- "Guides Tailored to Your Role" card (Resources) ----------
   Exact Figma spec: soft #F6F6F9 surface, 30px radius, 32/24 padding. Stacks a
   vuesax icon -> bold 20px title (8px below the icon) -> 20/28 body -> a
   checkmark bullet list (24px purple #4F32C9 circle + white tick, 12px gap,
   20/24 text) -> an underlined "View ... guides" link followed by a long purple
   arrow. The body flex-grows so the list + link sit at the card bottom across
   the row. Compound `.card.card-guide` so the soft surface beats the later
   glassy `.card` override (same trick as `.card-audience`). */
.card.card-guide {
  background: #f6f6f9;
  background: color(display-p3 0.965 0.965 0.976);
  border: 0;
  box-shadow: none;
  backdrop-filter: none;
  border-radius: var(--radius-l);              /* 30px */
  padding: 32px 24px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.card-guide > .feature-icon-img {
  width: auto;
  height: 44px;                                /* vuesax glyph ~ Figma */
  margin: 0 0 8px;                             /* icon -> title 8px */
}
.card-guide > h3 {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 20px;
  line-height: 28px;
  letter-spacing: 0;
  color: var(--ink-2);                         /* #1d1232 */
  margin: 0;
}
.card-guide-body {
  margin: 16px 0 0;                            /* title -> body 16px */
  flex: 1 1 auto;                              /* push list + link to the bottom */
}
.card-guide-body p {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;                           /* Figma 140% */
  color: var(--ink-2);                         /* #1d1232 */
  margin: 0;
}
.card-guide-body p + p { margin-top: 16px; }
.card-guide .feature-list {
  list-style: none;
  margin: 0;
  padding: 24px 0;                             /* Figma list padding */
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
}
.card-guide .feature-list li {
  position: relative;
  padding-left: 36px;                          /* 24px circle + 12px gap */
  min-height: 24px;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 24px;                           /* Figma 120% */
  color: var(--ink-2);                         /* #1d1232 */
}
.card-guide .feature-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'%3E%3Cpath d='M3.5 7.5 6 10 10.5 4.5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 14px 14px no-repeat;
  background-color: #4F32C9;
  background-color: color(display-p3 0.294 0.200 0.757);
}
.card-guide .feature-list li a { color: inherit; text-decoration: none; }
.card-guide .feature-list li a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* "View ... guides" link: underlined label + long purple arrow. */
.card-guide .guide-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
}
.card-guide .guide-link-label {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 1;
  color: var(--ink);                           /* #161129 */
  padding-bottom: 6px;
  border-bottom: 1px solid var(--ink-2);       /* #1d1232 */
}
.card-guide .guide-link-arrow {
  flex: none;
  width: 52px;
  height: 16px;
  color: #4F32C9;
  color: color(display-p3 0.294 0.200 0.757);
}
.card-guide .guide-link:hover .guide-link-label { border-bottom-color: var(--purple); }

/* ---------- Grid helpers ---------- */

.grid { display: grid; gap: 24px; }
.grid-1 { grid-template-columns: 1fr; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-5 { grid-template-columns: repeat(5, 1fr); }
@media (max-width: 980px) {
  .grid-3, .grid-4, .grid-5 { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 700px) {
  .grid-2, .grid-3, .grid-4, .grid-5 { grid-template-columns: 1fr; }
}

/* Contact page — stacked CardGrid cards, fixed 766 x 402 per Figma.
   Scoped via the .hero-centered-contact sibling so it only affects the
   Contact page hero's subsequent CardGrid (not other 1-col grids
   elsewhere on the site). The grid track is capped at 766px and centered
   so the column doesn't stretch full container width. */
.hero-centered-contact ~ section .grid.grid-1 {
  grid-template-columns: 766px;
  justify-content: center;
  row-gap: 24px;
}
.hero-centered-contact ~ section .grid.grid-1 > .card {
  width: 766px;
  height: 402px;
  box-sizing: border-box;
}
/* The "How can we help?" section title above the cards is left-aligned
   by default, but the cards are centered inside .container — leaving
   the title's left edge stuck at the container edge while the cards
   sit further in. Cap the title at 766 and center it so its left edge
   lines up with the cards' left edge. */
.hero-centered-contact ~ section .section-title {
  max-width: 766px;
  margin-left: auto;
  margin-right: auto;
}
@media (max-width: 820px) {
  .hero-centered-contact ~ section .grid.grid-1 {
    grid-template-columns: 1fr;
  }
  .hero-centered-contact ~ section .grid.grid-1 > .card {
    width: 100%;
    height: auto;
  }
  .hero-centered-contact ~ section .section-title {
    max-width: 100%;
  }
}

/* ---------- Team grid ---------- */

/* About team section: let the heading use the full container so it stays on
   ONE line as the responsive h2 (clamp(30px, 3.4vw, 48px)) grows on desktop.
   The base .section-title caps at 720px, which forces "Built by entrepreneurs
   with investing experience" to wrap once the font passes ~34px (at the 48px
   ceiling it needs ~1060px). Scoped to the team section (teamGrid is About-only)
   so other section titles keep their 720px measure; wraps naturally below
   ~700px, where the team grid also collapses. */
.container:has(> .team-grid) > .section-title { max-width: none; }
.team-grid { row-gap: 44px; }
.team-member {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.team-avatar {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  margin-bottom: 18px;
  color: var(--ink);
  font-size: 30px;
  font-weight: 600;
  letter-spacing: 0.01em;
  user-select: none;
}
.team-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.team-name { margin: 0; font-size: 16px; font-weight: 700; color: var(--ink); }
.team-role { margin: 4px 0 0; font-size: 13px; font-weight: 600; color: var(--ink-3); }
.team-bio { margin: 8px 0 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* Team cards are compact — stay 2-up on phones (overriding the generic
   .grid-5 → 1col rule above), collapsing to a single column only when truly
   narrow. A 10-person team as one tall column reads poorly otherwise. */
@media (max-width: 700px) {
  .team-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 460px) {
  .team-grid { grid-template-columns: 1fr; }
}

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 5vw, 80px);
  align-items: center;
}
@media (max-width: 880px) { .split { grid-template-columns: 1fr; } }

/* ---------- Hero ---------- */

.hero {
  padding: clamp(72px, 11vw, 140px) 0 clamp(56px, 8vw, 110px);
  border-bottom: 1px solid var(--line);
}
/* The hero gets a wider container than the rest of the site so the
   larger headline AND the original-size Napoli card can both fit on
   one row. Other sections still use the standard 1200 px container. */
.hero > .container { max-width: 1400px; }

/* The home hero no longer needs its own border — the sitewide
   gradient on body provides the visual continuity. */
/* Extra breathing room below the fixed 156px header (Leo): the base
   `.hero` top padding (clamp …140px) left the headline tucked right under
   the nav. Bump only the home hero's TOP padding so the whole hero shifts
   down as a unit — internal spacing and every section below are unchanged. */
.hero-home {
  border-bottom: none;
  padding-top: clamp(96px, 14vw, 200px);
  /* Tighten the gap between the CTAs and the data-source logo row (Leo): the
     base `.hero` bottom padding (clamp …110px) left too much empty space. */
  padding-bottom: clamp(40px, 5vw, 72px);
}
.hero-home,
.hero-band,
.hero-band > .hero-home,
.hero-band > .section-soft { background: transparent; }

/* Figma hero grid (public/images/hero-grid.svg): the white node/connector
   lattice + its own bright bloom, pinned to the RIGHT edge over the blue
   glow. Anchored to the viewport right; starts behind the header (negative
   top) and bleeds downward, exactly as the mock. Sits behind the hero
   content. */
.hero-band { position: relative; }
.hero-band > .hero-home { position: relative; z-index: 2; }
/* Layering on the right: blue ball (glow) -> grid (lattice) -> content.
   The blue ball is centered at the band's vertical middle (Figma filter20
   cy≈1075 of the 2136 hero+companion band), so its strong blue lands on the
   companion / bottom-right and bleeds down. z-index -1 keeps it behind the
   companion content it overlaps. */
/* ============================================================================
   FIGMA → FLUID CONVERSION   (reference frame: 1440 × 9012, content column 1160)
   ----------------------------------------------------------------------------
   The Asha design is a fixed 1440px-wide canvas. To make any Figma value work on
   every screen we "fluidise" it with one formula:

       clamp( MIN , calc(FIGMA_PX / 1440 * 100vw) , FIGMA_PX )

   - calc(FIGMA_PX / 1440 * 100vw) == FIGMA_PX exactly when the viewport is 1440px
     wide, so the page is pixel-perfect to Figma at 1440 and scales smoothly below.
   - the FIGMA_PX cap stops decor from ballooning on monitors wider than 1440.
   - MIN keeps it usable on phones.

   Background decorations (balls, grid, glows) ALSO anchor to the nearest VIEWPORT
   EDGE instead of the centred 1440 box, so on wide screens they hug the edge
   rather than stranding mid-screen behind white margins. Their art fades to
   transparent inside its own box (full-circle SVG, feathered grid), so anchoring
   or scaling can never hard-clip.
   ============================================================================ */

/* Hero blue ball (right) — EXACT Figma element: a 933x922 ellipse (rx466.5), 90px
   blur, 0.7 opacity, centred at (1523.5, 1075) in the 1440 frame (~84px off the
   right edge, low). This is the ONLY blue ball on the right — it sits in the hero's
   lower-right and bleeds down (the companion's separate blue glow was removed, so
   nothing doubles up with it). 1480px box → 1480px width renders the true size. */
.hero-glow {
  position: absolute;
  top: clamp(180px, calc(335 / 1440 * 100vw), 335px);
  right: clamp(-824px, calc(-824 / 1440 * 100vw), -480px);
  width: clamp(760px, calc(1480 / 1440 * 100vw), 1480px);
  height: auto;
  z-index: -1;
  pointer-events: none;
  user-select: none;
}
/* Hero blue ball (left) — EXACT Figma element: a 488px circle (r244), 90px blur,
   0.8 opacity, centred at (-150, 336) in the 1440 frame (i.e. 150px off the left
   edge). blue-ball-left.svg is a 1056px box (488 circle + blur padding), so a
   1056px width renders the circle at its true 488px size; the box centre (+528)
   lands the circle centre at the Figma coordinates. Fluidised via /1440. */
.hero-glow-left {
  position: absolute;
  top: clamp(-192px, calc(-192 / 1440 * 100vw), -110px);
  left: clamp(-678px, calc(-678 / 1440 * 100vw), -400px);
  width: clamp(560px, calc(1056 / 1440 * 100vw), 1056px);
  height: auto;
  z-index: -1;
  pointer-events: none;
  user-select: none;
}
@media (max-width: 880px) { .hero-glow-left { display: none; } }
/* Hero grid lattice (right). Figma: 749px wide, top -92px (bleeds up behind the
   transparent header). Fluidised, then anchored to bleed PAST the right edge so
   the browser (html/body overflow-x: clip) hard-cuts it at the screen edge — a
   real page-edge cut, not a CSS mask crop. */
.hero-decor {
  position: absolute;
  top: clamp(-92px, calc(-92 / 1440 * 100vw), -48px);
  right: clamp(-72px, calc(-28 / 1440 * 100vw), -16px);
  width: clamp(440px, calc(749 / 1440 * 100vw), 749px);
  height: auto;
  z-index: 1;
  pointer-events: none;
  user-select: none;
}
@media (max-width: 1024px) { .hero-glow, .hero-decor { display: none; } }

/* ---- Hero — resources-page decor ----
   Adds the Figma "Group 1000005669" grid lattice (hero-grid.svg, the same
   asset the home hero uses) to a centered hero, anchored to the viewport's
   RIGHT edge — not to a 1440px design box — so the grid scales with the
   browser. The Figma 1440-frame placement is width 1333.66 px, left 691 px,
   top 66 px (i.e. ~48% from the left in the 1440 box, extending past the
   right edge). Translated to a fluid layout:
     - width: clamp(900px, 80vw, 1700px) — grows with the viewport instead
       of capping at the Figma 749 px home-hero value.
     - right: -10vw with a -200 to -80 px clamp so the grid bleeds OFF the
       right edge at every width (matches the Figma overflow).
     - top: 66 px verbatim from the Figma spec.
   The mask softens the left edge so the lattice dissolves into the content
   area instead of ending in a hard vertical line.
   No blue glow on this hero — only the grid. */
.hero-centered.hero-centered-decor {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* Section is 488px tall with lavender base. Bottom edge cuts
     crisply into the next section. */
  background-color: #F4F2FD;
  border-bottom: none;
  height: 488px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* Resources hero typography — pulled from :root variables so the
   design system can tune sizing in one place. Scoped to the decorated
   hero so other pages using HeroCentered aren't affected. */
.hero-centered.hero-centered-decor h1 {
  font-family: var(--resources-hero-h1-font-family);
  font-size: var(--resources-hero-h1-font-size);
  font-weight: var(--resources-hero-h1-font-weight);
  line-height: var(--resources-hero-h1-line-height);
}
.hero-centered.hero-centered-decor .lead {
  font-family: var(--resources-hero-lead-font-family);
  font-size: var(--resources-hero-lead-font-size) !important;
  font-weight: var(--resources-hero-lead-font-weight);
  line-height: var(--resources-hero-lead-line-height);
}

/* Resources hero corner blooms — 5 independent SVGs, each carrying
   one Gaussian-blurred ellipse. Positioned in viewport-relative units
   so each bloom stays in its Figma-relative corner at any browser
   width. Sizes scale with viewport width so the blur feathers stay
   visually consistent. All sit behind text (z-index 0); container > *
   raises content above them. */
.hero-decor-bloom {
  position: absolute;
  pointer-events: none;
  user-select: none;
  z-index: 0;
  height: auto;
}

/* Figma cx=-2 / cy=44 in 1440×488 frame -> centered at viewport left
   edge, ~9% from the top. */
.hero-decor-bloom-blue-tl {
  top: -10%;
  left: -10%;
  width: 56vw;
}

/* Figma cx=1020 / cy=424 in 1440×488 frame -> ~71% from the left,
   ~87% down. Anchor to the right since it lives in the right half.
   Enlarged so the bloom continues smoothly past the right edge of
   the hex grid, eliminating the visible cut where the grid ends. */
.hero-decor-bloom-blue-br {
  bottom: -30%;
  right: -10%;
  width: 95vw;
}

/* Figma cx=1387 / cy=92 in 1440×488 frame -> ~96% from the left,
   ~19% down. Big wide one anchored to the upper-right. */
.hero-decor-bloom-purple-tr {
  top: -30%;
  right: -10%;
  width: 85vw;
}

/* Figma cx=70 / cy=392 in 1440×488 frame -> ~5% from the left,
   ~80% down. */
.hero-decor-bloom-purple-bl {
  bottom: -20%;
  left: -10%;
  width: 60vw;
}

/* Figma cx=527 / cy=246 in 1440×488 frame -> ~36% from the left,
   centered vertically. Soft center bloom at 5% opacity. */
.hero-decor-bloom-purple-center {
  top: 0;
  left: 15%;
  width: 87vw;
}

/* ---------- Contact page hero corner blooms (legacy, for the
   HeroCentered decor='contact' path. The dedicated ContactHero block
   has its own .contact-hero-* rules below.) ---------- */

.hero-decor-bloom-contact-blue-tl {
  top: -20%;
  left: -10%;
  width: 56vw;
}
.hero-decor-bloom-contact-purple-tr {
  top: -30%;
  right: -10%;
  width: 85vw;
}

/* ---------- ContactHero block ----------
   The Contact page's single 1440x2347 lavender section. Layout per the
   Figma reference:
     - "Get in touch" hero title + lead, left-aligned at the top of the
       section (aligned to the 1440 container's left padding edge).
     - "How can we help?" subtitle below, CENTERED above the cards.
     - 4 stacked cards (766x402 each), CENTERED in the section.
     - Decor: blue bloom at the BOTTOM-LEFT, purple bloom at the top-
       right, white grid lattice in the TOP-RIGHT quadrant (not full-
       height — it sits in the upper region above/behind the cards).
   The form follows in a separate section below with its own background. */

.contact-hero-section {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background-color: #F4F2FD;
  /* Top padding mirrors the Resources hero's effective top margin.
     Resources is a 488px-tall flex-centered band; its h1 lands ~170px
     from the top. We use the same offset here so "Get in touch" sits
     on the same baseline as "Resources" when comparing the two pages
     side by side. */
  padding-top: 170px;
  padding-bottom: 128px;
}

/* Container capped at 1440 + centered + clamp padding — matches the
   site header and the Resources hero so left/right margins align. */
.contact-hero-section > .container {
  position: relative;
  z-index: 1;
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  /* +83px extra left padding aligns the "G" of "Get in touch" with
     the "f" of "finapolis" in the header logo (same offset used on the
     Resources page to align "R" with the logo). The logo lockup's
     wordmark starts ~83px inside the container's standard left edge. */
  padding-left: calc(clamp(24px, 3.5vw, 50px) + 83px);
  padding-right: clamp(24px, 3.5vw, 50px);
}

/* Blue ellipse bloom — bottom-left of the section per Figma. Bleeds
   off the lower-left corner. */
.contact-hero-bloom-blue-tl {
  position: absolute;
  top: -20%;
  left: -10%;
  width: 56vw;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}

/* Second blue bloom — denser circle (opacity 0.7, 90 blur) anchored
   mid-left, sitting BELOW the top-left wash. The SVG's ellipse center
   sits at x=-88, y=641 in a 558x1282 viewBox, so the visible blue lobe
   bleeds in from the LEFT EDGE around the vertical middle of the
   section. Pull it off-edge so the hard SVG rectangle never shows. */
/* Per Figma "Ellipse 818" + the actual SVG asset:
     Figma frame box: 933 x 922 at left=-555, top=1140
     SVG viewBox: 558 x 1282 (includes the blur spread beyond the
       ellipse bounds; ellipse center is at cx=-88.5, cy=641 within
       this larger canvas)
   To align the SVG's ellipse center with Figma's spec position
   (relative to the centered 1440 frame), the SVG element must be
   positioned at left=0 (so SVG-x=0 lands at frame-x=0, then the
   ellipse at SVG-x=-88.5 lands at frame-x=-88.5) and top=960 (so
   the ellipse at SVG-y=641 lands at section-y=1601, matching
   Figma's 1140 frame top + 461 ellipse offset). */
/* The SVG file itself now declares width=1293 viewBox=-735 0 1293 1282
   (expanded from its original 558 canvas) so the full Gaussian blur
   tail is included instead of clipped at the canvas left edge. The
   ellipse center stays at SVG-x=-88.5, which is now 646.5 from the
   viewBox's left edge. To land the ellipse center at frame-x=-88.5
   per Figma, position the element at frame-relative left=-735. */
.contact-hero-bloom-blue-ml {
  position: absolute;
  /* Fluid-scaling per CLAUDE.md formula: clamp(MIN, calc(FIGMA_PX
     / 1440 * 100vw), FIGMA_PX). At 1440 viewport, left=-735px
     exactly (Figma-pixel-perfect with the ellipse center at
     frame-x=-88.5). Scales proportionally on wider/narrower
     viewports without breaking the body width. */
  left: clamp(-735px, calc(-735 / 1440 * 100vw), -500px);
  top: clamp(800px, calc(960 / 1440 * 100vw), 960px);
  width: clamp(1100px, calc(1293 / 1440 * 100vw), 1293px);
  height: clamp(1100px, calc(1282 / 1440 * 100vw), 1282px);
  z-index: 0;
  pointer-events: none;
  user-select: none;
}

/* Third blue bloom — soft + wide (opacity 0.1, 113 blur) anchored
   bottom-right, sitting BELOW the grid lattice. The SVG's ellipse
   center is at x=837 y=1046 in a 1057x1356 viewBox, so the visible
   blue lobe pools into the bottom-right corner. Right/bottom offsets
   pull the SVG bounds off-edge so the rectangle never shows. */
.contact-hero-bloom-blue-br {
  position: absolute;
  bottom: -20%;
  right: -10%;
  width: 74vw;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}

/* Purple ellipse bloom — top-right of the section. Sits behind the
   grid lattice, giving the upper-right corner a soft purple wash. */
.contact-hero-bloom-purple-tr {
  position: absolute;
  top: -10%;
  right: -10%;
  width: 85vw;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}

/* Grid lattice — anchored to the TOP-RIGHT quadrant (not tiled full
   height). Single 749x1092 SVG, positioned in the upper-right portion
   so it sits behind/above the "Get in touch" title and the first card.
   Its left edge sits roughly at the right half of the container. */
.contact-hero-grid {
  position: absolute;
  top: 0;
  right: 0;
  width: 749px;
  height: 1092px;
  z-index: 0;
  pointer-events: none;
  background-image: url("/images/hero-grid.svg");
  background-repeat: no-repeat;
  background-position: left top;
  background-size: 749px 1092px;
  /* Mask: keep solid on the upper-right, fade on the left + bottom so
     the lattice dissolves into the page instead of cutting in hard. */
  -webkit-mask-image: radial-gradient(ellipse 110% 110% at 80% 20%, #000 35%, transparent 90%);
          mask-image: radial-gradient(ellipse 110% 110% at 80% 20%, #000 35%, transparent 90%);
}

/* Below tablet, drop the grid lattice — too cramped to read. */
@media (max-width: 1024px) {
  .contact-hero-grid { display: none; }
}

/* Bottom-left grid lattice — second white node grid, larger than the
   top-right one. Per Figma:
     left: -718px, top: 1767px, width: 1333.66px, height: 1092px
   measured in the 1440 frame's coordinate space. The grid bleeds
   heavily off the LEFT edge so only its right side is visible on the
   page. Reuses /images/hero-grid.svg (same pattern); the SVG is sized
   to 1333.66 wide and pinned via background-position. */
.contact-hero-grid-bl {
  position: absolute;
  /* Figma → fluid conversion per CLAUDE.md. The grid is at Figma
     left=-350 inside the 1440 design frame. With negative `left`,
     the clamp's "MIN" is the most negative bound (clamp at narrow
     viewports = less negative = element pushed right) and the "MAX"
     is the least negative (clamp at wide viewports = more negative
     allowed). On wider viewports the element slides left smoothly.
     The width + height scale proportionally to stay Figma-faithful. */
  left: clamp(-350px, calc(-350 / 1440 * 100vw), -200px);
  top: 1767px;
  width: clamp(1100px, calc(1333.66 / 1440 * 100vw), 1333.66px);
  height: clamp(900px, calc(1092 / 1440 * 100vw), 1092px);
  z-index: 0;
  pointer-events: none;
  background-image: url("/images/hero-grid.svg");
  background-repeat: no-repeat;
  background-position: left top;
  background-size: 1333.66px 1092px;
  /* The SVG only has crosshair groups in its LEFT half (Column 1
     of the 2x2 matrix). Mirror horizontally so the crosshairs
     render on the RIGHT side of the rendered element — which is
     the side visible on the page. */
  transform: scaleX(-1);
  /* Diagonal mask: density TOP-RIGHT (visible near Press card),
     fading toward bottom-left so the top crosshair reads densely
     and the lattice dissolves into the page below. */
  -webkit-mask-image: linear-gradient(to bottom left, #000 35%, transparent 80%);
          mask-image: linear-gradient(to bottom left, #000 35%, transparent 80%);
}

@media (max-width: 1024px) {
  .contact-hero-grid-bl { display: none; }
}

/* Contact-page sections AFTER the ContactHero section (General inquiry
   contentSection + the form FormBlock) paint white so the body's
   lavender wash doesn't bleed through behind the form. Scoped to
   `~ section` so only Contact-page-following sections are affected.
   The CTABand is excluded — it carries its own dark rounded-card
   styling and must keep var(--cta-bg) as its background. */
/* Every sibling after ContactHero paints white so the body's lavender
   wash doesn't bleed through. The CTABand opts out via :not(.cta-band)
   so its dark rounded-card background stays. The selector matches both
   <section> blocks (contentSection, etc.) and <div class="my-16">
   wrappers (formBlock, which RenderBlocks puts in .my-16 instead of
   a section). */
.contact-hero-section ~ section:not(.cta-band),
.contact-hero-section ~ div.my-16 {
  position: relative;
  background: #ffffff;
  /* Override Tailwind my-16 = 4rem vertical margin. The form-area
     section spacing is owned by the surrounding contentSection
     padding-top instead, so the form wrapper itself should have a
     minimal margin. */
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

/* Per Figma "content" group spec — the General Inquiry section
   (heading contentSection + form + footer contentSection) is a single
   766px-wide column centered on the page, with 48px gap between rows.
   Each contentSection/formBlock renders as its own <section>, so we
   constrain their inner .container to 766 max-width + auto margin
   to land them in the same 766px column. */
.contact-hero-section ~ section:not(.cta-band) > .container,
.contact-hero-section ~ div:has(> .form-block-wrap),
.contact-hero-section ~ section:not(.cta-band) > .form-block-wrap {
  max-width: 766px;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0;
  padding-right: 0;
}

/* Vertical spacing between consecutive form-area sections. The first
   section gets a 96px top offset (so the General Inquiry heading
   doesn't sit flush against the ContactHero section above); the
   privacy footer section below the form gets a tighter 24px so the
   "We respect your privacy..." line sits close to the Send Message
   button (per Figma). */
.contact-hero-section ~ section:not(.cta-band) {
  padding-top: 24px;
  padding-bottom: 48px;
}
.contact-hero-section + section:not(.cta-band) {
  padding-top: 96px;
}

/* The FormBlock isn't wrapped in <section> by RenderBlocks — it lands
   inside a <div class="my-16"> wrapper. Kill that wrapper's lavender
   bleed-through, constrain its width, and center it. Bottom padding is
   intentionally 0 so the privacy footer section below renders closer
   to the Send Message button (its own padding-top provides the gap). */
.contact-hero-section ~ div:has(.form-block-wrap) {
  background: #ffffff;
  max-width: 766px;
  margin-left: auto;
  margin-right: auto;
  padding: 0;
}

/* The form block itself — remove the boxed border + rounded card
   from the template default, since the Figma form sits naked on
   white (no card frame around it). */
.form-block-wrap {
  width: 100%;
}
.form-block {
  padding: 0;
  border: none;
  border-radius: 0;
}

/* Flex-wrap row container that lets 50%/50% fields share a row. */
.form-block-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
}
.form-block-field {
  /* Width % comes from inline `flex` + `max-width` set by the
     <Width> component. Override the template's mb-6 stacking. */
  margin-bottom: 0;
}

/* Submit button — Figma "Send message" pill spec: 238 x 60, #151127,
   fully rounded (border-radius 30 = half height), white DM Sans 16/24
   medium text. */
.form-block-submit {
  display: inline-flex !important;
  align-items: center;
  justify-content: center;
  margin-top: 48px;
  width: 238px;
  height: 60px;
  padding: 0 32px;
  background: #151127 !important;
  color: #ffffff !important;
  border-radius: 30px !important;
  font-family: var(--font-dm-sans);
  font-weight: 500;
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
  transition: background-color 120ms ease-out;
  border: none;
}
.form-block-submit:hover { background: #2A1F4D !important; }

/* Acknowledgement checkbox — Figma spec:
   - Unchecked: 20x20 box, white fill, grey #D1D1DB border, 4px radius.
   - Checked: dark #151127 fill with a white check icon.
   Scoped to the Contact form area so other forms keep their own
   styling. Targets the Radix checkbox root via [data-slot="checkbox"]. */
.contact-hero-section ~ section [data-slot="checkbox"],
.contact-hero-section ~ div.my-16 [data-slot="checkbox"] {
  width: 20px !important;
  height: 20px !important;
  background: #ffffff !important;
  border: 1.5px solid #D1D1DB !important;
  border-radius: 4px !important;
  box-shadow: none !important;
  flex: none;
}
.contact-hero-section ~ section [data-slot="checkbox"][data-state="checked"],
.contact-hero-section ~ div.my-16 [data-slot="checkbox"][data-state="checked"] {
  background: #151127 !important;
  border-color: #151127 !important;
  color: #ffffff !important;
}
.contact-hero-section ~ section [data-slot="checkbox-indicator"],
.contact-hero-section ~ div.my-16 [data-slot="checkbox-indicator"] {
  color: #ffffff !important;
}

/* Checkbox row alignment — the Checkbox component wraps the box + the
   label in a `flex items-center gap-2` div, which centers the box
   vertically across the (wrapping) 2-line label so the box sits
   between the lines. Override to top-align so the box lines up with
   the FIRST line of label text. The 3px top offset visually centers
   the 20px box against a 24px line-height first line. */
.contact-hero-section ~ section [data-slot="checkbox"]:not(.no-row-align) ~ label,
.contact-hero-section ~ div.my-16 [data-slot="checkbox"]:not(.no-row-align) ~ label {
  /* sibling-label trick fails because the wrapper is flex; instead
     target the parent flex row via :has() */
}
.contact-hero-section ~ section .form-block-fields div:has(> [data-slot="checkbox"]),
.contact-hero-section ~ div.my-16 .form-block-fields div:has(> [data-slot="checkbox"]) {
  align-items: flex-start;
}
.contact-hero-section ~ section [data-slot="checkbox"],
.contact-hero-section ~ div.my-16 [data-slot="checkbox"] {
  margin-top: 3px;
}

/* Inputs + textarea + select trigger: Figma "Required" field style —
   #F6F6F9 grey pill, no visible border. Scoped to the Contact form
   area so other forms on the site keep their existing styling.
   :not([type="checkbox"]) excludes the consent checkbox, which needs
   its own (much smaller) styling below.

   Per Figma, all single-line inputs (Name, Email, Subject) and the
   Select trigger render as a 48-tall pill with radius 24 — fully
   rounded ends. The Message textarea is shaped differently (taller,
   gentler radius) and gets its own rule below. */
.contact-hero-section ~ section input:not([type="checkbox"]),
.contact-hero-section ~ section [data-slot="select-trigger"],
.contact-hero-section ~ div.my-16 input:not([type="checkbox"]),
.contact-hero-section ~ div.my-16 [data-slot="select-trigger"] {
  background: #F6F6F9 !important;
  border: 1px solid #F6F6F9 !important;
  border-radius: 24px !important;
  min-height: 48px !important;
  height: 48px !important;
  padding: 0 20px !important;
  font-family: var(--font-dm-sans);
  font-size: 16px !important;
  line-height: 24px !important;
  color: var(--ink, #1B1230) !important;
  box-shadow: none !important;
}
/* Textarea — taller, gentler 10px radius, multi-line. */
.contact-hero-section ~ section textarea,
.contact-hero-section ~ div.my-16 textarea {
  background: #F6F6F9 !important;
  border: 1px solid #F6F6F9 !important;
  border-radius: 10px !important;
  min-height: 120px !important;
  padding: 18px 20px !important;
  font-family: var(--font-dm-sans);
  font-size: 16px !important;
  line-height: 24px !important;
  color: var(--ink, #1B1230) !important;
  box-shadow: none !important;
  resize: vertical;
}
/* Placeholder text inside the SelectValue renders as a child span;
   match the Figma 0.7 opacity ink color when no value is selected. */
.contact-hero-section ~ section [data-slot="select-trigger"] [data-slot="select-value"],
.contact-hero-section ~ div.my-16 [data-slot="select-trigger"] [data-slot="select-value"] {
  color: rgba(27, 18, 48, 0.7);
}
.contact-hero-section ~ section input:not([type="checkbox"]):focus,
.contact-hero-section ~ section textarea:focus,
.contact-hero-section ~ section [data-slot="select-trigger"]:focus,
.contact-hero-section ~ div.my-16 input:not([type="checkbox"]):focus,
.contact-hero-section ~ div.my-16 textarea:focus,
.contact-hero-section ~ div.my-16 [data-slot="select-trigger"]:focus {
  outline: 2px solid var(--purple, #4B33C1);
  outline-offset: 2px;
  border-color: var(--purple, #4B33C1) !important;
}
.contact-hero-section ~ section input::placeholder,
.contact-hero-section ~ section textarea::placeholder,
.contact-hero-section ~ div.my-16 input::placeholder,
.contact-hero-section ~ div.my-16 textarea::placeholder {
  color: rgba(27, 18, 48, 0.7);
  opacity: 1;
}

/* Field label spacing: Figma puts ~8px between the label and the
   input box. Override Tailwind's tighter default. */
.contact-hero-section ~ section label,
.contact-hero-section ~ div.my-16 label {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-dm-sans);
  font-size: 14px;
  font-weight: 400;
  color: var(--ink, #1B1230);
}

/* Select dropdown panel — the floating menu that opens when the
   trigger is clicked. The shadcn default ships with a dark
   highlighted state which paints the first/active item dark and
   makes its dark text invisible (Figma screenshot bug). Force every
   item to render as light surface with dark text + a subtle hover
   highlight, matching the grey input fields above. The dropdown
   uses portal rendering so it isn't a DOM descendant of
   .contact-hero-section — we target via [data-slot] attributes
   instead. */
[data-slot="select-content"] {
  background: #ffffff !important;
  border: 1px solid #F6F6F9 !important;
  border-radius: 10px !important;
  box-shadow: 4px 10px 65px -5px rgba(0, 0, 0, 0.1),
              4px 8px 10px -6px rgba(0, 0, 0, 0.1) !important;
  padding: 8px !important;
}
[data-slot="select-item"] {
  background: transparent !important;
  color: var(--ink, #1B1230) !important;
  font-family: var(--font-dm-sans);
  font-size: 16px !important;
  padding: 10px 12px !important;
  border-radius: 6px !important;
  cursor: pointer;
}
[data-slot="select-item"]:hover,
[data-slot="select-item"][data-highlighted],
[data-slot="select-item"][data-state="checked"] {
  background: #F6F6F9 !important;
  color: var(--ink, #1B1230) !important;
}

/* Hero head — left-aligned, Amethysta 48 title + DM Sans 20 lead. */
.contact-hero-head {
  text-align: left;
  margin-bottom: 96px;
}
.contact-hero-head h1 {
  font-family: var(--resources-hero-h1-font-family);
  font-size: var(--resources-hero-h1-font-size);
  font-weight: var(--resources-hero-h1-font-weight);
  line-height: var(--resources-hero-h1-line-height);
  margin: 0;
}
.contact-hero-head .lead {
  font-family: var(--resources-hero-lead-font-family);
  font-size: var(--resources-hero-lead-font-size);
  font-weight: var(--resources-hero-lead-font-weight);
  line-height: var(--resources-hero-lead-line-height);
  margin-top: 24px;
  max-width: 600px;
}

/* "How can we help?" subtitle — sits above the cards, centered with
   the card column, Amethysta 40 per Figma. */
.contact-hero-subtitle {
  font-family: var(--resources-hero-h1-font-family);
  /* Matches the card heading Amethysta Regular 48. */
  font-size: 48px;
  font-weight: 400;
  line-height: 1.1;
  margin: 0 auto 32px;
  max-width: 766px;
  color: var(--ink, #1B1230);
  /* Pull the subtitle (and cards below) LEFT by 83px/2 = 41.5px to
     undo HALF the container's 83px title-alignment offset, so the
     subtitle + cards center visually on the page (not under the
     title's left edge). Since the container is centered with equal
     left+right margin AND extra 83px on the left, the cards land
     41.5px to the right of true center; we shift back by that amount.
     Cards below inherit this shift via margin on .contact-hero-cards. */
  transform: translateX(-41.5px);
}

/* Stacked cards — 766x402 each, single column, CENTERED in the
   container per the Figma reference. */
.contact-hero-cards {
  display: grid;
  grid-template-columns: 766px;
  row-gap: 48px;
  justify-content: center;
  /* Same -41.5px nudge as .contact-hero-subtitle so the card column
     also centers visually on the page, ignoring the container's
     83px title-alignment offset above. */
  transform: translateX(-41.5px);
}
/* Per Figma "card" spec — 766 wide, padding 40, gap 48 between rows,
   flex column with items aligned to the start. Shadow is the Figma
   "shadow/xl" token (two layered shadows). */
.contact-hero-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 766px;
  height: 402px;
  box-sizing: border-box;
  padding: 40px;
  background: #FFFFFF;
  border-radius: 30px;
  box-shadow: 4px 10px 65px -5px rgba(0, 0, 0, 0.1),
              4px 8px 10px -6px rgba(0, 0, 0, 0.1);
}
/* Per-element spacing inside cards, per Figma. Heading + body sit
   at the top (20px gap). The action group (CTA +/or email link)
   sits 48px below the body — now that the heading is Amethysta 48
   (taller than the previous 32), the total content stack fills the
   card height naturally, and the URL lands close to the bottom
   padding without needing margin-top:auto. CTA + email link pair
   at 16px. */
.contact-hero-card h2 + p {
  margin-top: 20px;
}
.contact-hero-card p + .contact-hero-card-cta,
.contact-hero-card p + .contact-hero-card-link {
  margin-top: 48px;
}
.contact-hero-card .contact-hero-card-cta + .contact-hero-card-link {
  margin-top: 16px;
}
/* Cards without a CTA pill button (Security & Compliance, Press &
   Partnerships) are shorter — 766 x 326 default per Figma. */
.contact-hero-card:not(:has(.contact-hero-card-cta)) {
  height: 326px;
}
/* The Technical support card (2nd) has the italic footnote line —
   766 x 446 per Figma to fit the extra "We're in beta..." text. */
.contact-hero-card:has(.contact-hero-card-note) {
  height: 446px;
}
/* The Press & Partnerships card (4th, the LAST stacked card) is the
   shortest at 766 x 298 — its body is only 2 lines vs Security's 3,
   so Figma trims the height accordingly. */
.contact-hero-cards .contact-hero-card:last-child:not(:has(.contact-hero-card-cta)) {
  height: 298px;
}
.contact-hero-card h2 {
  /* Per Figma — Amethysta Regular 48 (same scale as the page hero
     "Get in touch" title). */
  font-family: var(--resources-hero-h1-font-family);
  font-size: 48px;
  font-weight: 400;
  line-height: 1.1;
  margin: 0;
  color: var(--ink, #1B1230);
}
.contact-hero-card p {
  /* Figma body spec: DM Sans Regular 20/28 in ink #161129, 667px
     wide x 84px tall (3 lines at 28px line-height = 84). */
  font-family: var(--font-dm-sans);
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
  color: #161129;
  margin: 0;
  /* pre-line honors explicit \n line breaks in the seed body string
     while still collapsing other whitespace and wrapping long runs.
     Used to force the 3-line layout on the Sales card body. */
  white-space: pre-line;
}
/* CTA: dark pill button (matches header's "Start free trial" pill). */
.contact-hero-card-cta {
  /* Matches the Figma "Book a demo" pill export — 226 x 60 dark pill,
     #151127 background, white DM Sans 16/24 medium label, fully
     rounded (border-radius 30 = half of height for a true pill). */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: flex-start;
  min-width: 226px;
  height: 60px;
  padding: 0 32px;
  background: #151127;
  color: #ffffff;
  border-radius: 30px;
  font-family: var(--font-dm-sans);
  font-weight: 500;
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
  transition: background-color 120ms ease-out;
}
.contact-hero-card-cta:hover {
  background: #2A1F4D;
  text-decoration: none;
  color: #ffffff;
}
/* Underlined email link below the CTA button (or instead of it, for
   cards without a CTA). */
.contact-hero-card-link {
  /* Per Figma "content" frame spec — 190 x 36 inline pill, 8px top/
     bottom padding, 1px solid #1D1232 bottom border (replaces the
     CSS text-decoration: underline so the underline width matches
     the 190px content frame exactly, not the text glyph). */
  display: inline-flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  padding: 8px 0;
  gap: 8px;
  height: 36px;
  align-self: flex-start;
  font-family: var(--font-dm-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: var(--ink, #1B1230);
  text-decoration: none;
  border-bottom: 1px solid #1D1232;
}
/* Italic footnote below the email link — Figma "We're in beta.
   Response time may vary." spec: DM Sans Italic 20/28 at 70% ink.
   Sits below the email link with the same 16px gap pattern used
   between CTA and email link above. */
.contact-hero-card-note {
  display: block;
  margin-top: 16px;
  font-family: var(--font-dm-sans);
  font-style: italic;
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: rgba(29, 18, 50, 0.7);
}

/* Mobile fallback — cards become fluid width / auto height. */
@media (max-width: 820px) {
  .contact-hero-cards {
    grid-template-columns: 1fr;
  }
  .contact-hero-card {
    width: 100%;
    height: auto;
    padding: 32px 24px;
  }
  .contact-hero-subtitle {
    font-size: 32px;
    text-align: center;
  }
}
/* Resources hero container capped at 1440 and centered, matching the
   site header. On wider viewports equal left/right margins appear. */
.hero-centered.hero-centered-decor > .container {
  position: relative;
  z-index: 1;
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(24px, 3.5vw, 50px);
  padding-right: clamp(24px, 3.5vw, 50px);
}
.hero-decor-resources {
  position: absolute;
  top: 66px;
  /*
    Native 749x1092 size — top-left quadrant of the lattice. At 1440
    viewport this fills the right portion of the page; on wider
    viewports it STAYS PUT (anchored to the 1440 frame, not the
    viewport edge), and the mirrored ::after below paints the
    top-right quadrant continuing to the right of it.

    Position math: at 1440 viewport the grid sits at the same place
    as before (right edge 50-68 = -18px past the page right). On
    wider viewports the (100% - 1440)/2 term grows, pinning the grid
    left of the right edge by that same amount.
  */
  right: calc((100% - 1440px) / 2 + clamp(24px, 3.5vw, 50px) - 68px);
  left: auto;
  width: 749px;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: radial-gradient(ellipse 110% 110% at 70% 30%, #000 45%, transparent 95%);
          mask-image: radial-gradient(ellipse 110% 110% at 70% 30%, #000 45%, transparent 95%);
}

/* Top-right quadrant — a horizontally mirrored copy of hero-grid.svg
   sitting immediately to the right of the original grid. On viewports
   wider than 1440 the gap between Grid 1's right edge and the
   viewport's right edge grows, and this mirrored copy fills that gap
   with continued lattice pattern. At 1440 it sits off-screen.

   Mask: kept SOLID across the visible LEFT side (the seam where it
   meets Grid 1), fading on the RIGHT side (the outer page edge).
   After the scaleX(-1) mirror, the SVG's left edge becomes the visible
   right edge — so the mask should be solid on what reads as the SVG's
   *right* edge in pre-transform coordinates. Linear gradient from
   solid → transparent going LEFT in pre-transform = solid on the
   visible seam side, fading on the outer edge. */
.hero-centered.hero-centered-decor::after {
  content: "";
  position: absolute;
  top: 66px;
  left: auto;
  right: calc((100% - 1440px) / 2 + clamp(24px, 3.5vw, 50px) - 68px - 681px);
  width: 749px;
  height: 1092px;
  z-index: 0;
  pointer-events: none;
  background: url("/images/hero-grid.svg") left top / 749px 1092px no-repeat;
  transform: scaleX(-1);
  -webkit-mask-image: linear-gradient(to left, #000 0%, #000 70%, transparent 100%);
          mask-image: linear-gradient(to left, #000 0%, #000 70%, transparent 100%);
}
@media (max-width: 1024px) {
  .hero-decor-resources { display: none; }
  .hero-centered.hero-centered-decor::after { display: none; }
}
@media (max-width: 880px) {
  .hero-decor-resources { display: none; }
}

/* Lock the Resources hero headline at the Figma display size (72px) on
   desktop instead of fluidly resizing with the viewport. Below the
   1024px tablet breakpoint it can still scale down. */
.hero-centered.hero-centered-decor h1 {
  font-size: 72px;
}
@media (max-width: 1024px) {
  .hero-centered.hero-centered-decor h1 {
    font-size: clamp(40px, 5vw, 72px);
  }
}

/* Reusable background "white ball" (Figma white-ball.svg) — a soft white
   bloom bleeding in from the right behind a section's content. Add the
   `.section-glow-host` class to the section and drop in
   `<img class="section-glow" src="/images/white-ball.svg">` as its first
   child. Used on the trust → pricing region (and reusable elsewhere). */
.section-glow-host { position: relative; }
.section-glow-host > .container { position: relative; z-index: 1; }
.section-glow {
  position: absolute;
  top: -40px;
  right: -6%;
  width: 805px;
  max-width: 64vw;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
@media (max-width: 880px) { .section-glow { display: none; } }

/* Footer "ellipse" (Figma blue-ellipse.svg) — the wide, very soft blue bloom
   bleeding into the footer from the left, behind the content. */
/* margin-top pulls the footer UP so its lavender/blue background rises behind
   the lower third of the .cta-band card (Figma overlap). z-index:0 makes the
   footer one self-contained stacking context that sits BELOW the card (z:1).
   The footer's large top padding keeps the wordmark/columns clear of the card. */
/* Footer pulls UP behind the .cta-band so the dark card overlaps the
   lavender footer band's top edge (Figma) — a small reveal, not a
   full third. Pairs with the .cta-band's `z-index: 1` so the card
   paints above the lavender. Site-footer's padding-top below
   absorbs the overlap so the wordmark sits in the visible band. */
.site-footer { position: relative; z-index: 0; overflow: hidden; margin-top: clamp(-80px, -6vw, -48px); }
.site-footer > .container { position: relative; z-index: 1; }
/* Figma "blue ball" (Copy as CSS): a 488px blue circle bleeding in from the
   left edge, behind the blueprint grid. */
.footer-glow {
  position: absolute;
  z-index: 0;
  width: 488px;
  height: 488px;
  left: -392px;
  top: 66px;
  background: #0081FF;
  border-radius: 50%;
  opacity: 0.8;
  filter: blur(90px);
  pointer-events: none;
}
@media (max-width: 880px) { .footer-glow { display: none; } }

/* Figma footer "blueprint" — the faint node/connector lattice behind the
   brand, top-left. Reuses hero-grid.svg (same motif as hero + companion),
   feathered so it dissolves into the lavender wash. */
.site-footer::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: clamp(-160px, calc(-110 / 1440 * 100vw), -60px);
  left: clamp(-220px, calc(-130 / 1440 * 100vw), -70px);
  width: clamp(640px, calc(853 / 1440 * 100vw), 853px);
  height: clamp(650px, calc(865 / 1440 * 100vw), 865px);
  background: url("/images/footer-grid.svg") no-repeat top left;
  background-size: contain;
  opacity: 1;
  -webkit-mask-image: radial-gradient(115% 110% at 30% 42%, #000 70%, transparent 100%);
  mask-image: radial-gradient(115% 110% at 30% 42%, #000 70%, transparent 100%);
  pointer-events: none;
}
@media (max-width: 880px) { .site-footer::before { display: none; } }

/* Cards float nicely on the gradient with a hint of translucency. */
.card {
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(140%) blur(6px);
  box-shadow: 0 8px 24px rgba(40, 60, 120, 0.06);
}
/* Soft cards (used in dark / inverted contexts) keep their original look. */
.section-dark .card,
.cta-band .card { background: #fff; backdrop-filter: none; }
.hero-split {
  display: grid;
  /* Napoli's column is PINNED at its original ~512 px width so the
     mascot card never shrinks; the text column takes the rest, which
     gives the larger headline room to render on 2 lines. The minmax
     on the Napoli column lets it scale down gracefully on narrow
     desktop widths before the 880 px breakpoint stacks the columns. */
  grid-template-columns: minmax(0, 1fr) minmax(400px, 512px);
  gap: clamp(28px, 5vw, 80px);
  align-items: center;
}
@media (max-width: 1024px) { .hero-split { grid-template-columns: 1fr; } }

.hero h1 {
  /* HARD RULE: this headline is two lines, pinned by an explicit <br>.
     Figma Headline 1 Serif = 72px / line-height 110% / -0.05em. */
  font-size: clamp(48px, 5.2vw, 72px);
  margin-bottom: 24px;
  line-height: 1.1;
  letter-spacing: -0.05em;
  text-wrap: balance;
}
.hero p.lead {
  font-size: clamp(18px, 1.5vw, 20px);
  color: var(--ink);
  margin-bottom: 24px;
  max-width: 560px;
  line-height: 1.4;
}
.hero-actions { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; }
/* Figma stacks the home hero CTAs vertically, equal 238px width,
   20px gap (Frame 1000005690: flex-direction column, gap 20px). */
.hero-split .hero-actions { flex-direction: column; align-items: flex-start; gap: 20px; flex-wrap: nowrap; }
.hero-split .hero-actions .btn { width: 238px; }

.hero-meta {
  margin-top: 28px;
  color: var(--muted);
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.5;
}

.hero-centered { text-align: center; }
.hero-centered h1 { max-width: 16ch; margin-left: auto; margin-right: auto; }
.hero-centered p.lead { margin-left: auto; margin-right: auto; }
.hero-centered .hero-actions { justify-content: center; }

/* Left-aligned variant — matches the Figma Resources hero (headline +
   lead align to the left, hex grid bleeds off the right edge). The
   headline drops its narrow 16ch cap so it can use the wider column;
   the lead keeps its readable maxLeadWidth set by the block. */
.hero-centered.hero-centered-left { text-align: left; }
.hero-centered.hero-centered-left h1 {
  max-width: none;
  /* Align the "R" with the "f" of "finapolis" in the header logo.
     The header logo SVG is mounted at the container's left edge, but
     the "f" character inside the SVG sits ~83px to the right of the
     image's left edge (the diamond mark + gap take up that space).
     Pushing the H1 in by 83px brings the headline left edge under
     the wordmark's first letter. */
  margin-left: 83px;
  margin-right: 0;
}
.hero-centered.hero-centered-left p.lead {
  margin-left: 83px;
  margin-right: 0;
}
.hero-centered.hero-centered-left .hero-actions { justify-content: flex-start; }

/* ---------- Data-source logos lockup (under hero) ---------- */
/* Figma data-source lockup (public/images/data-sources.svg): the exact 4-logo
   row — polygon.io, Tiingo, FRED, SEC API — as #030208 silhouettes, left-aligned. */
/* The logos sit directly under the hero and must share the hero's left edge.
   The hero uses a wider container (`.hero > .container` = 1400px), while this
   strip's plain `.container` is the sitewide 1160px — which indented the logos
   ~120px to the right of the headline/CTAs. Match the hero's container width so
   the lockup's left edge lines up with the hero text. */
.data-sources-strip > .container {
  max-width: 1400px;
}

.data-sources-lockup {
  display: block;
  width: 100%;
  max-width: 820px;
  height: auto;
}

/* ---------- Companion split (Figma "Your investment companion") ---------- */
/* Faint visual placeholder on the left; title + intro + left-accented item
   list on the right. */

/* The section is its own background "band": a soft white bloom behind the left
   visual and a blue glow bleeding in from the top-right. The layers sit behind
   the content (z 0) and never catch pointer events. No `overflow: clip` here —
   `html, body { overflow-x: clip }` already blocks horizontal scroll, and the
   glows are feathered to nothing by their own blur. */
.companion-band { position: relative; }
.companion-band > .container { position: relative; z-index: 1; }
.companion-glow-white,
.companion-glow-blue {
  position: absolute;
  z-index: 0;
  height: auto;
  pointer-events: none;
  user-select: none;
}
/* Soft white bloom behind the left visual — a CSS radial-gradient that fades to
   fully transparent well inside its box, so (unlike the white-ball.svg, whose
   blur is clipped at the canvas edge) it never leaves a hard vertical edge. */
.companion-glow-white {
  top: 50%;
  left: max(-280px, calc((100% - 1440px) / 2 - 240px));
  transform: translateY(-50%);
  width: clamp(620px, 60vw, 980px);
  height: clamp(620px, 60vw, 980px);
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 70%);
  opacity: 0.5;
}
/* Soft blue glow bleeding from the top-right (the exact Figma blue ball, held
   a little softer so it reads as a wash, not a hotspot). */
.companion-glow-blue {
  top: clamp(-280px, -18vw, -150px);
  right: max(-160px, calc((100% - 1440px) / 2 - 120px));
  width: clamp(480px, 50vw, 820px);
  opacity: 0.7;
}
/* Bottom-left node/connector lattice + its white bloom (reuses hero-grid.svg).
   Anchored to the FRAME's LEFT edge (not the centred 1440 box) so it bleeds off
   the left and is cut by the white past 1920 — never floated mid-page with a hard
   cut. Rotated 180deg so the dense corner + bloom land at the bottom-left, then
   radially feathered so the lattice dissolves up-and-right into the page. */
.companion-grid {
  position: absolute;
  z-index: 0;
  bottom: clamp(-120px, calc(-60 / 1920 * 100vw), -40px);
  left: clamp(-180px, calc(-90 / 1920 * 100vw), -40px);
  width: clamp(440px, calc(760 / 1920 * 100vw), 760px);
  height: auto;
  transform: rotate(180deg);
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: radial-gradient(145% 145% at 100% 0%, #000 18%, transparent 84%);
  mask-image: radial-gradient(145% 145% at 100% 0%, #000 18%, transparent 84%);
}
@media (max-width: 1024px) {
  .companion-glow-blue,
  .companion-grid { display: none; }
}
@media (max-width: 880px) {
  .companion-glow-white { display: none; }
}

.companion-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}
@media (max-width: 880px) {
  .companion-split { grid-template-columns: 1fr; }
  .companion-visual { display: none; }
}
/* The left column is an open placeholder area in the Figma — no hard card; the
   section's white bloom + bottom-left grid read straight through it. Kept as a
   layout spacer so the split keeps its proportions until the onboarding visual
   ships. */
.companion-visual {
  min-height: 440px;
}
.companion-head { margin-bottom: 8px; }
.companion-head h2 { margin-bottom: 16px; }
.companion-intro {
  font-size: 20px;
  line-height: 1.5;
  color: var(--ink-3);
  max-width: 46ch;
}
/* Figma "timeline" line down the left of the items: a 5px white track with
   rounded caps and the design's drop shadow (which is exactly --shadow), plus
   a dark #1B1230 "active" segment over the FIRST item. */
.companion-list {
  margin-top: 36px;
  position: relative;
  display: flex; flex-direction: column; gap: 28px;
  padding-left: 28px;
}
.companion-list::before {
  content: "";
  position: absolute; left: 0; top: 2px; bottom: 2px;
  width: 5px; border-radius: 999px;
  background: #fff;
  box-shadow: var(--shadow);
}
.companion-item { position: relative; }
/* dark active segment — overlays the white track for the first item */
.companion-item:first-child::before {
  content: "";
  position: absolute; left: -28px; top: -8px; bottom: 0;
  width: 5px; border-radius: 999px;
  background: #1b1230;
}
.companion-item h3 { font-size: 20px; font-weight: 600; margin-bottom: 8px; }
.companion-item p { font-size: 16px; line-height: 1.55; color: var(--muted); }

/* ---------- Visual placeholders (figma-like) ---------- */

.visual {
  background: var(--bg-dim);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  display: grid;
  place-items: center;
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: 24px;
  min-height: 240px;
  position: relative;
  overflow: hidden;
}
.visual.tall { min-height: 480px; }
.visual.short { min-height: 200px; }
.visual.darker { background: var(--bg-shape); }
.visual span { position: relative; z-index: 1; }
.visual small { display: block; color: var(--muted-2); font-size: 12px; margin-top: 4px; }

/* Napoli portrait — transparent frame, image centered, no border. */
.visual.napoli-portrait {
  background: transparent;
  border: none;
  padding: 0;
}
.visual.napoli-portrait img {
  max-width: 78%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 14px 26px rgba(40, 60, 120, 0.12));
  user-select: none;
  -webkit-user-drag: none;
}

.visual-circle {
  width: 110px; height: 110px;
  border-radius: 50%;
  background: #cfcfd4;
}

/* ─────────────────────────────────────────────────────────
   Napoli's diorama — a glassy, contained space he lives in.

   Structure:
     .napoli-space   → outer card (top stacking layer)
       .napoli-bubble → speech bubble (overlays top of stage)
       .napoli-stage  → walking ground (overflow hidden)
         .napoli-actor → translates horizontally; holds clips
       .napoli-chat   → text input + send button

   JS drives a small state machine: an intro walk-in (~1.2s),
   then he wanders his stage using walk/turn clips with idle
   pauses. Submitting the chat form pops the speech bubble.
   ───────────────────────────────────────────────────────── */
.visual.hero-mascot {
  background: transparent;
  border: none;
  padding: 0;
  min-height: 0;
  overflow: visible;       /* Never clip Napoli */
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 5;              /* Above sibling hero content */
}

.napoli-space {
  position: relative;
  width: 100%;
  /* Bumped from 440 → 540 so the card matches the Figma proportion
     (the wireframe's right column is nearly as wide as the text
     column on the left, not a small 440px chip). */
  max-width: 540px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 24px;
  /* Pulled back from 22px → 14px to match the wireframe's tighter,
     less-rounded card. */
  border-radius: 14px;
  /* Figma's right-side placeholder is a flat, near-white box with a
     thin border — no glass morphism, no heavy shadow. Removed the
     backdrop-filter (heavy blur + saturation), the rgba translucency,
     and the multi-layer inset shadow. Replaced with a near-solid
     light fill so the card reads as a deliberate object rather than
     a floating glass tile. */
  background: #f5f6f8;
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(10, 10, 10, 0.04);
  z-index: 5;
}

/* ---- Speech bubble ---- */
.napoli-bubble {
  position: relative;
  align-self: flex-start;
  max-width: 92%;
  margin-bottom: -6px;
  padding: 12px 16px;
  background: #fff;
  border: 1.5px solid var(--ink);
  border-radius: 14px;
  font-size: 14px;
  line-height: 1.45;
  color: var(--ink-2);
  box-shadow: 4px 4px 0 var(--ink);
  transform-origin: 24px 100%;
  transform: scale(0);
  opacity: 0;
  pointer-events: none;
  transition: transform 240ms cubic-bezier(0.34, 1.56, 0.64, 1),
              opacity   180ms ease-out;
}
.napoli-bubble.is-visible {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}
.napoli-bubble::after,
.napoli-bubble::before {
  content: "";
  position: absolute;
  bottom: -10px;
  left: 28px;
  width: 0;
  height: 0;
  border: 10px solid transparent;
  border-top-color: var(--ink);
  border-bottom: 0;
}
.napoli-bubble::before {
  bottom: -8px;
  left: 30px;
  border: 8px solid transparent;
  border-top-color: #fff;
  border-bottom: 0;
  z-index: 1;
}
.napoli-bubble-text {
  margin: 0;
}

/* Typing indicator — three pulsing dots */
.napoli-bubble.is-typing .napoli-bubble-text {
  display: inline-flex;
  gap: 4px;
  padding: 4px 0;
}
.napoli-bubble.is-typing .napoli-bubble-text::before,
.napoli-bubble.is-typing .napoli-bubble-text::after,
.napoli-bubble.is-typing .napoli-bubble-text > * {
  content: "";
}
.napoli-bubble.is-typing .napoli-bubble-text {
  /* Render three dots via three pseudo elements isn't possible in
     CSS, so we ship the dots as <span>s from JS. */
}
.napoli-bubble.is-typing .napoli-bubble-text span {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ink);
  animation: napoli-typing 1.2s ease-in-out infinite;
}
.napoli-bubble.is-typing .napoli-bubble-text span:nth-child(2) { animation-delay: 0.15s; }
.napoli-bubble.is-typing .napoli-bubble-text span:nth-child(3) { animation-delay: 0.30s; }

@keyframes napoli-typing {
  0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
  30%           { opacity: 1;   transform: translateY(-3px); }
}

/* ---- Stage (the ground Napoli walks on) ----
   Note: overflow is VISIBLE on purpose. The rounded background
   gradient still paints inside the border-radius (CSS clips
   backgrounds to border-radius automatically), but the absolutely-
   positioned actor — and his drop shadow — render without being
   sliced by the rounded corners or the bottom edge. Previously we
   had overflow:hidden here, which was cutting off Napoli's tail,
   his drop shadow, and any limb that extended past his bounding box
   during walk-cycle frames. The JS positions him at 33–67% of the
   stage width (sprite width: 58%, so half-width: 29%), which keeps
   him well inside even with a few percent of breathing room. */
.napoli-stage {
  position: relative;
  height: clamp(220px, 32vw, 300px);
  border-radius: 14px;
  /* overflow-x: clip prevents the actor's intro position (left: 75%+) from
     extending the document scrollWidth past the viewport on mobile.
     overflow-y stays visible so the actor's drop shadow renders below. */
  overflow-x: clip;
  overflow-y: visible;
  background:
    radial-gradient(ellipse 80% 60% at 50% 100%, rgba(150, 188, 222, 0.25), rgba(150, 188, 222, 0) 70%),
    linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.4) 100%);
  cursor: pointer;
  outline: none;
  -webkit-tap-highlight-color: transparent;
}
.napoli-stage:focus-visible {
  box-shadow: 0 0 0 2px var(--ink);
}

/* The actor sits at the bottom of the stage. JS sets `left` (a
   percentage of the stage width) to drive horizontal motion. The
   `--actor-w` variable controls his on-screen size. */
.napoli-actor {
  --actor-w: 58%;
  position: absolute;
  /* bottom: 0 puts Napoli's lowest pixel exactly on the stage's
     bottom edge. Previously this was -4% to "tuck him into the
     ground" — but that only looked right while overflow was hidden.
     With overflow visible (so the drop shadow can render), -4% would
     leave the rounded edge of the stage visibly cutting through his
     lower body. 0 keeps him grounded AND fully readable. */
  bottom: 0;
  left: 50%;
  width: var(--actor-w);
  transform: translateX(-50%);
  /* `left` is the property we tween — JS sets transitions on it. */
  will-change: left;
}

.napoli-static {
  width: 100%;
  height: auto;
  display: block;
  opacity: 0;
  filter: drop-shadow(0 10px 18px rgba(10, 10, 10, 0.1));
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
  background: transparent;
}

.napoli-clip {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  filter: drop-shadow(0 10px 18px rgba(10, 10, 10, 0.1));
  user-select: none;
  -webkit-user-drag: none;
  pointer-events: none;
  background: transparent;
  /* NO opacity transition. A crossfade between two clips drops the
     combined coverage to ~75% at the midpoint (1 − 0.5·0.5), which
     lets the white card background bleed through. That's the "white
     flash" symptom. Hard-cut swaps avoid this — combined with z-index
     stacking in the JS (newest active clip on top), the incoming clip
     covers the outgoing one for the swap frame, so the user never
     sees a transparent middle. */
}
.napoli-clip.is-active { opacity: 1; }

/* ---- Chat input ---- */
.napoli-chat {
  display: flex;
  gap: 8px;
  align-items: stretch;
}
.napoli-chat input {
  flex: 1;
  min-width: 0;
  padding: 11px 14px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s ease;
}
.napoli-chat input:focus { border-color: var(--ink); }
.napoli-chat input::placeholder { color: var(--muted); }
.napoli-chat button {
  flex-shrink: 0;
  width: 44px;
  border: none;
  border-radius: 10px;
  background: var(--ink);
  color: #fff;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.15s ease;
}
.napoli-chat button:hover { background: #1f1f22; }
.napoli-chat button:active { transform: scale(0.94); }

@media (prefers-reduced-motion: reduce) {
  .napoli-static { opacity: 1; }
  .napoli-clip { display: none !important; }
  .napoli-actor { left: 50% !important; transition: none !important; }
  .napoli-bubble { transition: opacity 0.15s ease; transform: none; }
}

/* ---------- Pricing ---------- */

.price-grid {
  display: grid;
  /* Column count follows the number of tiers (--price-cols, set inline by the
     component): 3 on the home summary, 4 on the pricing page — so the cards
     always fill the row instead of leaving an empty slot.
     minmax(0, 1fr) (not bare 1fr) forces equal-width tracks and lets feature
     text wrap. Bare 1fr resolves to minmax(auto, 1fr), so a card whose longest
     word exceeds its share grows its track and pushes the grid past the
     container (the 4th card was overflowing ~98px and clipping). */
  grid-template-columns: repeat(var(--price-cols, 4), minmax(0, 1fr));
  gap: 24px;
  align-items: stretch;
  position: relative;
}
@media (max-width: 1100px) { .price-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 880px) { .price-grid { grid-template-columns: 1fr; } }

/* Figma "blue ball" behind the HOME pricing summary — a soft blue bloom
   bleeding in from the LEFT edge, behind the cards. Home only: the
   `.price-glow-host` class + `.price-glow` element are added by the PricingCards
   component when the billing toggle is hidden (the home summary); the /pricing
   page omits them. Pure CSS circle straight from the Figma "Copy as CSS"
   (758px, #0081FF, 0.6 opacity, 90px blur, origin left -448px (since nudged down-and-right per Leo) in the 1440
   frame), same technique as .footer-glow. Fluidised + viewport-edge anchored per
   the house decoration convention: exact at 1440, modest left peek elsewhere.
   No overflow:hidden on the host, so the featured card's "Most popular" pill
   (top:-46px) isn't clipped; the page's global overflow-x: clip cuts the left
   bleed. Hidden ≤880px (matches the footer/hero glows). */
.price-glow-host { position: relative; }
.price-glow-host > .container { position: relative; z-index: 1; }
.price-glow {
  position: absolute;
  z-index: 0;
  top: 62%;
  left: clamp(-410px, calc(-298 / 1440 * 100vw), -210px);
  width: clamp(520px, calc(758 / 1440 * 100vw), 758px);
  height: clamp(520px, calc(758 / 1440 * 100vw), 758px);
  transform: translateY(-50%);
  background: #0081ff;
  border-radius: 50%;
  opacity: 0.6;
  filter: blur(90px);
  pointer-events: none;
  user-select: none;
}
@media (max-width: 880px) { .price-glow { display: none; } }

/* Figma white "blueprint" grid lattice over the blue ball, behind the HOME
   pricing cards (the node/connector motif the site already uses in the hero and
   footer). Home only, added by PricingCards as `.price-blueprint` when the
   toggle is hidden. Leo's exact Figma export lives at /images/pricing-grid.svg
   (511×865, white-fill dots/connectors + a baked-in soft white edge glow).

   Layering: the ball and this element are both z-index 0 under the container
   (z-index 1, cards on top), but `.price-blueprint` follows `.price-glow` in the
   DOM so it paints ON TOP of the ball — the white lines only read against the
   blue, and dissolve against the page white, so the grid must overlap the ball.
   Offset down and to the right of the ball's centre (per Leo), still bleeding
   slightly off the left edge; fluidised per the house convention (exact at
   1440). A radial mask feathers the far edges so the lattice fades out rather
   than ending on a hard rectangle (same idea as .site-footer::before). Hidden
   ≤880px with the rest of the glows. */
.price-blueprint {
  position: absolute;
  z-index: 0;
  top: 105%;
  left: clamp(-40px, calc(-10 / 1440 * 100vw), 0px);
  width: clamp(410px, calc(511 / 1440 * 100vw), 511px);
  height: clamp(694px, calc(865 / 1440 * 100vw), 865px);
  transform: translateY(-50%);
  background: url("/images/pricing-grid.svg") no-repeat top left;
  background-size: contain;
  opacity: 0.9;
  -webkit-mask-image: radial-gradient(58% 46% at 16% 20%, #000 40%, transparent 84%);
  mask-image: radial-gradient(58% 46% at 16% 20%, #000 40%, transparent 84%);
  pointer-events: none;
  user-select: none;
}
@media (max-width: 880px) { .price-blueprint { display: none; } }

.price-card {
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-l);
  padding: 32px;
  display: flex; flex-direction: column; gap: 24px;
  position: relative;
  box-shadow: var(--shadow);
}
.price-card.is-featured {
  background: var(--feature-card);
  color: #fff;
  border-color: var(--feature-card);
}
.price-card.is-featured h3,
.price-card.is-featured .price,
.price-card.is-featured .plan-name { color: #fff; }
.price-card.is-featured .price-cap,
.price-card.is-featured p,
.price-card.is-featured .billed { color: #b8b8bc; }
.price-card.is-featured .feature-list li { color: #ededed; }
.price-card.is-featured .feature-list li::before { color: #fff; }
.price-card.is-featured .price-divider { background: #2b2b2b; }
.price-card.is-featured .small-link { color: #d1d1d4; }

/* Figma: the pricing CTA is a full-width pill pinned to the card bottom, so
   every card's button aligns on one baseline. Light cards get a near-black
   fill; the featured (dark) card flips to a white fill. */
.price-card .btn {
  width: 100%;
  min-height: 60px;
  margin-top: auto;
  border-radius: var(--radius-pill);
}
.price-card:not(.is-featured) .btn {
  background: var(--cta-bg);
  color: #fff;
  border-color: transparent;
}
.price-card:not(.is-featured) .btn:hover { background: var(--ink); }
.price-card.is-featured .btn {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}
.price-card.is-featured .btn:hover { background: #ededed; }

/* Figma pricing tier name = DM Sans 400, 30px (e.g. "Advisor"), not a
   small uppercase label. */
.plan-name {
  font-size: 30px;
  line-height: 1.2;
  font-weight: 400;
  color: var(--ink);
  margin-bottom: 0;
}
/* Figma: a muted sub-label sits directly under the plan name (e.g. "For
   self-directed individuals"), above the price. */
.plan-sub {
  font-size: 20px;
  color: var(--muted);
  margin-top: 4px;
  line-height: 1.4;
}
.price-card.is-featured .plan-name { color: #fff; }
.price-card.is-featured .plan-sub { color: #b8b8bc; }
.plan-name.large { font-size: 30px; text-transform: none; letter-spacing: -0.01em; color: var(--ink); font-weight: 400; }

.price-tag { display: flex; align-items: baseline; gap: 4px; }
.price {
  font-size: 60px;
  font-weight: 400;
  line-height: 1;
  /* tabular-nums keeps every digit the same advance width — without
     this, the price column shifts horizontally as digits change. */
  font-variant-numeric: tabular-nums;
  display: inline-block;
  /* Anchor the dip at the bottom-left so the "$" / "/month" baseline
     doesn't appear to lift while the number is mid-tween. */
  transform-origin: 0 100%;
  transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1),
              filter 0.32s cubic-bezier(0.16, 1, 0.3, 1),
              color 0.2s ease;
  will-change: transform, filter;
}
/* During the count tween: a subtle dip in scale + soft blur sells
   the "value is changing" moment without obscuring legibility. The
   cubic-bezier ramps fast and settles slow, so it reads as a held
   breath rather than a flicker. JS adds .is-flipping for the tween
   duration and removes it on completion. */
.price.is-flipping {
  transform: scale(0.965);
  filter: blur(0.4px);
}
/* Slot-machine price reel (PricingCards). Each digit is a vertical strip that
   spins onto the new value when the billing toggle flips. The reel inherits the
   .price font (60px, tabular-nums) so digit widths stay fixed and the column
   doesn't jitter as numbers change. `--reel-shift` nudges the glyphs onto the
   "$" / "/month" baseline (inline-block + overflow:hidden takes its baseline
   from the bottom edge, which otherwise sits the digits slightly low). */
.price-reel {
  display: inline-flex;
  vertical-align: baseline;
  font-variant-numeric: tabular-nums;
}
.price-digit {
  display: inline-block;
  height: 1em;
  line-height: 1;
  overflow: hidden;
  vertical-align: baseline;
}
.price-strip {
  display: block;
  will-change: transform;
}
.price-cell {
  display: block;
  height: 1em;
  line-height: 1;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* Visually-hidden real value so screen readers announce the price even though
   the animated reel is aria-hidden. */
.price-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
/* Reduced-motion: no spin — the strip sits on its settled position and the
   value swaps instantly. */
@media (prefers-reduced-motion: reduce) {
  .price-strip { transition: none !important; }
}

.price-cap { color: var(--muted); font-size: 18px; }
.billed {
  font-size: 13px;
  color: var(--muted);
  display: inline-block;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.billed.is-fading {
  opacity: 0;
  transform: translateY(2px);
}

/* Toggle thumb glide + active-label colour shift, so the affordance
   change feels as deliberate as the price tween it triggers. */
.toggle-switch { transition: background-color 0.25s ease; }
.toggle-switch::after { transition: transform 0.36s cubic-bezier(0.16, 1, 0.3, 1); }
.price-toggle .toggle-label { transition: color 0.2s ease; }

/* Honour reduced-motion: kill the dip + fade so users with the
   pref see an instant text swap (still readable, no jank). */
@media (prefers-reduced-motion: reduce) {
  .price, .price.is-flipping { transition: none; transform: none; filter: none; }
  .billed, .billed.is-fading { transition: none; transform: none; opacity: 1; }
  .toggle-switch::after { transition: none; }
}

.price-divider { height: 1px; background: var(--line); margin: 4px 0; }

.feature-list li {
  position: relative;
  padding-left: 28px;
  margin: 12px 0;
  color: var(--ink-3);
  font-size: 16px;
  line-height: 1.5;
}
.feature-list li::before {
  content: "✓";
  position: absolute; left: 0; top: 0;
  color: var(--purple);
  font-weight: 700;
  font-size: 15px;
}
.feature-list.x li::before { content: "✕"; color: var(--muted-2); }

/* Figma pricing cards use plain bullet dots in the text colour, not the
   purple checkmarks shown in the comparison table and feature tabs. */
.price-card .feature-list { display: flex; flex-direction: column; gap: 16px; }
.price-card .feature-list li { padding-left: 20px; margin: 0; font-size: 18px; line-height: 1.4; color: var(--ink); }
.price-card .feature-list li::before {
  content: "\2022";
  color: var(--ink);
  font-weight: 400;
  font-size: 18px;
  line-height: 1.5;
  top: 0;
}
.price-card.is-featured .feature-list li::before { color: #ededed; }

.feature-list.tight li { margin: 8px 0; }

/* Figma: the "Most popular" pill is a dark (near-black) capsule that floats
   in the gap above the featured card, not a purple tab overlapping its edge. */
.most-popular-pill {
  position: absolute;
  top: -46px; left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: #fff;
  padding: 10px 22px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  border: none;
  white-space: nowrap;
}

.includes-pill {
  display: inline-block;
  padding: 4px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-3);
}

.price-toggle {
  display: inline-flex; gap: 16px;
  align-items: center;
  margin: 0 auto;
}
.price-toggle .toggle-label {
  font-size: 14px;
  color: var(--muted);
  font-weight: 500;
}
.price-toggle .toggle-label.is-active { color: var(--ink); }

.toggle-switch {
  width: 48px; height: 26px;
  background: var(--ink);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  border: none;
}
.toggle-switch::after {
  content: "";
  position: absolute;
  top: 3px; left: 3px;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  transition: transform .15s ease;
}
.toggle-switch.is-annual::after { transform: translateX(22px); }

.price-toggle-wrap { display: flex; flex-direction: column; align-items: center; gap: 10px; margin-bottom: 48px; }
.price-toggle-note { font-size: 13px; color: var(--muted); }

.small-link {
  display: block;
  text-align: center;
  font-size: 13px;
  color: var(--muted);
}

/* Figma: below the home pricing summary, a centered link out to the full
   /pricing page ("See full pricing and feature breakdown →"). The PricingCards
   component renders it only when the billing toggle is hidden (home), so the
   pricing page itself doesn't repeat it. */
.price-fulllink-wrap {
  display: flex;
  justify-content: center;
  margin-top: 40px;
}
.price-fulllink {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1px;
  transition: color 0.2s ease;
}
.price-fulllink .arrow {
  flex: none;
  color: var(--purple);
  transition: transform 0.2s ease;
}
.price-fulllink:hover { color: var(--purple); }
.price-fulllink:hover .arrow { transform: translateX(4px); }
.price-fulllink:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 4px;
  border-radius: 4px;
}

/* ---------- FAQ ---------- */

.faq {
  max-width: 960px;
  margin: 0 auto;
}
/* Figma FAQ: borderless rows separated by a 2px purple rule, with a circular
   2px-purple-outlined toggle on the right holding a chevron that points down
   when collapsed and rotates 180deg (up) when the row is open. */
.faq details {
  border: none;
  border-bottom: 2px solid var(--purple);
  background: transparent;
  border-radius: 0;
  padding: 24px 0;
  margin-bottom: 0;
}
.faq summary {
  list-style: none;
  cursor: pointer;
  font-family: 'DM Sans', system-ui, sans-serif;
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: var(--cta-bg);
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px;
}
/* circular outlined toggle with a down-chevron (SVG) centred inside */
.faq summary::after {
  content: "";
  flex: none;
  width: 27px; height: 27px;
  border: 2px solid var(--purple);
  border-radius: 50%;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6' fill='none'%3E%3Cpath d='M1 1L5 5L9 1' stroke='%234f32c9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center no-repeat;
  transition: transform .2s ease;
}
.faq details[open] summary::after { transform: rotate(180deg); }
.faq summary::-webkit-details-marker { display: none; }
.faq summary:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 4px;
  border-radius: 4px;
}
.faq details p {
  margin-top: 8px;
  font-size: 16px;
  line-height: 1.3;
  color: rgba(29, 18, 50, 0.7);
}
@media (prefers-reduced-motion: reduce) {
  .faq summary::after { transition: none; }
}

/* ---------- CTA ---------- */

/* Figma CTA = an inset near-black rounded card (not a full-bleed band):
   #030209, 30px radius, centred Amethysta headline, purple + white-outline
   pill buttons. */
.cta-band {
  background: var(--cta-bg);
  color: #fff;
  text-align: center;
  /* Sits ABOVE the footer so its lower third overlaps the footer's
     lavender/blue background (Figma). Pairs with .site-footer's negative
     margin-top, which pulls the footer up behind this card. */
  position: relative;
  z-index: 1;
  max-width: 1220px;
  /* margin-bottom: 0 — the CTABand sits flush against the lavender
     footer band's top edge with no white gap. Top margin keeps its
     clamp so the band has breathing room above. */
  margin: clamp(40px, 6vw, 80px) auto 0;
  border-radius: var(--radius-l);
  box-shadow: 0 4px 10px 5px rgba(0, 0, 0, 0.12);
  /* Tighter vertical padding than the section default so the card reads as a
     compact panel, not a tall block (was 48-72px top/bottom). */
  padding: clamp(36px, 4.5vw, 52px) clamp(24px, 5vw, 64px);
}
.cta-band > .container { max-width: 860px; padding: 0; }
/* The headline is one line by design ("From dispersed data to investable
   conviction"). At the section h2 ceiling (48px) it measures ~935px and wraps
   inside the 860px container, so cap it smaller here: 40px = ~779px, one line
   with margin to spare. Still a clamp so it scales down (and wraps) on mobile. */
.cta-band h2 { color: #fff; margin-bottom: 16px; font-size: clamp(26px, 3vw, 40px); }
.cta-band p { color: rgba(255, 255, 255, 0.72); margin-bottom: 32px; font-size: 18px; }
/* Figma: primary = solid purple pill (white text); secondary = WHITE pill with
   a purple hairline border and purple label. Both sit on the dark card. */
.cta-band .btn-primary { background: var(--purple); color: #fff; border-color: var(--purple); }
.cta-band .btn-primary:hover { background: #5d3fe0; }
.cta-band .btn-secondary { background: #fff; border-color: var(--purple); color: var(--purple); }
.cta-band .btn-secondary:hover { background: var(--bg-soft); border-color: var(--purple); }
/* Figma gap between the two pills is 32px (button1 right 613.5 → button2 left 645.5). */
.cta-band .btn-row { display: inline-flex; gap: 32px; flex-wrap: wrap; justify-content: center; }

/* Figma: the closing CTA band sits close beneath the FAQ, not separated by a
   full FAQ bottom-padding PLUS the card's own top margin. Collapse just that
   one boundary. Scoped to the FAQ->CTA adjacency so other pages are unaffected
   and the card's bottom margin (its footer overlap) is preserved. */
section:has(.faq):has(+ .cta-band) { padding-bottom: clamp(20px, 2.5vw, 36px); }
section:has(.faq) + .cta-band { margin-top: clamp(6px, 1vw, 16px); }

/* ---------- Footer ---------- */

.site-footer {
  background-color: var(--bg-soft);
  /* Soft purple bloom upper-right + a gentle blue wash down the LEFT. The left
     wash gives the white blueprint grid (::before) something to contrast
     against — on the near-white lavender alone the white lines wash out. The
     blue ball (.footer-glow) supplies the deeper blue at the bottom-left. */
  background-image:
    radial-gradient(48% 60% at 90% 22%, rgba(79, 50, 201, 0.1), transparent 72%),
    radial-gradient(52% 72% at 2% 50%, rgba(60, 96, 224, 0.32), transparent 74%);
  background-repeat: no-repeat;
  /* Top padding absorbs the .cta-band overlap (~48-80px behind the
     card) plus visible breathing room before the wordmark. */
  padding: clamp(120px, 13vw, 160px) 0 48px;
  font-size: 16px;
}
/* Brand block + however many link columns the Footer global supplies.
   Flex (not grid) so the layout adapts to any column count without a
   reserved/collapsed empty track. */
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 40px 56px;
  margin-bottom: 32px;
}
/* Brand block grows to fill the left so the three link columns are pushed to
   the right half — matching the Figma footer layout. */
.footer-grid > :first-child { flex: 1 1 380px; }
.footer-col { flex: 0 1 auto; min-width: 150px; }
@media (max-width: 880px) {
  .footer-grid { gap: 32px 40px; }
  .footer-grid > :first-child { flex-basis: 100%; }
}

/* Footer brand = the wordmark (Figma), not a dark pill. */
/* Footer logo: the finapolis wordmark (no sparkle), sized 1:1 to the Figma. */
.footer-brand-mark {
  display: block;
  margin-bottom: 14px;
}
.footer-brand-mark img { width: 190px; height: auto; }
/* Punchline: serif, near-black (#151127), matching the Figma. */
.footer-brand-text {
  font-family: var(--font-serif);
  color: var(--ink);
  font-size: 20px;
}
.footer-social { display: inline-flex; gap: 10px; }
.footer-social a {
  width: 40px; height: 40px;
  display: inline-grid; place-items: center;
  background: var(--ink);
  color: #fff; font-size: 16px;
  border-radius: var(--radius-pill);
}
.footer-social a:hover { background: var(--purple); }

.footer-col h3 {
  font-size: 20px;
  color: var(--ink);
  margin-bottom: 20px;
  font-weight: 400;
  letter-spacing: -0.01em;
}
.footer-col ul li { margin: 12px 0; }
.footer-col ul a {
  color: var(--ink);
  font-size: 16px;
}
.footer-col ul a:hover { color: var(--purple); }

.footer-bottom {
  padding-top: 28px;
  color: var(--ink);
  font-size: 14px;
}
/* Figma bottom bar: social badges (left) + copyright (right) share one row;
   the dark 2px divider sits beneath the whole row, then the disclaimers. */
.footer-bottom-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-bottom: 24px;
  margin-bottom: 24px;
  border-bottom: 2px solid var(--ink);
}
.footer-bottom .row {
  margin: 0;
  text-align: right;
  color: var(--ink);
  font-size: 16px;
}
.footer-disclosure {
  color: var(--ink); font-size: 13px;
  line-height: 1.6; margin: 0;
}
.footer-disclosure strong { color: var(--ink); font-weight: 700; }

/* ---------- Tabs ---------- */

.tabs {
  display: flex; gap: 8px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 0;
  flex-wrap: wrap;
}
.tabs button {
  /* Figma uses natural-width tabs grouped on the LEFT (not stretched
     across the whole bar). Active tab differs only in color + underline,
     never in size or weight, so nothing jumps when switching. */
  padding: 14px 22px;
  font-weight: 500;
  font-size: 15px;
  line-height: 1.2;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: transparent;
}
.tabs button.is-active {
  color: var(--ink);
  border-bottom-color: var(--ink);
  font-weight: 500;
  font-size: 15px;
}
.tabs.tabs-card { background: #fff; border: 1px solid var(--line); border-radius: var(--radius) var(--radius) 0 0; padding: 0 8px; }
.tabs-card + .tab-panel-wrap {
  border: 1px solid var(--line); border-top: none;
  border-radius: 0 0 var(--radius) var(--radius); padding: 36px;
  background: #fff;
  /* Lock the panel area so switching tabs NEVER reflows the page. The
     height is determined by the image column (aspect 1200/740) at the
     ~575 px column width inside a 1200 px container, plus 72 px of
     vertical padding. */
  min-height: 480px;
}
.tab-panel { display: none; }
.tab-panel.is-active { display: block; }
.tab-panel .split {
  /* Figma vertically-centers the text block against the screenshot, so
     the title sits at roughly the same Y as the middle of the image
     instead of clinging to the top of the panel. min-height is kept so
     switching tabs doesn't reflow. */
  align-items: center;
  min-height: 408px;
}
/* Match the Figma's image proportion — the screenshot reads slightly
   narrower than the text column, with a touch of breathing room on
   the inside edge so the panel doesn't feel front-loaded. */
.tab-panel .module-snap { max-width: 540px; margin-left: auto; }
/* Figma's tab-panel typography is tighter than the rest of the site —
   smaller h3, smaller body text, smaller bullets — so the text column
   reads as a clean compact pane next to the screenshot. */
.tab-panel .split > div:first-of-type > h3 {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.015em;
}
.tab-panel .split > div:first-of-type > h3 + p {
  font-size: 15px;
  line-height: 1.55;
  margin-top: 14px;
}
.tab-panel .feature-list li { font-size: 14px; line-height: 1.5; }
.tab-blurb { color: var(--muted); padding: 18px 8px 0; font-size: 14px; }

/* ===== Workflow tabview (ModuleTabs) — Figma "End-to-end research workflow" =====
   Open layout (no boxed card), purple active underline, filled-circle bullets. */
/* The workflow section sits in the WHITE gap between the two bloom bands, so it
   paints its own white background — the violet->white transition then lands at
   this section's top edge (where the companion section ends) instead of wherever
   band 1's fixed pixel height happens to fall. */
/* No overflow:hidden here: the corner decorations (blue ball + grid) deliberately
   bleed BELOW the section into the lavender band that follows. z-index:1 lifts the
   whole section above that band so the grid paints OVER the lavender, while the
   container's own z-index:1 keeps the decorations behind the workflow content.
   Horizontal bleed is contained by the page's `html, body { overflow-x: clip }`. */
.wf-section { position: relative; padding: clamp(56px, 8vw, 104px) 0; background: #ffffff; z-index: 1; }
.wf-section > .container { position: relative; z-index: 1; }
/* Figma "Ellipse 831" — soft blue bloom pooling into the lower-right, behind the
   content. Pure-CSS twin of the exported circle (#0081FF, 571px, 50% opacity, 90px
   Gaussian blur). Held clear of the section's bottom edge so the glow fades out
   inside the white section and never spills into the lavender band below. */
.wf-section::before {
  content: "";
  position: absolute;
  right: -120px;
  bottom: 96px;
  width: 571px;
  height: 571px;
  border-radius: 50%;
  background: #0081FF;
  background: color(display-p3 0.122 0.498 0.984);
  opacity: 0.5;
  filter: blur(90px);
  z-index: 0;
  pointer-events: none;
}
@media (max-width: 880px) { .wf-section::before { display: none; } }
/* Figma workflow lattice — the white node/connector grid plus its baked-in white
   bloom (the "Ellipse 822" 90px-blur circle that lives inside the asset). Reuses
   the existing hero-grid.svg (the same lattice motif as the hero + footer) instead
   of rebuilding the Figma vector dump. It deliberately spills past the section's
   bottom edge so the lattice carries DOWN over the lavender band below (the section's
   z-index:1 keeps it on top of that band); the white art only reads where it crosses
   the blue glow and the lavender, dissolving on the plain white. Pinned bottom-right
   and feathered so it fans up-and-left, exactly as the mock. */
.wf-section::after {
  content: "";
  position: absolute;
  z-index: 0;
  right: clamp(-160px, calc(-100 / 1440 * 100vw), -60px);
  bottom: clamp(-300px, calc(-230 / 1440 * 100vw), -150px);
  width: clamp(440px, calc(720 / 1440 * 100vw), 720px);
  height: clamp(560px, calc(900 / 1440 * 100vw), 900px);
  background: url("/images/hero-grid.svg") no-repeat right bottom;
  background-size: contain;
  opacity: 0.9;
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: radial-gradient(135% 135% at 90% 64%, #000 42%, transparent 90%);
  mask-image: radial-gradient(135% 135% at 90% 64%, #000 42%, transparent 90%);
}
@media (max-width: 880px) { .wf-section::after { display: none; } }
.wf-head { max-width: 560px; }
.wf-title {
  font-family: var(--font-serif);
  font-weight: 400;
  letter-spacing: -0.05em;
  line-height: 1.2;
  font-size: clamp(34px, 3.4vw, 48px);
  color: var(--ink);
  margin: 0 0 16px;
}
.wf-sub { color: var(--ink-3); font-size: 20px; line-height: 1.4; max-width: 478px; margin: 0; }

.wf-tabs {
  display: flex;
  gap: clamp(20px, 3vw, 36px);
  flex-wrap: wrap;
  margin: 40px 0 0;
}
.wf-tabs button {
  padding: 0 0 16px;
  background: transparent;
  border: 0;
  border-bottom: 3px solid transparent;
  color: var(--muted);
  font-family: var(--font-sans);
  font-size: 18px;
  font-weight: 500;
  line-height: 28px;
  cursor: pointer;
}
.wf-tabs button:hover { color: var(--ink); }
.wf-tabs button.is-active { color: var(--ink); border-bottom-color: var(--purple); }

/* All panels share ONE grid cell, so the panel area is always as tall as the
   TALLEST module. Switching tabs only toggles which panel is visible — the
   height never changes, so the tabs above AND the flow row / page below never
   shift on click (no layout jump; you can click through tabs without the next
   target moving). Inactive panels stay in layout to reserve that max height but
   are hidden from view + assistive tech via visibility:hidden. A shorter module
   just leaves empty space at the BOTTOM of the area — the top stays anchored. */
.wf-panels { display: grid; }
.wf-panel { grid-area: 1 / 1; visibility: hidden; }
.wf-panel.is-active { visibility: visible; }
.wf-split {
  display: grid;
  /* Narrower text column + tighter gap give the demo visual more width (Leo:
     "make the demo bigger"). */
  grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: clamp(28px, 3vw, 44px);
  /* Top-align the demo with the heading (Leo: video top on the heading's top
     line), not vertically centered against the text column. */
  align-items: start;
  padding-top: clamp(36px, 4vw, 56px);
  min-height: 430px;
}

/* Figma "text-3xl/leading-normal/medium": DM Sans 500, 30px, 120%, #161129,
   no letter-spacing. (Was 600/semibold with -0.02em tracking.) */
.wf-text h3 {
  font-family: var(--font-sans);
  font-size: 30px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: normal;
  color: var(--ink);
  margin: 0;
}
/* Figma "text-xl 20/leading-normal/normal": DM Sans 400, 20px, 28px line-height,
   #161129 (full dark, same as the heading — not the softened --ink-3). */
.wf-text > p { color: var(--ink); font-weight: 400; font-size: 20px; line-height: 1.4; margin: 16px 0 0; }

.wf-checks { list-style: none; margin: 40px 0 0; padding: 0; display: flex; flex-direction: column; gap: 20px; }
.wf-checks li {
  position: relative;
  padding-left: 44px;
  color: var(--ink);
  font-size: 20px;
  line-height: 1.4;
}
.wf-checks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--purple)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14'%3E%3Cpath d='M3.5 7.5 6 10 10.5 4.5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")
    center / 14px 14px no-repeat;
}

.wf-visual {
  position: relative;
  /* Bleed the demo to the right past the container gutter so its right edge
     reaches where the page margin starts (Leo). Height follows automatically
     via the .module-visual / .wf-card-empty aspect-ratio. Reset on mobile. */
  margin-right: calc(-1 * var(--gutter));
}
.wf-visual .module-visual,
.wf-card-empty {
  width: 100%;
  max-width: none;
  margin-left: auto;
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: #fff;
  box-shadow: var(--shadow);
}
.wf-card-empty { aspect-ratio: 1100 / 678; }

.wf-flow { margin-top: clamp(40px, 5vw, 64px); }
.wf-flow-label {
  font-family: var(--font-sans);
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 14px;
}
/* Figma context-flow row: DM Sans 400, 20px. Module names sit on --ink-2 at 70%
   opacity; the first ("Screener") is full-strength --ink, same weight (NOT bold).
   Arrows are a filled chevron icon in --purple — the first hop solid, the rest at
   25% opacity. Column gap tracks Figma's ~40px spacing (2.78vw at 1440 design). */
.wf-flow-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px clamp(20px, 2.78vw, 40px);
  font-size: 20px;
  font-weight: 400;
  color: var(--ink-2);
  margin: 0;
}
.wf-flow-steps > span { color: var(--ink-2); opacity: 0.7; }
.wf-flow-steps > span.is-active { color: var(--ink); opacity: 1; }
.wf-flow-steps .wf-arrow { width: 12.7px; height: 14px; flex: none; color: var(--purple); opacity: 0.25; }
.wf-flow-steps .wf-arrow.is-active { opacity: 1; }

@media (max-width: 900px) {
  .wf-split { grid-template-columns: 1fr; gap: 28px; min-height: 0; }
  .wf-visual { margin-right: 0; }
  .wf-visual .module-visual, .wf-card-empty { max-width: none; }
}

/* The white section that follows the pill tab row needs proper breathing
   room above the "Step-by-step..." subtitle and the article cards.
   Without this, the content sits crammed up against the tabs. */
.resources-tabs-section .tab-blurb {
  margin-top: 56px;
  padding-top: 0;
  font-family: var(--resources-tab-blurb-font-family);
  font-size: var(--resources-tab-blurb-font-size);
  font-weight: var(--resources-tab-blurb-font-weight);
  line-height: var(--resources-tab-blurb-line-height);
  color: var(--ink-2);
  /* Preserve manual \n line breaks from the seed blurb. The Platform
     Guides blurb intentionally breaks after "for" so the subtitle
     reads as two balanced lines per Figma. */
  white-space: pre-line;
}
.resources-tabs-section .grid {
  margin-top: 48px;
}
.resources-tabs-section {
  padding-bottom: 32px;
}

/* Resources tabs section — the pill row STRADDLES the boundary between
   the lavender hero band above and the white articles section below.
   The section paints an opaque white background so the body's page-
   level lavender wash (bg-wash.svg + #F4F2FE base color) is hidden.
   Top padding leaves room for the pill row, which is absolutely
   positioned and pulled UP so 30px of it overflows into the hero. */
.resources-tabs-section {
  position: relative;
  z-index: 2;          /* sit above both the hero and the next section */
  background: #ffffff;
  /* Reserve vertical space for the straddling pill row (52px pill
     height minus the 30px that overflows into the hero = 22px sits
     inside the section, plus 40px breathing room below). */
  padding-top: 62px;
}

/* All sections following the resources-tabs-section on the resources
   page also paint white, so the body's page-wide lavender wash
   doesn't bleed through. Without this rule, ArticleGrid (Featured),
   CardGrid (Guides Tailored to Your Role), and Newsletter would all
   show the lavender background between them. The "~ section" combinator
   picks up every subsequent section sibling of resources-tabs-section. */
/* Resources page is fully white — no lavender body wash, no bg-wash
   bloom SVGs. Override the body-level background (Asha's #F4F2FE +
   bg-wash + bg-wash-mid) on pages that contain the resources tabs.
   The hero band keeps its own lavender via .hero-centered-decor. */
body:has(.resources-tabs-section) {
  background-color: #ffffff;
  background-image: none;
}

/* Contact page is fully white — same as Resources. Override the
   body-level background (Asha's #F4F2FE + bg-wash + bg-wash-mid).
   The ContactHero section keeps its OWN lavender via the
   .contact-hero-section background-color. Everything below it
   (General Inquiry, form, footer text, CTABand) sits on white. */
body:has(.contact-hero-section) {
  background-color: #ffffff;
  background-image: none;
}

/* All Resources-page sections after the pill tabs paint white so any
   residual body bleed-through is covered (belt + suspenders, also
   sets a stacking context for the per-section dividers).
   The CTABand is excluded — it IS its own dark rounded card section
   (not a container with a card inside), so its background MUST stay
   var(--cta-bg). The white wrapper around the CTABand comes from
   sibling sections / the body:has() override above. */
.resources-tabs-section ~ section:not(.cta-band) {
  position: relative;
  background: #ffffff;
}

/* Match the hero/tabs container exactly: capped at 1440 and centered
   so the article grid contents sit on the same left column as the
   hero headline + pill row above. The 83px extra left padding aligns
   content with the "R" of the Resources headline. */
.resources-tabs-section ~ section:not(.cta-band) > .container {
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: calc(clamp(24px, 3.5vw, 50px) + 83px);
  padding-right: clamp(24px, 3.5vw, 50px);
}

/* Horizontal divider between successive resources-page sections.
   Per Figma SVG spec: 1161 wide × 2 tall, color #1B1230 (--ink-2).
   Width matches the card row above so the line spans exactly under
   the three 371px cards + their 24px gaps. The first article grid
   doesn't get a top divider (it's the first card row, already
   separated from the pills by the tab row + blurb). */
.resources-tabs-section ~ section:not(.cta-band) ~ section:not(.cta-band) > .container {
  padding-top: 32px;
  position: relative;
}
.resources-tabs-section ~ section:not(.cta-band) ~ section:not(.cta-band) > .container::before {
  content: "";
  display: block;
  width: 1161px;
  max-width: 100%;
  height: 2px;
  background: var(--ink-2);
  margin-bottom: 32px;
}
/* Tighten the vertical gap so the cards above don't leave a huge
   empty band between the last card row and the divider. */
.resources-tabs-section ~ section:not(.cta-band) {
  padding-top: 32px;
  padding-bottom: 32px;
}

/* "Load more articles" CTA at the bottom of an ArticleGrid — rendered
   as a dark pill button centered under the card row. The .center
   utility (existing site-wide) plus generous top spacing gives the
   button its breathing room. */
.article-grid-cta {
  text-align: center;
  margin: 48px 0 0;
}

/* Suppress the divider on any section that immediately follows a
   section containing a Load-more CTA. The "Load more articles" pill
   IS the visual separator for that pair (per Figma), so no horizontal
   line is needed between it and the next section. */
.resources-tabs-section ~ section:has(.article-grid-cta) + section > .container::before {
  display: none;
}

/* Also suppress the divider on the Newsletter section. Per Figma the
   newsletter signup sits flush with the CardGrid above it, no line
   between them. Targets the section that contains a .newsletter form. */
.resources-tabs-section ~ section:has(.newsletter) > .container::before {
  display: none;
}

/* Suppress the divider above the "Guides Tailored to Your Role"
   CardGrid section. The CardGrid is the only block on the Resources
   page that renders .card elements (ArticleGrid uses .resource-card,
   CTABand has no .card). Per Figma the section above (All Platform
   Guides + its Load-more CTA pill) flows directly into Guides
   Tailored with no separator line. */
.resources-tabs-section ~ section:has(> .container > .grid > .card) > .container::before {
  display: none;
}

/* ---------- Resources-page-only card sizing ----------
   Per Figma: three 371×566 cards in a row with 24px gaps =
   3 × 371 + 2 × 24 = 1161px total row width at the 1440 design
   width. We lock the row to 1161px max and the cards to 371×566
   exact — they don't stretch to fill the wider container.
   Cards keep their Figma proportions; the row sits left-aligned
   inside the section's 83px-indented column (same as the headline). */
.resources-tabs-section ~ section .grid.grid-3 {
  grid-template-columns: repeat(3, 371px);
  gap: 24px;
  max-width: 1161px;
  margin-left: 0;
  margin-right: auto;
}
/* Article cards: 371 × 566 (the taller ArticleGrid card with image
   area + text). CardGrid tiles: 371 × 510 (shorter, text-only). Per
   Figma — two different card types share width but differ in height. */
.resources-tabs-section ~ section .grid.grid-3 > .resource-card {
  width: 371px;
  height: 566px;
  aspect-ratio: auto;
}
.resources-tabs-section ~ section .grid.grid-3 > .card {
  width: 371px;
  height: 510px;
  aspect-ratio: auto;
  /* Per Figma: pale grey fill, 30px radius, no border, generous padding
     for the icon + title + body stack. */
  background: #F6F6F9;
  border: none;
  border-radius: 30px;
  box-shadow: none;
  padding: 32px;
}
/* Card icon — Figma shows the icon at upper-left of the card with
   margin below it before the title. Override the default .feature-icon
   to a transparent backdrop so the SVG glyph reads on the pale grey
   card without an extra dark tile. */
.resources-tabs-section ~ section .grid.grid-3 > .card .feature-icon {
  background: transparent;
  width: auto;
  height: auto;
  margin: 0 0 24px;
  padding: 0;
  color: var(--ink-2);
  font-size: 36px;
}

/* Resources-page CardGrid bullets — 24×24 purple filled circle with a
   white checkmark, per Figma SVG spec. Overrides the global
   .feature-list bullet ("✓" text glyph in purple) only inside the
   resources article range, so pricing-page feature lists keep their
   text-checkmark style. */
.resources-tabs-section ~ section .feature-list li {
  padding-left: 36px;
}
.resources-tabs-section ~ section .feature-list li::before {
  content: "";
  width: 24px;
  height: 24px;
  background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none'><circle cx='12' cy='12' r='12' fill='%234B33C1'/><path d='M7.20056 11.9999L10.4536 15.036C10.6481 15.2176 10.9506 15.215 11.142 15.0302L17.7606 8.63989' stroke='white' stroke-width='2' stroke-linecap='round'/></svg>") no-repeat center / contain;
  /* Reset the text glyph the global rule sets so neither shows. */
  color: transparent;
  font-size: 0;
  top: 2px;
}

/* Resources-page cards drop the dark backdrop the base ResourceCard
   uses elsewhere. The image area paints against a light card frame
   and the dark border is removed — per Figma the resources cards
   are floating tiles, not dark-backed module showcases like the
   home page's "Learn from the best". */
.resources-tabs-section ~ section .resource-card {
  background: #ffffff;
  border-color: transparent;
}
/* Match the hero container exactly (1440 cap, centered) so the section
   uses the same frame width as the hero. */
.resources-tabs-section > .container {
  position: relative;
  z-index: 1;
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(24px, 3.5vw, 50px);
  padding-right: clamp(24px, 3.5vw, 50px);
}
/* The pill row + the "Step-by-step..." blurb sit under the "Resources"
   headline, so they get the same 83px indent that aligns the H1 with
   the "f" in the logo above. The article grid below does NOT get the
   indent — it spans the full 1440 frame edge-to-edge so the left card
   aligns with the hero's left edge and the right card aligns with the
   header's CTA on the right. */
.resources-tabs-section .resources-tabs,
.resources-tabs-section .tab-blurb {
  margin-left: 83px;
}

/* ---------- Resources page tabs (pill style with icon) ----------
   Per Figma — three pill buttons left-aligned under the "Resources"
   headline. The pill row sits ON the boundary between the hero band
   (lavender) and the section below (white) — 30px of the pill height
   overflows up into the hero, the rest sits on the white section.
   transform: translateY shifts the row visually without changing
   layout flow (so it doesn't drag the section up via margin collapse,
   the bug we hit with margin-top: -30px earlier). */
.resources-tabs {
  display: flex;
  justify-content: flex-start;
  gap: 16px;
  flex-wrap: wrap;
  padding: 0;
  transform: translateY(-30px);
}
.resources-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;       /* center icon + label as a group inside the pill */
  gap: 16px;
  /* Figma exact dimensions: each pill is 52px tall; widths vary by
     label (Platform Guides 266, Market Commentary 304, Education 216)
     and are set per-pill below via :nth-child. */
  height: 52px;
  padding: 0 24px;
  border-radius: 26px;           /* fully rounded at 52px height */
  /* Pill typography is centralized in :root variables so the design
     system can tune label sizing in one place. */
  font-family: var(--pill-tab-font-family);
  font-size: var(--pill-tab-font-size);
  font-weight: var(--pill-tab-font-weight);
  line-height: var(--pill-tab-line-height);
  color: var(--ink-2);          /* #1B1230 */
  background: #ffffff;
  border: 1px solid var(--ink-2);
  cursor: pointer;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease, transform .04s ease;
  white-space: nowrap;
}
/* Per-Figma exact widths, in declared order:
     1st (Platform Guides)   266
     2nd (Market Commentary) 304
     3rd (Education)         216 */
.resources-tabs .resources-tab:nth-child(1) { width: 266px; }
.resources-tabs .resources-tab:nth-child(2) { width: 304px; }
.resources-tabs .resources-tab:nth-child(3) { width: 216px; }
.resources-tab:hover { background: var(--bg-soft); }
.resources-tab:active { transform: translateY(1px); }
.resources-tab.is-active {
  background: var(--ink-2);
  color: #ffffff;
  border-color: var(--ink-2);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.1),
    0 1px 3px rgba(0, 0, 0, 0.1);
}

/* The icon tile — 36x36 dark rounded square at every state.
   Per Figma, the tile background stays #1B1230 in both active and
   inactive states. On the inactive (white) pill it shows as a dark
   tile contrasting with white; on the active (dark) pill it visually
   blends with the pill, so the white glyph appears to float. */
.resources-tab-icon {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--ink-2);
  color: #ffffff;
  flex: none;
}
.resources-tab-icon svg { display: block; }
.resources-tab-label { display: inline-block; }

/* Static module screenshots inside each tab panel — fill the visual slot
   with the AVIF/JPG snapshot of the corresponding module's UI. */
.module-snap {
  display: block;
  width: 100%;
  aspect-ratio: 1200 / 740;
  border-radius: var(--radius);
  overflow: hidden;
  background: #d6dae0;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}
.module-snap img {
  display: block;
  width: 100%;
  height: 100%;
  /* `contain` lets each module shot show in full inside the locked
     1200/740 container even if its source aspect differs. Matching-
     aspect shots fill the box edge-to-edge; mismatched shots show a
     slim background band rather than getting their sides cropped. */
  object-fit: contain;
}
/* The Dashboard screenshot is wider/shorter than the others
   (1361×639 vs 1200×740). Stretch it to fully fill its container
   so there are no letterbox bands above or below. */
.tab-panel[data-tab-panel="home"] .module-snap img {
  object-fit: fill;
}

/* ---------- Resource cards ---------- */

/* Recreated 1:1 from the Figma export (a 371×566 frame). The card is a single
   link: a dark #030208 backdrop holds the cover image (371×276) with a dark
   book "save/read" badge top-right, then a white content panel that rises 40px
   over the image with 30px rounded top corners. Colours are the figma literals,
   each of which equals a design token (#1B1230 = --ink-2, #4B33C1 = --purple,
   #030208 ≈ --cta-bg); the box-shadow is var(--shadow) — already the exact pair
   of figma drop shadows. */
.resource-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: #030208;
  border: 1px solid rgba(27, 18, 48, 0.15);
  border-radius: var(--radius-l);            /* 30px */
  box-shadow: var(--shadow);
  overflow: hidden;
  text-decoration: none;
  color: var(--ink);
  /* Card dimensions are scoped to the resources page only (see the
     `.resources-tabs-section ~ section .resource-card` rule above).
     The base .resource-card here stays unsized so other pages
     (home "Learn from the best", etc.) keep their existing layout. */
}
.resource-card:hover { text-decoration: none; }

/* Image area — 371×276 in figma, cover-cropped. */
.resource-card .visual {
  position: relative;
  flex: 0 0 auto;
  height: 276px;
  min-height: 0;
  border: none;
  border-radius: 0;
  background: #030208;
  padding: 0;
  overflow: hidden;
}
.resource-card .visual img:not(.resource-card__icon) { width: 100%; height: 100%; object-fit: cover; }
.resource-card .visual > span { color: rgba(255, 255, 255, 0.55); font-size: 13px; }

/* Dark "save / read" book badge — 60×60, 21px radius, top-right, 24px inset. */
.resource-card__icon {
  position: absolute;
  top: 24px;
  right: 24px;
  width: 60px;
  height: 60px;
  z-index: 2;
  pointer-events: none;
}

/* White content panel — rises 40px over the image, rounded top corners. */
.resource-card .body {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  margin-top: -40px;
  background: #fff;
  border-radius: var(--radius-l) var(--radius-l) 0 0;
  padding: 28px 25px 32px;
  display: flex;
  flex-direction: column;
}

/* Date — #1B1230 @ 70%, 16px. */
.resource-card .card-date {
  display: block;
  font-size: 16px;
  line-height: 1.2;
  color: rgba(27, 18, 48, 0.7);
  margin: 0 0 12px;
}

/* Title — #030208, 24px / 26px, DM Sans medium (figma cap 17.1 ÷ 0.70). */
.resource-card h3 {
  font-size: 24px;
  line-height: 26px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: #030208;
  margin: 0 0 12px;
}

/* Byline (category / desk) — solid #1B1230, 16px / 500. Resets the old pill. */
.resource-card .meta {
  display: block;
  align-self: auto;
  font-size: 16px;
  line-height: 1.2;
  font-weight: 500;
  color: #1b1230;
  letter-spacing: normal;
  text-transform: none;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0 0 18px;
}

/* Description — #1B1230 @ 70%, 16px / 21px, clamped to 3 lines. */
.resource-card p {
  font-size: 16px;
  line-height: 21px;
  color: rgba(27, 18, 48, 0.7);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Footer — Read → (dark text + purple arrow) left, "n min Read" (purple) right. */
.resource-card .footer-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 24px;
  font-size: inherit;
  color: inherit;
}
.resource-card .read-more {
  display: inline-flex;
  align-items: center;
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  color: #151127;
  margin: 0;
}
.resource-card .read-more__arrow { width: 52px; height: 16px; margin-left: 12px; flex: 0 0 auto; }
.resource-card .read-time {
  font-size: 20px;
  font-weight: 500;
  line-height: 1;
  color: #4b33c1;
  white-space: nowrap;
}

/* ---------- Resources showcase: "Learn from the best" (homepage articleGrid) ----------
   Figma "Learn from the best": a left intro column (eyebrow + Amethysta H2 + DM Sans
   subtitle + dark pill CTA) beside a horizontally scrollable row of white guide cards
   (400×616, 30px radius, the exact --shadow drop pair). Each card is a dark line icon
   floating in a soft colour glow, then a title, a short description, and an underlined
   "Read guide" with a purple arrow. A circular purple-ringed button advances the row. */
.resource-showcase {
  padding: clamp(56px, 9vw, 110px) 0;
}
.resource-showcase-grid {
  display: grid;
  grid-template-columns: minmax(300px, 420px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px);
  /* Figma top-aligns the intro column: the "RESOURCES" eyebrow sits level with
     the top of the card row, not vertically centred against it. */
  align-items: start;
}
.resource-intro {
  max-width: 464px;
}
.resource-intro h2 {
  font-size: clamp(34px, 4vw, 48px);
  margin: 0 0 16px;
}
.resource-intro .eyebrow {
  color: var(--ink);
}
.resource-intro p {
  /* Figma subtitle: DM Sans 20px, #161129 (= --ink). Near-black on the lavender
     bloom-band clears WCAG AA comfortably. */
  color: var(--ink);
  font-size: 20px;
  line-height: 1.4;
  margin: 0 0 28px;
}
.resource-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 60px;
  padding: 16px 40px;
  background: var(--accent);          /* #161129 dark pill */
  color: var(--accent-ink);
  border-radius: 9999px;
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  text-decoration: none;
}
.resource-cta:hover {
  text-decoration: none;
  opacity: 0.92;
}
.resource-cta:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Carousel = a scroll-snap track of cards + a single circular "next" control. */
.guide-carousel {
  position: relative;
  min-width: 0;
}
.guide-track {
  display: flex;
  gap: 24px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Generous padding so the card's 65px-blur drop shadow renders IN FULL rather
     than being hard-clipped into a grey box by this scroll container (overflow-x
     auto forces overflow-y to clip too). The equal negative margins pull the
     track back so its visual footprint — content position AND height — is
     unchanged. Right stays tight so the edge-fade mask (below) still lines up
     with the peeking card. */
  padding: 60px 6px 72px 60px;
  margin: -52px 0 -44px -54px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Soft edge fade so the partially-visible "next" card fades out at the right
     (and the just-passed card fades at the left once scrolled). The mask sits
     on the visible box, so whichever card peeks past an edge fades; clicking
     "next" scrolls it into the solid middle = it "comes in". JS toggles
     [data-edge] by scroll position so the first/last card is never faded when
     there is nothing more that way. */
  --guide-fade: 110px;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--guide-fade)), transparent);
          mask-image: linear-gradient(to right, #000 calc(100% - var(--guide-fade)), transparent);
}
.guide-track[data-edge='none'] {
  -webkit-mask-image: none;
          mask-image: none;
}
.guide-track[data-edge='middle'] {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--guide-fade), #000 calc(100% - var(--guide-fade)), transparent);
          mask-image: linear-gradient(to right, transparent, #000 var(--guide-fade), #000 calc(100% - var(--guide-fade)), transparent);
}
.guide-track[data-edge='end'] {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--guide-fade));
          mask-image: linear-gradient(to right, transparent, #000 var(--guide-fade));
}
.guide-track::-webkit-scrollbar {
  display: none;
}

.guide-card {
  scroll-snap-align: start;
  flex: 0 0 auto;
  width: clamp(300px, 78vw, 400px);
  display: flex;
  flex-direction: column;
  gap: 34px;                          /* Figma media→body gap (Frame 1000005727) */
  background: #fff;
  border-radius: var(--radius-l);     /* 30px */
  /* Softer, horizontally-symmetric shadow instead of the shared --shadow token.
     --shadow has a +4px x-offset plus a tight second layer (4px 8px 10px -6px),
     which on these tall guide cards read as a hard band down the RIGHT edge. A
     single wide, centred (0 x-offset) shadow gives an even, smooth falloff on
     both sides — matching the Figma's soft card lift. */
  box-shadow: 0 20px 55px -14px rgba(0, 0, 0, 0.12);
  padding: 24px;
  text-decoration: none;
  color: var(--cta-bg);               /* #030209 */
}
.guide-card:hover {
  text-decoration: none;
}
.guide-card:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 3px;
}

/* Icon area — the white-book-on-near-black squircle badge (figma), centered
   over a soft, blurred colour glow. */
.guide-card__media {
  position: relative;
  height: 276px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 22px;
}
.guide-card__glow {
  position: absolute;
  width: 152px;
  height: 152px;
  border-radius: 50%;
  filter: blur(50px);
  pointer-events: none;
}
.guide-card__icon {
  position: relative;
  width: 110px;
  height: 110px;
  object-fit: contain;
}

.guide-card__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  flex: 1 1 auto;
  padding: 4px 8px 8px;
}
.guide-card__title {
  font-family: var(--font-sans);
  font-size: clamp(24px, 2.4vw, 30px);
  line-height: 1.2;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--cta-bg);
  margin: 0;
}
.guide-card__desc {
  font-size: 18px;
  line-height: 1.45;
  color: var(--cta-bg);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.guide-read {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: auto;
  padding-top: 8px;
  font-size: 20px;
  font-weight: 400;
  color: var(--cta-bg);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.guide-read__arrow {
  width: 52px;
  height: 16px;
  flex: 0 0 auto;
}
.guide-card:hover .guide-read {
  color: var(--purple);
}

/* Circular "next" — white fill, purple ring + purple chevron (figma 99px).
   Figma (Group 1000005681) places the control straddling the gutter between the
   first two cards, low in the artwork band near the media's bottom edge — NOT
   level with the icon and NOT pinned far-right over a title.
   Vertical: the Figma circle centre sits 268.5px below the card top (circle at
   top 378, card at top 159; 378 + 99/2 − 159). Cards begin 8px below the
   carousel top (track padding-top), so centre = 8 + 268.5 ≈ 276px.
   Horizontal: centred on the gutter between the first two cards. Measured: the
   bare "card width + half-gap" sits ~52px right of the true gutter (the carousel
   box starts left of the first card), so the value is pulled back 52px. The
   offset is constant across widths, so this holds at 1280 and 1440 alike. */
.guide-next {
  position: absolute;
  top: 276px;
  left: calc(clamp(300px, 78vw, 400px) - 40px);
  transform: translate(-50%, -50%);
  width: clamp(64px, 6vw, 88px);
  height: clamp(64px, 6vw, 88px);
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border: 2px solid var(--purple);
  border-radius: 50%;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  z-index: 2;
}
.guide-next svg {
  width: 38%;
  height: 38%;
}
.guide-next:hover {
  background: var(--purple);
}
.guide-next:hover svg path {
  stroke: #fff;
}
.guide-next:focus-visible {
  outline: 2px solid var(--purple);
  outline-offset: 3px;
}

@media (max-width: 900px) {
  .resource-showcase-grid {
    grid-template-columns: 1fr;
    gap: 28px;
    align-items: start;
  }
  .resource-intro {
    max-width: none;
  }
  .guide-carousel {
    display: flex;
    flex-direction: column;
  }
  .guide-next {
    position: static;
    transform: none;
    margin: 4px auto 0;
  }
}

/* ---------- Pill / tag ---------- */

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 4px;
  background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.pill.light { background: var(--bg-soft); color: var(--ink); border: 1px solid var(--line); }

.pill-tag {
  display: inline-flex; align-items: center;
  padding: 4px 12px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-3);
}

/* ---------- Step rows ---------- */

.steps {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: start;
}
@media (max-width: 880px) { .steps { grid-template-columns: 1fr; } }

.step-card { display: flex; flex-direction: column; align-items: center; gap: 18px; text-align: center; }
.step-card .visual { width: 100%; min-height: 240px; }
.step-card .num {
  background: var(--ink);
  color: #fff;
  width: 28px; height: 28px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px;
  font-weight: 500;
  margin-top: -28px;
  position: relative;
  z-index: 2;
}
.step-card h4 { font-size: 18px; }
.step-card p { font-size: 14px; color: var(--muted); max-width: 36ch; }

.step-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  align-items: center;
}
@media (max-width: 880px) { .step-row { grid-template-columns: 1fr 1fr; } }
.step-tile {
  background: var(--bg-shape);
  border-radius: 8px;
  padding: 24px;
  text-align: center;
}
.step-tile .icon {
  width: 28px; height: 28px;
  margin: 0 auto 12px;
  display: grid; place-items: center;
  color: var(--ink); font-size: 18px;
}
.step-tile h4 { font-size: 14px; font-weight: 500; }

.workflow-strip {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 0; padding: 28px 0;
}
@media (max-width: 880px) { .workflow-strip { grid-template-columns: 1fr; } }
.workflow-strip .item { text-align: center; padding: 0 24px; }
.workflow-strip .item .check {
  width: 28px; height: 28px;
  border: 1px solid #fff;
  border-radius: 50%;
  margin: 0 auto 12px;
  color: #fff;
  display: grid; place-items: center;
}
.workflow-strip .item h4 { color: #fff; font-size: 16px; font-weight: 500; }

/* ---------- Article ---------- */

.article-hero {
  padding: 64px 0 40px;
}
.article-hero .container { max-width: 920px; }

/* ---------- Article hero BAND ----------
   New per-Figma article header — 1444 x 749 frame, current page
   background (lavender body wash shows through), decorated with a
   blue bloom on the left and the same white crosshair grid lattice
   used on the Resources page hero. Holds breadcrumb + category pill
   + title + byline.

   Fluid-scaling per CLAUDE.md formula:
     clamp(MIN, calc(FIGMA_PX / 1440 * 100vw), FIGMA_PX)
   At 1440 viewport: pixel-perfect to Figma. Below 1440: scales down
   gracefully. Above 1440: capped at Figma value (capped at 1444 by
   the body's max-width:1920, so the band never exceeds 1444 visible
   on a centered design). */
.article-hero-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  width: 100%;
  /* Auto-height: the band wraps its header so the hero image sits a CONSISTENT
     gap below the byline regardless of title length. Was a fixed 749px, which
     left a large empty gap under shorter headers (Leo). Visible gap =
     padding-bottom − the image's 60px overlap (≈57px). min-height keeps a floor
     so very short articles still have presence. */
  min-height: clamp(340px, calc(440 / 1440 * 100vw), 440px);
  /* Header anchored at Figma y=201 from the band top. */
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding-top: clamp(130px, calc(201 / 1440 * 100vw), 201px);
  padding-bottom: clamp(88px, calc(117 / 1440 * 100vw), 117px);
  margin: 0;
  /* Background is the Figma composite SVG (bg-wash-article.svg)
     mounted as an absolutely-positioned <img> inside the band —
     gives us the lavender base + 2 blue + 3 purple blooms as
     authored in Figma. No CSS background-color needed; the
     body:has() override below kills the sitewide lavender wash so
     only the band shows lavender. */
}

/* Figma background composite — covers the full band, sits behind
   all content (z-index 0 vs content's 1). */
.article-hero-band .article-hero-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
  user-select: none;
}
/* Article page = white body, lavender ONLY in the hero band above.
   Override the sitewide body lavender wash + bg-wash SVGs for any
   page that contains an article-hero-band (i.e., post pages). */
/* Article page = pure white everywhere EXCEPT the hero band. Kill
   the sitewide lavender wash on both <body> (Asha's #F4F2FE) and
   on the .page-frame wrapper (Asha's bg-wash.svg image), plus any
   inherited bloom decor. */
body:has(.article-hero-band),
body:has(.article-hero-band) .page-frame {
  background-color: #ffffff !important;
  background-image: none !important;
}
.article-hero-band-inner {
  /* Header content column. Centered horizontally in the page at the
     1440 design width, padded to match the Figma 140 left offset
     (clamp(24, 3.5vw, 50) for narrower viewports + extra 90 to
     reach the Figma 140 mark on a 1440 frame). Per Figma Frame
     1000005689: left=140, top=201, width=1160 → inside a 1440 frame
     centered with auto margins, that's container-left + 140 padding. */
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1440px;
  margin-left: auto;
  margin-right: auto;
  padding-left: clamp(24px, 9.7vw, 140px);
  padding-right: clamp(24px, 9.7vw, 140px);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 20px;
}
/* Blue bloom — anchored to the LEFT side of the band, bleeding off
   the left edge. SVG is 763 wide with the ellipse center off-canvas
   left so the soft blur naturally fades into the page. */
/* (removed .article-hero-bloom — superseded by the composite
   .article-hero-bg SVG above, which contains all 5 Figma blooms.) */
/* Crosshair grid lattice — same dual-grid treatment as the Resources
   hero. Grid 1 (this img) is the original 749x1092 lattice anchored
   to the right of the 1440 frame. Grid 2 (the ::after pseudo-element
   below) is a horizontally mirrored copy positioned to the right of
   Grid 1 — off-screen at 1440 viewport, but on wider viewports the
   gap between Grid 1's right edge and the viewport right grows, and
   Grid 2 fills that gap with continued lattice pattern (no hard
   right-edge cut). */
.article-hero-grid {
  position: absolute;
  top: 66px;
  right: calc((100% - 1440px) / 2 + clamp(24px, 3.5vw, 50px) - 68px);
  left: auto;
  width: 749px;
  height: auto;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: radial-gradient(ellipse 110% 110% at 70% 30%, #000 45%, transparent 95%);
          mask-image: radial-gradient(ellipse 110% 110% at 70% 30%, #000 45%, transparent 95%);
}
/* Grid 2 — horizontally mirrored copy of hero-grid.svg, anchored
   to sit immediately to the right of Grid 1. On 1440 viewports it
   sits off-screen past the right edge; on wider viewports the
   widening gap brings Grid 2 into view, extending the lattice. */
.article-hero-band::after {
  content: "";
  position: absolute;
  top: 66px;
  left: auto;
  right: calc((100% - 1440px) / 2 + clamp(24px, 3.5vw, 50px) - 68px - 681px);
  width: 749px;
  height: 1092px;
  z-index: 0;
  pointer-events: none;
  background: url("/images/hero-grid.svg") left top / 749px 1092px no-repeat;
  transform: scaleX(-1);
  -webkit-mask-image: linear-gradient(to left, #000 0%, #000 70%, transparent 100%);
          mask-image: linear-gradient(to left, #000 0%, #000 70%, transparent 100%);
}
/* Mobile: drop both grid layers (too cramped to read). */
@media (max-width: 1024px) {
  .article-hero-grid { display: none; }
  .article-hero-band::after { display: none; }
}
/* The breadcrumb inside the band sheds its bottom border + tight
   padding so it sits cleanly above the title. */
.article-hero-band .breadcrumb {
  border-bottom: none;
  padding: 0;
  margin: 0 0 24px;
}
/* Title — per Figma "Headline 2 Serif" spec:
     Amethysta Regular 48, line-height 120% (= 57.6px),
     letter-spacing -0.05em, color #161129.
     max-width: 700 limits line length to ~4 words at this font/size
     so multi-word titles wrap to 3 lines (matching the Figma layout).
     min-height: 174 reserves the full 3-line height so the byline
     always lands at the same vertical position regardless of how
     many lines the actual title text needs. */
.article-hero-band h1 {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 400;
  font-size: 48px;
  line-height: 1.2;
  letter-spacing: -0.05em;
  color: #161129;
  /* Cap title width to ~700 to force ~4 words/line wrap (matches the
     Figma 3-line layout). Box sits flush-LEFT in the header column,
     text inside is left-aligned. */
  width: 700px;
  max-width: 100%;
  min-height: 174px;
  margin: 0;
  margin-right: auto;
  text-align: left;
  align-self: flex-start;
}
/* Inline hero image card — per Figma "Hero Image Placeholder" spec:
   1311 x 588 centered card, white background, 30 radius, shadow/xl.
   Positioned to overlap the bottom of the .article-hero-band (the
   Figma frame has `top: 689` inside a 749 hero, so the card sits
   60px from the band's top edge with its bottom extending past — we
   model this with a negative margin-top so the card visually sits
   over the hero band's lower portion).
   Fluid-scales per CLAUDE.md formula. */
.article-hero-image {
  display: block;
  width: clamp(1000px, calc(1311 / 1440 * 100vw), 1311px);
  height: clamp(450px, calc(588 / 1440 * 100vw), 588px);
  margin-left: auto;
  margin-right: auto;
  /* Per Figma — image card overlaps the bottom of the hero band by
     60px. With the header pinned to the bottom of the band via
     padding-bottom (see .article-hero-band rule), the byline always
     sits 57px above the image regardless of how many lines the
     title wraps to. */
  margin-top: -60px;
  position: relative;
  z-index: 2;
  background: #FFFFFF;
  border-radius: 30px;
  box-shadow: 4px 10px 65px -5px rgba(0, 0, 0, 0.1),
              4px 8px 10px -6px rgba(0, 0, 0, 0.1);
  overflow: hidden;
}
.article-hero-image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 30px;
}

/* Article hero band byline — per Figma "Container" spec:
     display: flex, row, align-items: flex-end, gap: 24px, padding: 0
     width: 762px, height: 43px
   Strips the legacy top/bottom borders that .article-byline used
   in the old article template. The new Figma hero band has a single
   bold divider ABOVE the byline (the .article-hero-divider rule
   below) and nothing below. */
/* Byline — matches the Figma: a 40px avatar (vertically centered) + a text
   block where the NAME sits on top and the role + date + read-time share ONE
   evenly-spaced row below. Putting them on one row makes the spacing neat
   regardless of how wide the name is (the old layout floated the date after the
   wide name, leaving a big gap after a short role). */
.article-hero-band .article-byline {
  border-top: none;
  border-bottom: none;
  padding: 0;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  gap: 12px; /* avatar -> text block */
  flex-wrap: nowrap;
  /* Span the content column (matches the divider above) so the Share button,
     pushed right with margin-left:auto, lands under the divider's right edge. */
  width: 100%;
  max-width: 1160px;
}
.article-hero-band .article-byline > .avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  object-fit: cover;
  background: #d8d8dc;
  flex: none;
}
.article-hero-band .byline-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* All byline type is DM Sans 16px; name is full-ink #1B1230, the row items are
   #1B1230 at 0.7 opacity. Scoped to the hero so other bylines stay smaller. */
.article-hero-band .byline-name {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.3;
  color: #1b1230;
}
.article-hero-band .byline-row {
  display: flex;
  align-items: baseline;
  gap: 32px;
}
.article-hero-band .byline-row > * {
  font-size: 16px;
  line-height: 1.3;
  color: rgba(27, 18, 48, 0.7);
}
/* Share button (Figma: purple pill, share icon + "Share", right-aligned). */
.article-hero-band .article-share-btn {
  margin-left: auto; /* push to the far right of the byline */
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  /* Figma: 127 x 41 fully-rounded pill. Fixed height + generous side padding
     reproduce the pill; var(--purple) is the brand purple (same design-intent
     colour as the Figma's #4B33C1, kept for consistency with other buttons). */
  height: 41px;
  padding: 0 28px;
  border: 0;
  border-radius: 9999px;
  background: var(--purple);
  color: #fff;
  font-family: var(--font-dm-sans);
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.article-hero-band .article-share-btn:hover { background: #5d3fe0; }
.article-hero-band .article-share-btn svg {
  width: 16px;
  height: 16px;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
@media (max-width: 600px) {
  /* On narrow screens the byline wraps; keep Share from overflowing. */
  .article-hero-band .article-share-btn { margin-left: 0; }
}

/* Article subtitle / deck — per Figma spec DM Sans Regular 20.
   Sits between the title and the divider, left-aligned with the
   title. Width capped at ~380px to force ~4 words per line wrap
   (matches the title's 4-words/line treatment). */
.article-hero-band .article-hero-subtitle {
  font-family: var(--font-dm-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: var(--ink-3, rgba(27, 18, 48, 0.7));
  margin: 0;
  width: 380px;
  max-width: 100%;
  text-align: left;
}

/* Horizontal divider between title block and byline in the hero
   band — per Figma a thin gray rule spanning the 1160 content
   column. Sits 48px below the title and 24px above the byline. */
.article-hero-divider {
  display: block;
  /* Inner spacing is owned by the parent flex gap (20px between
     every header item per Figma), so zero margin here. */
  margin: 0;
  width: 100%;
  max-width: 1160px;
  /* Match the Resources page divider — 2px tall, solid var(--ink-2)
     (#1d1232) rather than a low-opacity gray. */
  height: 2px;
  border: 0;
  background: var(--ink-2);
}

/* Category badge inside the article hero band — per Figma "Badge"
   spec: 148 width, 20 height, padding 2/8, dark pill (#161129),
   white DM Sans text, fully rounded. The text is centered INSIDE
   the pill, but the pill itself is left-aligned in the header
   column (sits at the same x position as the title below). */
.article-hero-band .pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 148px;
  width: fit-content;
  height: 20px;
  padding: 2px 8px;
  background: #161129;
  color: #ffffff;
  border-radius: 9999px;
  font-family: var(--font-dm-sans);
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  box-sizing: border-box;
}
.article-meta {
  display: flex; gap: 16px; align-items: center;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.article-meta .pill { font-size: 11px; }
.breadcrumb {
  font-size: 13px; color: var(--muted);
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
  margin-bottom: 32px;
}
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--ink); }
.breadcrumb .current { color: var(--ink-3); }

.article-author {
  display: flex; gap: 12px; align-items: center;
}
.article-author .avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: #d8d8dc;
  /* When rendered as <img>, fill the 40x40 circle with a cover crop
     so any aspect ratio (square is ideal, but non-square images
     still look ok). */
  object-fit: cover;
  flex: none;
}
.article-author strong { font-size: 14px; }
.article-author small { color: var(--muted); display: block; font-size: 13px; }

.article-byline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 24px 0;
}
.article-byline .meta-bits {
  color: var(--muted); font-size: 14px;
  display: flex; gap: 24px;
  align-items: center;
}
.article-share { font-size: 14px; color: var(--ink-3); display: inline-flex; gap: 8px; align-items: center; }

.article-layout {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 56px;
  align-items: flex-start;
  max-width: 1080px;
  margin: 0 auto;
}
@media (max-width: 980px) { .article-layout { grid-template-columns: 1fr; } }

.article-body { padding-top: 0; }
.article-body p {
  /* Figma article body: DM Sans 400, 16px, 130% line-height, #161129 (--ink).
     40px gap between blocks (margin-bottom only avoids margin collapse). */
  margin: 0 0 40px;
  color: var(--ink);
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 16px;
  line-height: 1.3;
}
.article-body p:last-child { margin-bottom: 0; }

/* Topics section — 40px gap above (matches body paragraph rhythm).
   The body's last <p> has margin-bottom: 0 (see .article-body
   p:last-child rule above), so this margin-top owns the gap.
   Padding: 0 to override the global `section { padding: clamp(56px,
   8vw, 110px) 0 }` rule — without this, this inner <section> picks
   up 56–110px of vertical padding and the gap balloons. */
.post-topics {
  margin-top: 40px;
  padding: 0;
}
.post-topics-title {
  font-family: var(--font-dm-sans);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink, #1B1230);
  margin: 0 0 16px;
}
/* Tag row inside .post-topics — zero its own vertical margin so the
   only vertical spacing comes from the title's margin-bottom above
   and the .post-helpful margin-top below. Without this, .tag-row's
   default `margin: 14px 0` adds 14px above+below, distorting the
   intended 40px gap to .post-helpful. */
.post-topics .tag-row {
  margin: 0;
}
/* Topics chips — per Figma "Button" spec: lavender bg #F4F2FE,
   purple text #4B33C1, fully rounded, 74x32 baseline pill. */
.post-topics .pill-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  background: #F4F2FE !important;
  border: none !important;
  border-radius: 9999px;
  font-family: var(--font-dm-sans);
  font-size: 13px;
  font-weight: 500;
  color: #4B33C1 !important;
}

/* "Was this article helpful?" — Yes/No prompt below Topics. The
   Topics tag-row above closes the section with no margin-bottom,
   so add 40px margin-top here to match the body's paragraph rhythm.
   Padding: 0 — same reason as .post-topics: kill the global
   `section { padding: clamp(56px, 8vw, 110px) 0 }` so the only
   vertical gap is this 40px margin-top. */
.post-helpful {
  margin-top: 40px;
  padding: 0;
}
.post-helpful-title {
  font-family: var(--font-dm-sans);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink, #1B1230);
  margin: 0 0 16px;
}
.post-helpful-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
/* Yes/No buttons — per Figma "Button" spec:
     width: 74, height: 32, padding 8/10, gap 6
     background: #F4F2FE, border-radius: 9999 (fully rounded)
     purple text #4B33C1
   Same visual treatment as the Topics chips above. */
.post-helpful-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 74px;
  height: 32px;
  padding: 8px 10px;
  background: #F4F2FE;
  color: #4B33C1;
  border: none;
  border-radius: 9999px;
  font-family: var(--font-dm-sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 120ms ease-out;
}
.post-helpful-btn:hover {
  background: #4B33C1;
  color: #ffffff;
}
.post-helpful-btn:focus-visible {
  outline: 2px solid #4B33C1;
  outline-offset: 2px;
}
.post-helpful-thanks {
  font-family: var(--font-dm-sans);
  font-size: 16px;
  color: var(--ink-3, rgba(27, 18, 48, 0.7));
  margin: 0;
}
.post-helpful-error {
  margin-top: 8px;
  font-family: var(--font-dm-sans);
  font-size: 14px;
  color: var(--ink-3, rgba(27, 18, 48, 0.5));
}

/* Related Articles section — sits below the article body + Topics +
   Helpful prompt. Renders the post's relatedPosts as 3 cards using
   the same ResourceCard component the Resources page uses. */
.post-related {
  padding: 48px 0 16px;
}
.post-related-title {
  font-family: var(--font-serif);
  font-size: 36px;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--ink, #1B1230);
  margin: 0 0 32px;
  text-align: left;
}
/* Align the heading + card row to the SAME span as the article body+TOC
   above (792 + 56 gap + 272 = 1120px), centred in the container exactly like
   .post-layout — so the heading and cards left-align with the article body and
   the row never overflows the content edge. (The old fixed 3×371 = 1161px row
   was wider than the 1120px content span and spilled past the right margin.) */
.post-related-title,
.post-related-grid {
  /* 1120px CENTRED over the container content via a negative-margin calc — the
     same visual span .post-layout produces (its 1120px grid overflows the
     gutter, putting the body at 160px). Plain `margin:auto` can't do this:
     CSS zeroes auto margins once the element is wider than its container, which
     left-aligns it and eats the right gutter. The calc keeps it symmetric so
     the heading + cards line up with the article body above. Reset on <=1200. */
  width: 1120px;
  margin-left: calc((100% - 1120px) / 2);
  margin-right: calc((100% - 1120px) / 2);
}
.post-related-grid {
  /* Three fluid columns filling the 1120px span (~357px each) instead of a
     fixed 371px that overflowed the content. */
  grid-template-columns: repeat(3, 1fr);
}
/* Borderless cards in Related Articles — per Figma, the article-page
   "Related" row uses cards with NO outer border (the default
   .resource-card has a 1px ink-tinted border for the Resources page
   grid). */
.post-related-grid > .resource-card {
  border: none;
}
.post-related-grid > .resource-card {
  width: 100%;
}
@media (max-width: 1200px) {
  .post-related-title,
  .post-related-grid {
    width: auto;
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
  }
  .post-related-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .post-related-grid > .resource-card { width: 100%; }
}
@media (max-width: 700px) {
  .post-related-grid {
    grid-template-columns: 1fr;
  }
}

/* CTABand → footer flush — handled sitewide via the base
   `.cta-band { margin: ... auto 0 }` rule (bottom margin zeroed).
   No article-page-specific override needed here anymore. */
.article-body h2 {
  /* Figma section heading: DM Sans 500, 30px, 120%, #1D1232 (override global serif h2). */
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.2;
  letter-spacing: normal;
  color: #1D1232;
  margin: 40px 0 16px;
}
.article-body h3 {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: 20px;
  line-height: 1.3;
  letter-spacing: normal;
  color: #1D1232;
  margin: 28px 0 12px;
}
.article-body figure { margin: 28px 0; }
.article-body figcaption { font-size: 13px; color: var(--muted); margin-top: 10px; font-style: italic; }
.article-body .visual.tall { min-height: 400px; }

.article-sidebar {
  position: sticky; top: 100px;
}
.article-sidebar h5 {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-bottom: 14px;
  font-weight: 500;
}
.toc a {
  display: block;
  padding: 6px 0;
  font-size: 14px;
  color: var(--ink-3);
  line-height: 1.4;
}
.toc a:hover { color: var(--ink); text-decoration: none; }
.toc a.is-active { color: var(--ink); font-weight: 500; }

.callout {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin: 28px 0;
}
.callout h4 { font-size: 15px; margin-bottom: 8px; display: flex; gap: 8px; align-items: center; }
.callout p { font-size: 15px; margin: 0; }

/* Article pull-quote (Figma): 4px purple left bar + purple serif text. Built-in
   Lexical blockquote, styled here for the article body. Overrides Tailwind
   prose's :where() blockquote (0-specificity) easily. */
.article-body blockquote {
  margin: 40px 0;
  padding: 0 0 0 16px;
  border-left: 4px solid var(--purple);
  color: var(--purple);
  font-family: var(--font-serif);
  font-weight: 400;
  font-style: normal;
  font-size: 24px;
  line-height: 1.4;
  letter-spacing: -0.5px;
  quotes: none;
}
.article-body blockquote p { margin: 0 0 8px; color: inherit; font: inherit; }
.article-body blockquote p:last-child { margin-bottom: 0; }
.article-body blockquote p::before,
.article-body blockquote p::after { content: none; }

/* "Platform Tip" callout (Figma): lavender box, purple border, lightbulb +
   bold label + body. Used as the `tip` inline block in posts content. */
.tip-callout {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 16px;
  padding: 24px;
  background: #F4F2FE;
  border: 1px solid var(--purple);
  border-radius: 16px;
  margin: 40px 0;
  color: var(--ink);
}
.tip-callout-icon { width: 24px; height: 24px; flex: none; color: var(--purple); }
.tip-callout-content { display: flex; flex-direction: column; min-width: 0; }
.tip-callout-label { font-family: var(--font-sans); font-weight: 500; font-size: 18px; line-height: 28px; color: var(--ink); }
.tip-callout p { margin: 0; font-family: var(--font-sans); font-weight: 400; font-size: 16px; line-height: 1.3; color: var(--ink); }

.continue-card {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 22px;
  margin-top: 28px;
}
.continue-card .label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-bottom: 8px;
  display: block;
}
.continue-card h4 { font-size: 15px; line-height: 1.4; margin-bottom: 8px; }
.continue-card .meta { font-size: 13px; color: var(--muted); }

.tag-row {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin: 14px 0;
}
.tag-row .pill-tag { background: #fff; }

.helpful-row {
  display: flex; gap: 12px; align-items: center;
  margin-top: 32px;
}
.helpful-row .label { font-size: 14px; color: var(--ink-3); }
.btn-yn {
  padding: 6px 18px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink-3);
  font-size: 14px;
  border-radius: var(--radius-s);
}
.btn-yn:hover { border-color: var(--ink); }

/* ---------- Audience cards ---------- */

.audience-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 880px) { .audience-cards { grid-template-columns: 1fr; } }
.audience-card { padding: 32px; border: 1px solid var(--line); border-radius: var(--radius); background: #fff; display: flex; flex-direction: column; gap: 16px; }
.audience-card .badge {
  display: inline-block; font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; padding: 6px 12px;
  background: var(--ink); color: #fff;
  border-radius: 4px; font-weight: 500;
  align-self: flex-start;
}
.audience-card h4 { font-size: 17px; }
.audience-card p { font-size: 14px; line-height: 1.5; color: var(--ink-3); flex: 1; }
.audience-link {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 4px;
  font-size: 14px; font-weight: 500;
  color: var(--ink);
  text-decoration: none;
}
.audience-link:hover { gap: 10px; text-decoration: underline; text-underline-offset: 3px; }

/* ---------- Compare 3 cards ---------- */

.compare-trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 880px) { .compare-trio { grid-template-columns: 1fr; } }
.compare-card {
  padding: 28px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-soft);
}
.compare-card.dark { background: var(--ink); border-color: var(--ink); color: #fff; }
.compare-card.dark h4 { color: #fff; }
.compare-card.dark .feature-list li { color: #ededed; }
.compare-card.dark .feature-list li::before { color: #fff; }
.compare-card .icon-square {
  width: 28px; height: 28px;
  background: #d8d8dc; border-radius: 4px;
  margin-bottom: 16px;
}
.compare-card.dark .icon-square { background: #fff; }
.compare-card h4 { margin-bottom: 14px; }

/* ---------- Stats ---------- */

.stat {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px;
  background: #fff;
}
.stat .num { font-size: 44px; font-weight: 600; letter-spacing: -0.03em; line-height: 1; margin-bottom: 12px; }
.stat .label-eyebrow {
  font-size: 11px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  margin-bottom: 8px;
}
.stat .label { color: var(--ink-3); font-size: 14px; line-height: 1.5; }

/* ---------- Forms ---------- */

.form-grid { display: grid; gap: 20px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 600px) { .form-row { grid-template-columns: 1fr; } }

.field { display: flex; flex-direction: column; gap: 8px; }
.field label { font-size: 14px; font-weight: 500; color: var(--ink-2); }
.field input, .field select, .field textarea {
  font: inherit;
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: #fff;
  color: var(--ink);
  width: 100%;
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(10,10,10,0.08);
}
.field textarea { min-height: 130px; resize: vertical; }
.field-help { font-size: 13px; color: var(--muted); }

.checkbox { display: flex; gap: 10px; align-items: flex-start; font-size: 13px; color: var(--muted); }
.checkbox input { width: 16px; height: 16px; margin-top: 3px; }

/* ---------- Newsletter ---------- */

.newsletter {
  display: flex; gap: 8px; max-width: 480px; margin: 24px auto 0;
}
.newsletter input {
  flex: 1; padding: 13px 16px; border: 1px solid var(--line);
  border-radius: var(--radius-s); background: #fff; font: inherit;
}
.newsletter input:focus { outline: none; border-color: var(--ink); box-shadow: 0 0 0 3px rgba(10,10,10,0.08); }

/* ---------- Trust logos ---------- */

.trust-logos {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
}
@media (max-width: 880px) { .trust-logos { grid-template-columns: 1fr 1fr; } }
.trust-logo {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: #fff;
  padding: 28px 24px;
  text-align: center;
  font-size: 14px;
  color: var(--ink-3);
  display: flex; flex-direction: column; align-items: center; gap: 14px;
}
.trust-logo .logo-block {
  width: 120px; height: 36px;
  background: #d8d8dc;
  border-radius: 4px;
  /* When an <img> is dropped inside, it should fill the slot
     proportionally — remove the grey fill and let the logo show. */
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.trust-logo .logo-block:has(img) {
  background: transparent;
  border-radius: 0;
}
.trust-logo .logo-block img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

/* ---------- Sub nav (anchor bar) ---------- */

.subnav {
  background: var(--bg-soft);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  position: sticky;
  top: 72px;
  z-index: 5;
}
.subnav .container {
  display: flex; gap: 32px; padding-top: 14px; padding-bottom: 14px;
  flex-wrap: wrap;
}
.subnav a {
  color: var(--muted);
  font-weight: 500;
}
.subnav a.is-active { color: var(--ink); }
.subnav a:hover { color: var(--ink); text-decoration: none; }

/* ---------- Side nav (accessibility, etc.) ---------- */

.side-nav-layout {
  display: grid; grid-template-columns: 280px 1fr; gap: 64px;
  align-items: flex-start;
}
@media (max-width: 980px) { .side-nav-layout { grid-template-columns: 1fr; } }
.side-nav { position: sticky; top: 96px; }
.side-nav ul a {
  display: block; padding: 12px 16px;
  color: var(--ink-3); font-size: 14px;
  border-radius: var(--radius-s);
  margin-bottom: 4px;
}
.side-nav ul a.is-active { background: var(--bg-soft); color: var(--ink); font-weight: 500; }
.side-nav ul a:hover { background: var(--bg-soft); color: var(--ink); text-decoration: none; }

/* ===================================================================
   LEGAL / POLICY PAGES — chapterPage block (Figma "day" design)
   One shared template for Terms / Privacy / Cookies / Disclosures /
   Accessibility. Title + "last updated" run full-width; below them a
   two-column grid: content on the LEFT, a sticky "Jump to section" TOC
   on the RIGHT with a purple active pill. (Layout only here — the page
   background wash is handled separately.)
   =================================================================== */
.chapter-page {
  /* Clear the fixed ~156px site header — legal pages have no hero to sit beneath it. */
  padding: 190px 0 96px;
}

/* Top-right white node/connector grid lattice (Figma "Group 1000005669") — the
   SAME public/images/hero-grid.svg the home hero + About page already use.
   REUSED, not recreated. Sits BEHIND the content, bleeding up off the top and off
   the right edge (clipped by .page-frame's overflow-x: clip), showing over the
   lavender top band and dissolving as the page fades to white (the SVG carries its
   own white feather). */
.chapter-page {
  position: relative;
}
.chapter-page::before {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
  top: -230px;
  right: 0;
  width: 749px;
  height: 1092px;
  background: url("/images/hero-grid.svg") right top / 749px 1092px no-repeat;
}
@media (max-width: 1024px) {
  .chapter-page::before { display: none; }
}
.chapter-page > .container {
  position: relative;
  z-index: 1;
}

/* Legal-page background (Figma "Frame 1000005759"): lavender at the very top that
   FADES to white over a ~228px band at the intro / Quick-Summary level (Leo's red
   line), then WHITE all the way down to the footer. Legal pages don't match the
   home/about/resources white-outs, so the global lavender body wash would otherwise
   run full-page. White the body out, and let .page-frame paint the lavender bg-wash
   at the top with a white gradient OVER it: transparent until 401px, fully white by
   629px, then solid white down to the wash's 2136px extent (below which the white
   body shows). The footer keeps its own lavender band. */
body:has(.chapter-page) {
  background-color: #fff;
  background-image: none;
}
body:has(.chapter-page) .page-frame {
  background-color: #fff;
  background-image:
    linear-gradient(180deg, rgba(255, 255, 255, 0) 450px, #ffffff 629px),
    radial-gradient(48% 52% at 0% 9%, rgba(31, 127, 251, 0.12), transparent 70%),
    radial-gradient(48% 52% at 85% 87%, rgba(31, 127, 251, 0.12), transparent 70%),
    radial-gradient(62% 48% at 97% 19%, rgba(79, 50, 201, 0.12), transparent 70%),
    radial-gradient(46% 46% at 5% 80%, rgba(79, 50, 201, 0.12), transparent 70%),
    radial-gradient(40% 32% at 37% 50%, rgba(79, 50, 201, 0.06), transparent 72%),
    linear-gradient(180deg, #f4f2fe, #f4f2fe);
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 100% 629px;
}
/* Use the SAME 1440 frame + padding as the header so the title's left edge aligns
   with the nav logo and there's room for the 764px content column + right TOC. */
.chapter-page > .container {
  max-width: 1440px;
  padding-left: clamp(24px, 3.5vw, 50px);
  padding-right: clamp(24px, 3.5vw, 50px);
}
/* Header block — Figma "Frame 1000005689": title + "last updated" + intro,
   stacked with a 20px gap, 764px wide. */
.chapter-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 20px;
  max-width: 764px;
}
/* Title — Amethysta 48 / 120% / -0.05em / #161129 (= --ink). */
.chapter-title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 48px;
  line-height: 1.2;
  letter-spacing: -0.05em;
  color: var(--ink);
}
/* "Last updated" — DM Sans 20 / 28 / ink @ 70%. */
.chapter-updated {
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: rgba(29, 18, 50, 0.7);
}
/* Intro lead — DM Sans 20 / 28 / #161129 (= --ink). */
.chapter-main .chapter-intro {
  margin: 0 0 32px;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 20px;
  line-height: 28px;
  color: var(--ink);
}
/* Content column + TOC grid. */
.chapter-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 120px;
  align-items: start;
  margin-top: 20px;
}
@media (max-width: 980px) {
  .chapter-grid { grid-template-columns: 1fr; gap: 40px; }
}
.chapter-main { min-width: 0; max-width: none; padding: 0; }

/* Quick Summary box. */
.chapter-summary {
  background: #fff;
  border: none;
  border-radius: var(--radius-l);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05), 0 4px 6px 1px rgba(0, 0, 0, 0.05);
  padding: 28px 28px;
  margin: 0 0 8px;
}
.chapter-summary-label {
  font-weight: 600;
  font-size: 16px;
  color: var(--ink);
  margin-bottom: 12px;
}
.chapter-summary p { font-size: 16px; line-height: 1.7; }
.chapter-summary p:last-child { margin-bottom: 0; }

/* Numbered section heading — DM Sans 36 / 120% semibold. */
.chapter-main h2 {
  border-top: none;
  padding-top: 0;
  margin: 64px 0 0;
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 36px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.chapter-main h2:first-of-type { margin-top: 40px; }

/* Body copy — DM Sans 20 / 28 (140%), #161129. */
.chapter-main > .payload-richtext { margin-top: 20px; }
.chapter-main > .payload-richtext p {
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 28px;
  color: var(--ink);
  margin: 0 0 20px;
}
.chapter-main > .payload-richtext > *:last-child { margin-bottom: 0; }

/* Bulleted lists with purple check-disc bullets. */
.chapter-main > .payload-richtext ul {
  list-style: none;
  margin: 20px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.chapter-main > .payload-richtext ul li {
  position: relative;
  margin: 0;
  padding-left: 28px;
  font-family: var(--font-sans);
  font-size: 20px;
  line-height: 24px;
  color: var(--ink-2);
}
.chapter-main > .payload-richtext ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 4px;
  width: 16px;
  height: 16px;
  background: url('/images/check-disc.svg') center / contain no-repeat;
}
.chapter-main > .payload-richtext ul li p {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}

/* Right-hand sticky TOC inside .chapter-grid — Figma legal-page style.
   These rules are SCOPED to `.chapter-page .side-nav` so they only
   touch the legal-page TOC, not the article-page TOC (which uses
   `.post-layout-aside.side-nav` below). */
.chapter-grid .side-nav { position: sticky; top: 120px; }
.side-nav-label {
  margin: 0 0 14px;
  padding-left: 4px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink);
}
.chapter-page .side-nav ul { list-style: none; margin: 0; padding: 0; }
.chapter-page .side-nav ul a {
  display: block;
  padding: 15px 24px;
  margin-bottom: 0;
  font-size: 16px;
  line-height: 1.4;
  color: var(--ink-2);
  border-radius: 999px;
}
.chapter-page .side-nav ul a:hover {
  background: var(--bg-soft);
  color: var(--ink);
}
.chapter-page .side-nav ul a.is-active,
.chapter-page .side-nav ul a.is-active:hover {
  background: var(--purple);
  color: #fff;
  box-shadow:
    0 1px 2px -1px rgba(0, 0, 0, 0.1),
    0 1px 3px rgba(0, 0, 0, 0.1);
}

/* Article-page sidebar TOC ("In this article" panel) — per Figma
   "Frame 1000005739" spec: 272 wide, 424 tall, flex column with
   32px gap between items, no padding. Scoped to .post-layout-aside
   (the modifier class added in PostTOC.tsx) so the generic
   .side-nav used elsewhere keeps its existing styling. */
.post-layout-aside.side-nav {
  width: 272px;
  /* No min-height — the TOC sizes to its content so it can't extend
     past its grid cell into elements below (CTABand, footer). */
  max-height: calc(100vh - 128px);
  overflow-y: auto;
  align-self: start;
  padding: 0;
}
.post-layout-aside.side-nav ul {
  /* Per Figma "Frame 1000005744" — 8px gap between TOC items,
     padding-bottom 16px on the group. */
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding: 0 0 16px;
  list-style: none;
}
.post-layout-aside.side-nav ul li {
  margin: 0;
}
.post-layout-aside.side-nav ul a {
  display: block;
  padding: 0;
  margin: 0;
  background: transparent;
  border-radius: 0;
  font-family: var(--font-dm-sans);
  font-size: 16px;
  line-height: 1.4;
  /* Per Figma — TOC links render in purple (#4B33C1) */
  color: #4B33C1;
}
.post-layout-aside.side-nav ul a.is-active {
  background: transparent;
  color: #4B33C1;
  font-weight: 600;
}
.post-layout-aside.side-nav ul a:hover {
  background: transparent;
  color: #4B33C1;
  text-decoration: underline;
}

/* "Continue learning" card in the article sidebar — sits under the TOC and
   links to a related article (the post's relatedPosts[0], else a recent
   fallback). Soft card matching the resource palette. */
.continue-learning {
  margin-top: 24px;
  padding: 20px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.continue-learning-label {
  display: block;
  font-family: var(--font-dm-sans);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink);
  margin-bottom: 10px;
}
.continue-learning-title {
  display: block;
  font-family: var(--font-dm-sans);
  font-size: 16px;
  line-height: 1.35;
  font-weight: 500;
  color: #4B33C1;
  margin-bottom: 8px;
}
.continue-learning-title:hover { text-decoration: underline; }
.continue-learning-meta {
  display: block;
  font-family: var(--font-dm-sans);
  font-size: 13px;
  color: var(--muted);
}

/* Post body layout — narrower aside than .side-nav-layout because the
   article body itself is constrained to 820px max-width. The TOC
   component (PostTOC) hides itself if the post has fewer than two H2s,
   so single-section posts naturally fall back to a centered body. */
.post-layout {
  /* Body on the LEFT (792px per Figma), TOC sidebar on the RIGHT
     (272px per Figma "Frame 1000005739"). The PostTOC component
     renders its <aside> BEFORE the body in DOM order; flip the
     order visually with grid-template-areas so body lands in column
     1 (left) and TOC in column 2 (right). */
  display: grid;
  grid-template-columns: 792px 272px;
  grid-template-areas: "body toc";
  gap: 56px;
  align-items: flex-start;
  justify-content: center;
}
.post-layout > .post-layout-aside { grid-area: toc; }
.post-layout > *:not(.post-layout-aside) { grid-area: body; }
@media (max-width: 980px) {
  .post-layout {
    display: block;
    grid-template-columns: none;
    grid-template-areas: none;
  }
  .post-layout-aside { display: none; }
}

/* ---------- Provider cards (Data Sources) ----------
   1:1 with the Figma "Provider Details" card. The card is a white surface with
   the exact 30px radius (--radius-l) and the exact two-layer soft drop-shadow
   (--shadow, lifted from the Figma card's filter), 40px padding. Head row =
   serif provider name + sans sub-label on the left, logo top-right. Below it, a
   stack of spec rows: an uppercase, letter-spaced muted label over its value.
   Colors map straight to the design tokens (the SVG export's p3 values are
   identical): name/sub-label = --ink (#151127), value = --ink-2 (#1B1230),
   label = --ink-2 @ 0.7. Reused for every provider in the list. */

.provider-section-title { font-size: 32px; margin-bottom: 8px; }
.provider-section-sub { color: var(--muted); font-size: 18px; margin-bottom: 40px; max-width: 60ch; }

/* One card per row, stacked. Capped at the Figma card width (766px) and
   left-aligned under the section heading, so each card keeps the exact
   design proportions instead of stretching the full content column. */
.provider-grid { display: flex; flex-direction: column; gap: 28px; max-width: 766px; }

.provider {
  background: #fff;
  border-radius: var(--radius-l);   /* 30px — exact */
  box-shadow: var(--shadow);        /* exact Figma two-layer card shadow */
  padding: 40px;
}

/* Head: name + sub-label left, logo top-right. */
.provider-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 40px;
}
.provider-headings { min-width: 0; }
.provider-name {
  font-family: var(--font-serif);   /* Amethysta — the name is set in the serif */
  font-weight: 400;
  font-size: 48px;
  line-height: 1.05;
  letter-spacing: -0.05em;          /* matches the Figma serif headline tracking */
  color: var(--ink);
  margin: 0;
}
.provider-role { margin-top: 6px; }
.provider-role p,
.provider-role .payload-richtext { font-size: 20px; line-height: 1.3; color: var(--ink); margin: 0; }

.provider-logo { flex: none; margin-top: 6px; }
.provider-logo img {
  height: auto; width: auto;
  max-height: 48px; max-width: 160px;
  object-fit: contain;
}

/* Spec rows: ~79px pitch, label baseline sits ~26px above its value. */
.provider-specs { display: flex; flex-direction: column; gap: 32px; margin: 0; }
.provider-specs .k {
  display: block;
  font-size: 13px; line-height: 1.2; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: rgba(29, 18, 50, 0.7);     /* --ink-2 @ 0.7 */
  margin: 0 0 8px;
}
.provider-specs .v { font-size: 16px; line-height: 1.45; color: var(--ink-2); margin: 0; }

.provider-link {
  display: inline-block; margin-top: 28px;
  color: var(--purple); font-weight: 500;
}

@media (max-width: 640px) {
  .provider { padding: 28px; }
  .provider-head { flex-direction: column; }
  .provider-name { font-size: 34px; }
  .provider-role p, .provider-role .payload-richtext { font-size: 18px; }
}

/* ---------- Stage block (Methodology) ---------- */

.stage-block { padding: clamp(56px, 8vw, 100px) 0; }
/* Module sections use a wider container so the demo video can be large
   enough to read the UI inside it (matches the Figma layout). */
.stage-block > .container { max-width: 1440px; }
/* Text column gets a bit less than half so the video reads larger. */
.stage-block .split { grid-template-columns: 1fr 1.3fr; gap: clamp(28px, 5vw, 72px); }
/* When the visual is on the LEFT (Reporter, Trader), flip the column
   ratio so the visual still gets the wider 1.3fr slot. Without this,
   left-side modules render their video at the smaller 1fr width. */
.stage-block .split:has(> .module-visual:first-child) {
  grid-template-columns: 1.3fr 1fr;
}
@media (max-width: 980px) {
  .stage-block .split,
  .stage-block .split:has(> .module-visual:first-child) {
    grid-template-columns: 1fr;
  }
}
.stage-block .stage-num {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--muted);
  margin-bottom: 20px;
  font-weight: 500;
}
.stage-block h2 { margin-bottom: 24px; }
.stage-block p { font-size: 17px; line-height: 1.7; color: var(--ink-3); margin-bottom: 18px; }

/* ---------- Mid-CTA (above hero in Product) ---------- */

.midcta {
  background: var(--bg-dim);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px 32px;
  display: flex; justify-content: space-between; align-items: center;
  gap: 24px; flex-wrap: wrap;
}
.midcta h4 { font-size: 22px; margin-bottom: 4px; font-weight: 600; }
.midcta p { color: var(--muted); font-size: 14px; }

/* ---------- AI Chat Demo (For Investors) ---------- */

.chat-demo {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.chat-line { display: grid; grid-template-columns: 32px 1fr; gap: 12px; align-items: start; margin-bottom: 16px; }
.chat-line .av { width: 32px; height: 32px; border-radius: 50%; background: #cfcfd4; }
.chat-line .av.napoli { background: var(--ink); }
.chat-line .name { font-size: 13px; font-weight: 500; color: var(--ink); margin-bottom: 6px; }
.chat-line .bubble {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 18px;
  font-size: 14px;
  color: var(--ink-2);
}
.chat-line .bubble.dark { background: var(--ink); color: #fff; border-color: var(--ink); }

/* ---------- Holdings table (For Investors) ---------- */

.holdings {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.holdings h4 { margin-bottom: 16px; font-size: 16px; }
.holdings table { width: 100%; border-collapse: collapse; }
.holdings th, .holdings td {
  text-align: left; padding: 12px 0;
  font-size: 14px;
  border-bottom: 1px solid var(--line);
}
.holdings th { font-size: 12px; color: var(--muted); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; }
.holdings td.right, .holdings th.right { text-align: right; }
.holdings tr:last-child td { border-bottom: none; }

.reasoning-card {
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  padding: 24px;
}
.reasoning-card h4 { color: #fff; margin-bottom: 16px; font-size: 16px; }
.reasoning-card .sources { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.reasoning-card .source-pill {
  background: rgba(255,255,255,0.12); padding: 4px 10px;
  border-radius: 4px; font-size: 12px;
}
.reasoning-card p { color: #d1d1d4; font-size: 14px; line-height: 1.55; margin-bottom: 16px; }
.reasoning-card a { color: #fff; font-weight: 500; font-size: 14px; text-decoration: underline; }

/* ---------- Testimonials ---------- */

.testimonial {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px;
  display: flex; flex-direction: column; gap: 18px;
}
.testimonial .stars { color: var(--ink); letter-spacing: 4px; font-size: 14px; }
.testimonial blockquote {
  margin: 0;
  font-size: 15px;
  color: var(--ink-2);
  line-height: 1.55;
  font-style: italic;
}
.testimonial .author { display: flex; align-items: center; gap: 12px; }
.testimonial .avatar {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: #cfcfd4;
}
.testimonial .author small { color: var(--muted); display: block; font-size: 13px; }
.testimonial .author strong { font-size: 14px; }

/* ---------- Misc ---------- */

.divider { border: none; border-top: 1px solid var(--line); margin: 0; }
.center { text-align: center; }

.mt-2 { margin-top: 16px; }
.mt-4 { margin-top: 32px; }
.mt-6 { margin-top: 48px; }

/* ---------- Module video loops ---------- */
/* Each .module-visual stacks an AVIF/JPG poster (visible immediately on
   first paint) with a <video> that lazy-loads + autoplays when scrolled
   into view. Video fades in over the poster once the first frame is
   ready, so the section never looks blank. */
.module-visual {
  position: relative;
  width: 100%;
  aspect-ratio: 1100 / 678;
  border-radius: var(--radius);
  overflow: hidden;
  background: #d6dae0;
  box-shadow: var(--shadow);
  border: 1px solid var(--line);
}
.module-visual > picture,
.module-visual > picture > img,
.module-visual > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.module-visual > video {
  opacity: 0;
  transition: opacity 220ms ease-out;
}
.module-visual.is-playing > video { opacity: 1; }

/* When a .module-visual sits in the .split grid, it should NOT inherit
   the .visual placeholder min-height — its own aspect-ratio drives size. */
.split .module-visual { min-height: 0; }

/* Lazy-render module sections that are far below the fold. */
.stage-block { content-visibility: auto; contain-intrinsic-size: auto 700px; }

/* Respect users who've turned off motion: keep the poster, skip the video. */
@media (prefers-reduced-motion: reduce) {
  .module-visual > video { display: none; }
  .module-visual.is-playing > video { display: none; }
}

/* ============================ Trust tabview ============================ */
/* Figma "Built on institutional foundations / Accuracy builds trust": a left
   heading block, then a 2-col layout — a vertical tab rail (light track with a
   dark active segment) on the left, a swappable panel on the right. The Data
   Sources panel is a near-black card holding a 2×2 grid of white logo chips.
   Sits on the violet .bloom-band wash (trust → pricing). */

.trust-head { max-width: 560px; margin-bottom: 0; }

.trust-tabview {
  margin-top: clamp(32px, 5vw, 56px);
  display: grid;
  /* Figma: the heading stays flush-left while the tab group is indented
     right, so the rail line falls under the heading text and the cards sit
     on the right edge. Percentage keeps the offset proportional. */
  margin-left: 18%;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(32px, 6vw, 88px);
  align-items: start;
}

/* Left rail (Figma): a raised WHITE rounded track (5px) carrying the shadow/xl,
   with a dark rounded segment overlaid on the active tab. Drawn as pseudo-
   elements because a border can't have rounded caps or a line-only shadow:
   .trust-tabs::before is the continuous white track; each button's ::before is
   the dark active segment, pulled back onto the track via a negative left. */
.trust-tabs {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 48px;
  padding-left: 33px;
}
.trust-tabs::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  border-radius: 9999px;
  background: #fff;
  box-shadow: 4px 10px 65px rgba(0, 0, 0, 0.1), 4px 8px 10px rgba(0, 0, 0, 0.1);
}
.trust-tabs button {
  position: relative;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  padding: 22px 0;
  font-family: inherit;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.4;
  color: var(--ink);
  opacity: 0.45;
  transition: opacity 160ms ease;
}
.trust-tabs button::before {
  content: '';
  position: absolute;
  left: -33px;
  top: 0;
  bottom: 0;
  width: 5px;
  border-radius: 9999px;
  background: var(--ink);
  opacity: 0;
  transition: opacity 160ms ease;
}
.trust-tabs button:hover { opacity: 0.8; }
.trust-tabs button.is-active { opacity: 1; }
.trust-tabs button.is-active::before { opacity: 1; }
.trust-tabs button:focus-visible { outline: 2px solid var(--purple); outline-offset: 2px; border-radius: 2px; }

.trust-panels { min-width: 0; }
.trust-panel[hidden] { display: none; }

/* Data Sources — white logo chips floating on the section wash (Figma: no dark panel) */
.trust-logo-panel { background: transparent; border-radius: 0; padding: 0; max-width: 440px; }
.trust-logo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.trust-logo-card {
  background: #fff;
  border-radius: 16px;
  min-height: 80px;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 4px 4px 25px -3px rgba(0, 0, 0, 0.03);
}
.trust-logo-card img { max-width: 75%; max-height: 40px; width: auto; height: auto; object-fit: contain; }
.trust-caption { margin-top: 24px; max-width: 420px; font-size: 17px; line-height: 1.5; color: var(--ink-3); }

/* Team Credentials */
.trust-cred-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 22px; }
.trust-cred { display: flex; gap: 16px; align-items: center; }
.trust-cred-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--purple); flex: none; }
.trust-cred-text strong { display: block; font-size: 17px; color: var(--ink); }
.trust-cred-text span { display: block; font-size: 14px; color: var(--muted); margin-top: 2px; }

/* Methodology */
.trust-method :where(h3, h4) { font-size: 18px; margin: 0 0 6px; }
.trust-method :where(h3, h4):not(:first-child) { margin-top: 24px; }
.trust-method p { color: var(--muted); margin: 0; line-height: 1.6; }

@media (max-width: 880px) {
  .trust-tabview { grid-template-columns: 1fr; gap: 28px; margin-left: 0; }
  /* Tabs become a horizontal, scrollable row above the panel; the vertical
     white-track pseudo-elements are dropped for a bottom-border indicator. */
  .trust-tabs { flex-direction: row; padding-left: 0; border-bottom: 2px solid var(--line); gap: 8px; overflow-x: auto; }
  .trust-tabs::before { content: none; }
  .trust-tabs button {
    margin-bottom: -2px;
    border-bottom: 2px solid transparent;
    padding: 10px 4px 14px;
    white-space: nowrap;
    font-size: 16px;
  }
  .trust-tabs button::before { content: none; }
  .trust-tabs button.is-active { border-bottom-color: var(--ink); }
}

/* ---------- StatSplit (About "The problem we're solving") ----------
   Two columns: claim/body on the left, a stack of stat cards on the
   right. Stat cards reuse the canonical card surface (white + --shadow +
   --radius-l). Figma: cards stacked with a 24px gap; large serif figure;
   small uppercase audience eyebrow with a dark icon. */

/* Figma "Ellipse 818": the soft blue bloom bleeding in from the lower-left
   behind the problem section. Reuses blue-ball-right.svg (the EXACT 933×922
   ellipse, rx 466.5, 90px blur — per the reuse rule); its baked 0.7 opacity is
   dialed to the Figma's 0.2 (0.7 × 0.29 ≈ 0.2). Mounted as a ::before so the
   StatSplit component isn't touched; overflow-x clips the left bleed. */
section:has(> .container > .stat-split) { position: relative; overflow-x: clip; }
section:has(> .container > .stat-split) > .container { position: relative; z-index: 1; }
section:has(> .container > .stat-split)::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: -828px;                 /* ellipse centre ~88px off the section's left edge */
  top: 60%;
  transform: translateY(-50%);  /* bloom sits low-left, per Figma cy */
  width: 1480px;
  height: 1480px;
  background: url("/images/blue-ball-right.svg") center / contain no-repeat;
  opacity: 0.29;                /* blue-ball-right's baked 0.7 × 0.29 ≈ 0.2 */
  pointer-events: none;
}
@media (max-width: 880px) {
  section:has(> .container > .stat-split)::before { display: none; }
}

.stat-split {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: clamp(40px, 5vw, 80px);
  align-items: start;
}
.stat-split-copy h2 { margin-bottom: 24px; }   /* Figma auto-layout gap */
.stat-split-copy p {
  color: var(--ink);                           /* #161129 (Figma) — was --ink-3 */
  font-size: 16px;
  line-height: 1.3;                            /* 130% (Figma) — was 1.65 */
  margin: 0 0 24px;                            /* Figma 24px gap — was 18px */
}
.stat-split-copy p:last-child { margin-bottom: 0; }
.stat-split-cards {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
/* Figma card: white, 30px radius, no border, soft two-layer drop shadow, 40px
   padding. Layout is a 48px icon in a LEFT column + a right column stacking the
   uppercase eyebrow → large serif figure → supporting line (all #151127). */
.stat-card {
  display: flex;
  align-items: flex-start;
  gap: 40px;
  background: #fff;
  border: 0;
  border-radius: var(--radius-l);              /* 30px */
  /* Two-layer Figma shadow: feMorphology erode → negative spread; the
     feGaussianBlur stdDeviation doubles to the CSS blur radius. */
  box-shadow:
    4px 8px 10px -6px rgba(0, 0, 0, 0.1),
    4px 10px 65px -5px rgba(0, 0, 0, 0.1);
  padding: 40px;
}
.stat-card-icon { display: block; width: 48px; height: 48px; flex-shrink: 0; }
.stat-card-glyph {
  font-size: 40px;
  line-height: 1;
  color: var(--ink-2);
  flex-shrink: 0;
}
.stat-card-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.stat-card-eyebrow {
  font-family: var(--font-sans);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);                           /* #151127 (Figma) */
  margin: 0;
}
.stat-card-value {
  font-family: var(--font-serif);
  font-weight: 400;
  letter-spacing: -0.02em;
  font-size: clamp(38px, 3.8vw, 50px);
  line-height: 1;
  color: var(--ink);                           /* #151127 (Figma) */
  margin: 22px 0 0;
}
.stat-card-desc {
  font-family: var(--font-sans);
  color: var(--ink);                           /* #151127 (Figma) */
  font-size: 18px;
  line-height: 1.55;                           /* ~28px leading (Figma) */
  margin: 28px 0 0;
}
@media (max-width: 980px) {
  .stat-split { grid-template-columns: 1fr; gap: 40px; }
}

/* =====================================================================
   Data and methodology — About page (Figma)
   Two tall soft cards, a row of icon-left trust cards, and a legal
   disclaimer box.
   ===================================================================== */
.dm-title { margin-bottom: 40px; }
.dm-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; }
.dm-row + .dm-row { margin-top: 24px; }
/* Figma surface: flat #F6F6F9, 30px radius, no border/shadow/blur. The compound
   `.card.dm-card` selector beats the later translucent/glassy `.card` override
   (same fix as the audience panels), which otherwise wins on source order. */
.card.dm-card {
  background: #f6f6f9;
  background: color(display-p3 0.965 0.965 0.976);
  border: 0;
  box-shadow: none;
  backdrop-filter: none;
  border-radius: var(--radius-l);              /* 30px */
}
.dm-card { padding: 36px 24px; }
.dm-card h3 {
  font-family: var(--font-sans);
  font-size: 20px;                             /* Figma */
  font-weight: 700;
  color: var(--ink-2);                         /* #1B1230 (Figma) */
  margin: 0 0 16px;
}
.dm-body { font-size: 16px; line-height: 1.3; color: var(--ink); }  /* 16/130% #151127 (Figma) */
.dm-body p { margin: 0 0 16px; color: var(--ink); }  /* beat global `p` (--ink-3) → #151127 */
.dm-body p:last-child { margin-bottom: 0; }
.dm-body strong { color: var(--ink); font-weight: 700; }
/* Provider list: purple filled circle + white check, matching the Figma. */
.dm-body ul {
  list-style: none;
  margin: 18px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.dm-body ul li { position: relative; padding-left: 37px; }
/* Exact Figma marker: 24px purple disc + the verbatim white check PATH (not a
   font glyph). check-disc.svg is the circle + stroke transcribed from the SVG. */
.dm-body ul li::before {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  width: 24px;
  height: 24px;
  background: url("/images/check-disc.svg") center / 24px 24px no-repeat;
}

/* Trust cards — icon to the left of heading + one line of copy. */
.dm-row-trust .dm-card {
  display: flex;
  gap: 32px;
  align-items: flex-start;
  padding: 30px 24px;
}
.dm-trust-icon { width: 48px; height: 48px; flex: none; display: block; }
.dm-trust-glyph { font-size: 30px; line-height: 1; flex: none; color: var(--ink); }
.dm-trust-copy h3 { margin-bottom: 8px; }
.dm-trust-copy p { font-size: 16px; line-height: 1.45; color: var(--ink-2); margin: 0; }

/* Important Disclaimer box. */
.dm-disclaimer {
  margin-top: 36px;
  display: flex;
  gap: 14px;
  align-items: flex-start;
  border: 1px solid #ff5047;
  background: transparent;
  border-radius: var(--radius-l);
  padding: 22px 26px;
}
.dm-disclaimer-icon { width: 24px; height: 24px; flex: none; display: block; }
.dm-disclaimer-label { font-weight: 700; color: var(--ink); }
.dm-disclaimer-copy p {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--ink);
}
@media (max-width: 700px) {
  .dm-row { grid-template-columns: 1fr; }
}

/* ---------- Demo video lightbox (DemoVideoModal) ---------- */
/* Full-viewport dimmed backdrop; the player is centered and capped so it never
   exceeds the viewport. Sits above everything (header is ~z-index 50). */
.demo-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(16px, 4vw, 48px);
  background: rgba(3, 2, 8, 0.72);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  animation: demo-modal-fade 0.18s ease-out;
}
@keyframes demo-modal-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.demo-modal {
  position: relative;
  width: min(100%, 1100px);
  border-radius: var(--radius-l);           /* 30px, matches cards/CTA */
  background: #030208;
  box-shadow: 0 24px 80px -12px rgba(0, 0, 0, 0.55);
  animation: demo-modal-rise 0.2s ease-out;
}
@keyframes demo-modal-rise {
  from { transform: translateY(8px) scale(0.99); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.demo-modal-video {
  display: block;
  width: 100%;
  height: auto;
  max-height: calc(100vh - clamp(32px, 8vw, 96px));
  border-radius: var(--radius-l);
  background: #030208;
}
/* Close button — floats just outside the top-right corner of the player. */
.demo-modal-close {
  position: absolute;
  top: -14px;
  right: -14px;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: none;
  background: #fff;
  color: var(--ink);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.12s ease;
}
.demo-modal-close:hover { background: var(--bg-soft); transform: scale(1.05); }
.demo-modal-close:focus-visible { outline: 3px solid var(--purple); outline-offset: 2px; }
/* On small screens the close button sits inside the corner so it isn't clipped
   by the viewport edge. */
@media (max-width: 640px) {
  .demo-modal-close { top: 8px; right: 8px; }
}
