/* ==========================================================================
   Serifo — Design Tokens
   Source: Figma "Serifo Website" — Desktop (1440) & Mobile (430) frames.
   Fluid scaling: all tokens below use clamp() to interpolate linearly
   between two viewport anchors, locking at the Desktop value above 1440px.

   The TYPE tokens are anchored 320px -> 1440px; every other token is still
   anchored 430px -> 1440px as Figma authored it. That difference matters:
   anchored at 430, a clamp reaches its floor there and is FLAT below, so
   phones between 320 and 430 all rendered identical type in containers up
   to 110px apart. It also left a step at 768px, where the layout switches
   to three columns — type jumped back up to near-desktop size exactly
   where the columns became narrowest, and the tile copy overflowed its
   card by ~48px. One continuous ramp per token removes both problems.
   The 1440px values are unchanged, so the desktop design is as drawn.
   ========================================================================== */

:root {
  /* ---- Palette (from Figma "palette/*" variables — identical at both
     breakpoints) ---- */
  --color-black: #000000;
  --color-bone: #f8f7f5;
  --color-salmon: #ff8f8a;
  --color-maroon: #550000;
  --color-white: #ffffff;
  --color-burnt-orange: #c44a00;
  --color-peach: #ffd4b4;
  --color-light-teal: #aae9e5;
  --color-aegean-blue: #09264d;
  --color-teal: #00aca3;
  --color-bright-blue: #0069bc;

  /* ---- Font families (guessed weights map to closest system/CDN name —
     see README note on fonts) ---- */
  --font-serif: "EB Garamond", "Times New Roman", serif;
  --font-body: "Geist", "Helvetica Neue", Arial, sans-serif;
  --font-mono: "DM Mono", "Courier New", monospace;
  --font-display: "Space Grotesk", "Helvetica Neue", Arial, sans-serif;

  /* ---- Type scale — fluid between 430px and 1440px ---- */
  --fs-display: clamp(3.875rem, 2.9703rem + 3.3663vw, 6rem);   /* display-hero */
  --lh-display: clamp(3.875rem, 2.4594rem + 5.2673vw, 7.2rem);
  --ls-display: -2px;

  --fs-h1: clamp(3rem, 2.6275rem + 1.3861vw, 3.875rem);
  --lh-h1: clamp(3.6rem, 3.153rem + 1.6634vw, 4.65rem);
  --ls-h1: -2px;

  --fs-h2: clamp(1.875rem, 1.6621rem + 0.7921vw, 2.375rem);
  --lh-h2: clamp(2.25rem, 1.9946rem + 0.9505vw, 2.85rem);
  --ls-h2: 0px;

  --fs-h3: clamp(1.375rem, 1.3218rem + 0.198vw, 1.5rem);
  --lh-h3: clamp(2.0625rem, 1.9827rem + 0.297vw, 2.25rem);
  --ls-h3: 0px;

  --fs-body: clamp(1.125rem, 1.0718rem + 0.198vw, 1.25rem);
  --lh-body: clamp(1.6875rem, 1.6077rem + 0.297vw, 1.875rem);
  --ls-body: 0px;

  --fs-cta: clamp(1rem, 0.9468rem + 0.198vw, 1.125rem);
  --lh-cta: clamp(1.625rem, 1.5186rem + 0.396vw, 1.875rem);
  --ls-cta: 0px;

  --fs-caption: clamp(0.875rem, 0.8218rem + 0.198vw, 1rem);
  --hero-pill-fs: clamp(0.75rem, 0.6436rem + 0.396vw, 1rem); /* hero "Backed by..." pill */
  --lh-caption: 1.6rem;
  --ls-caption: 0px;

  --fs-metrics: clamp(3.5rem, 3.2871rem + 0.7921vw, 4rem);
  --lh-metrics: clamp(3.5rem, 3.2871rem + 0.7921vw, 4rem);
  --ls-metrics: 0px;

  --fs-num-badge: clamp(1.25rem, 1.1436rem + 0.396vw, 1.5rem); /* "01/02/03" tile badges */
  --fs-offering-index: clamp(1.5rem, 1.2871rem + 0.7921vw, 2rem); /* "01 02 03" list */
  --fs-stat-label: clamp(1.375rem, 1.3218rem + 0.198vw, 1.5rem);
  --lh-stat-label: 2rem;

  /* ---- Layout ---- */
  --page-max: 1200px;                 /* content container, fixed above 1440 viewport */
  --container-pad: clamp(24px, -16.8713px + 9.505vw, 120px); /* outer gutter */

  --header-h: clamp(62px, 52.6337px + 2.1782vw, 84px);

  /* ---- Per-component gaps/paddings — each pulled from its own Figma
     "gap-X" / "top-X" value at both breakpoints, not a shared bucket.
     See ASSETS.md / build notes for which sections use true vertical
     centering (veterans, stats, closing CTA) instead of padding. ---- */
  --caps-top: clamp(78px, 66.0792px + 2.7723vw, 106px);           /* capabilities: section top → intro */
  --caps-intro-gap: clamp(64px, 57.1881px + 1.5842vw, 80px);      /* capabilities: intro → tiles grid */
  --caps-to-offerings-gap: clamp(96px, 37.6733px + 13.5644vw, 233px); /* tiles grid → offerings heading */
  --offerings-intro-gap: clamp(24px, 18.8911px + 1.1881vw, 36px); /* offerings: heading → button */
  --offerings-to-list-gap: 64px;                                   /* offerings: intro block → row list */
  --expertise-top: clamp(82px, 32.1881px + 11.5842vw, 199px);      /* expertise: section top → copy */
  --expertise-gap: clamp(72px, 51.9901px + 4.6535vw, 119px);       /* expertise: copy → checklist/chart */
  --stats-lede-gap: clamp(64px, 52.9307px + 2.5743vw, 90px);       /* stats v2: lede → badge row (mobile extrapolated — no Figma mobile source yet, see note) */
  --articles-top: clamp(64px, 52.505px + 2.6733vw, 91px);          /* articles: section top → heading (mobile approx — see note) */
  /* One rhythm for every section's top and bottom on mobile. The per-section
     tokens above are Figma-derived for desktop and each scales on its own
     curve, so at phone widths they landed between 36px and 96px — six
     sections, six different insets, which read as sloppy rather than as
     deliberate variation. Those values keep their desktop behaviour; this
     replaces them below 768px only. See the mobile rhythm block at the end
     of main.css. */
  --section-pad-mobile: clamp(56px, -17.1px + 22.86vw, 72px);      /* 56px at 320w, 72px from 390w up */
  --nav-links-gap: 40px;                                           /* desktop nav link row gap */
  --veterans-h: clamp(662px, 833.0891px - 11.8812vw, 782px);       /* veterans: true section height (centered content) */
  --stats-h: 931px;                                                 /* stats v2: true desktop section height (centered content); mobile uses padding instead — see note */

  /* Stats v2 badge (26:3212, Aug 2026 redesign) — desktop-sourced;
     mobile values are a fluid extrapolation, not from a Figma mobile
     frame (none exists yet for this node). */
  --stat-badge-fs: clamp(3.25rem, 2.505rem + 2.7723vw, 5rem);
  --stat-badge-w: 360px;   /* fixed desktop badge width; mobile is 100% of its column */
  --stat-badge-ratio: 360 / 211.982;

  /* ---- Article + Careers pages (nodes 58:5905/62:6350, 58:5824/62:6473) ---- */
  --article-top-gap: clamp(68px, 49.6931px + 4.2574vw, 111px);      /* header → article content */
  --article-block-gap: 80px;                                        /* header block / body / sources — flat both bp */
  --article-section-gap: 72px;                                      /* between article body sections — flat both bp */
  --careers-hero-culture-gap: clamp(74px, 50.5842px + 5.4455vw, 129px);
  --careers-culture-heading-gap: clamp(36px, 25.7822px + 2.3762vw, 60px);
  --careers-culture-roles-gap: clamp(53px, -12.5644px + 15.2475vw, 207px);
  --role-row-pad: 36px;                                             /* accordion row vertical padding — flat both bp */

  /* The two gaps stacking the hero copy: headline -> button -> supporting
     line. Both were unresponsive, in opposite ways. The first was a flat
     --gap-md (36px at every width). The second was not a value at all — the
     supporting line used margin-top:auto, so the space above it was just
     whatever was left after everything else was placed, which meant it
     absorbed all the slack in the section: 112px at 1440 but 393px at 2560,
     a void between the button and the paragraph rather than a scaled gap.

     Anchored to reproduce 1440 exactly (36 / 112), so the design frame is
     untouched and only the sizes either side of it change. 24 / 64 at 430,
     44 / 136 at 2560 — the same ~1.2x the type takes into the 4K band.

     The body gap is additionally capped at 13vh. It is the largest gap in
     the hero and the one with the least to say, so it is what should give
     on a short window rather than pushing the copy up into the graphic.
     13vh exceeds the width-driven value at every normal window height and
     only bites below ~860px, where the space genuinely is not there. */
  --hero-title-gap: clamp(1.5rem, 1.1807rem + 1.1881vw, 2.25rem);
  --hero-body-gap: min(clamp(4rem, 2.7228rem + 4.7525vw, 7rem), 13vh);

  --gap-xxl: clamp(96px, 73.0099px + 5.3465vw, 150px);
  --gap-xl: clamp(72px, 68.5941px + 0.7921vw, 80px);
  --gap-lg: 64px;
  --gap-md: 36px;
  --gap-sm: 24px;
  --gap-xs: 16px;
  --gap-xxs: 12px;
  --gap-tiny: 8px;

  /* ---- Components ---- */
  --btn-pad-x: 24px;
  --btn-pad-y: 12px;
  --btn-cta-pad-x: clamp(24px, 35.4059px - 0.7921vw, 32px);
  --btn-cta-pad-y: clamp(12px, 17.703px - 0.396vw, 16px);

  --logo-w: clamp(27px, 25.1127px + 0.4389vw, 31.433px);
  --logo-h: clamp(31px, 28.8713px + 0.495vw, 36px);

  --tile-pad: 36px;
  --tile-h: clamp(300px, 261.6832px + 8.9109vw, 390px); /* single-column tile height on mobile */
  --tile-gap: 16px;                                      /* gutter between tiles, desktop grid */
  --tile-stagger: clamp(0px, -48.1089px + 11.1881vw, 113px); /* desktop-only: middle column offset down */

  /* ---- Section 5 "Quality" 12-column sub-grid (max-width 1200px,
     16px gutter): text 1–4 (left), gap col 5, checklist 6–8 (3 cols),
     chart 9–12 (4 cols, flush right). Desktop only — mobile stacks. */
  --grid-12-col-w: calc((100% - 11 * 16px) / 12);

  --card-pad-y: clamp(24px, 18.8911px + 1.1881vw, 36px);

  --radius-pill: 8px;
}

/* ==========================================================================
   Large screens (above the 1440px Figma frame)
   ==========================================================================
   The ramps above stop at 1440 and lock there, so a 2560px display rendered
   type at exactly the same size as a 1440px one — correct as a floor, but on
   a 4K screen the page reads as a small island of text in the middle of a
   very large canvas.

   This continues each token from its 1440 value up to a 2560 one, at roughly
   1.2x. --page-max rides along, widening the content column from 1200px to
   1460px: without it the bigger type would simply cut the words per line,
   which is the opposite of the intent. Together they hold the measure at
   ~120 characters throughout.

   Above 2560 everything locks again, which is the right behaviour — past
   that point the viewport is a wall, not a reading distance.
   ========================================================================== */
@media (min-width: 1441px) {
  :root {
    --fs-display: clamp(6rem, 4.0714rem + 2.1429vw, 7.5rem);
    --lh-display: clamp(7.2rem, 4.8857rem + 2.5714vw, 9rem);

    --fs-h1: clamp(3.875rem, 2.5893rem + 1.4286vw, 4.875rem);
    --lh-h1: clamp(4.65rem, 3.1071rem + 1.7143vw, 5.85rem);

    --fs-h2: clamp(2.375rem, 1.6518rem + 0.8036vw, 2.9375rem);
    --lh-h2: clamp(2.85rem, 1.9821rem + 0.9643vw, 3.525rem);

    --fs-h3: clamp(1.5rem, 1.0982rem + 0.4464vw, 1.8125rem);
    --lh-h3: clamp(2.25rem, 1.6473rem + 0.6696vw, 2.7188rem);

    --fs-body: clamp(1.25rem, 0.9286rem + 0.3571vw, 1.5rem);
    --lh-body: clamp(1.875rem, 1.3929rem + 0.5357vw, 2.25rem);

    --fs-cta: clamp(1.125rem, 0.8839rem + 0.2679vw, 1.3125rem);
    --lh-cta: clamp(1.875rem, 1.4732rem + 0.4464vw, 2.1875rem);

    --fs-caption: clamp(1rem, 0.7589rem + 0.2679vw, 1.1875rem);
    --lh-caption: clamp(1.6rem, 1.2464rem + 0.3929vw, 1.875rem);
    --hero-pill-fs: clamp(1rem, 0.7589rem + 0.2679vw, 1.1875rem);

    --fs-metrics: clamp(4rem, 2.7143rem + 1.4286vw, 5rem);
    --lh-metrics: clamp(4rem, 2.7143rem + 1.4286vw, 5rem);

    --fs-num-badge: clamp(1.5rem, 1.0982rem + 0.4464vw, 1.8125rem);
    --fs-offering-index: clamp(2rem, 1.4375rem + 0.625vw, 2.4375rem);
    --fs-stat-label: clamp(1.5rem, 1.0982rem + 0.4464vw, 1.8125rem);
    --lh-stat-label: clamp(2rem, 1.5179rem + 0.5357vw, 2.375rem);

    --stat-badge-fs: clamp(5rem, 3.3929rem + 1.7857vw, 6.25rem);

    /* The content column widens with the type so the measure holds. */
    --page-max: clamp(1200px, 865.714px + 23.2143vw, 1460px);

    /* Continue the hero stack past 1440 at the same ~1.2x as the type, so
       the copy keeps its proportions instead of the gaps staying put while
       the headline grows around them: 36 -> 44 and 112 -> 136 by 2560. */
    --hero-title-gap: clamp(2.25rem, 1.6071rem + 0.7143vw, 2.75rem);
    --hero-body-gap: min(clamp(7rem, 5.0714rem + 2.1429vw, 8.5rem), 13vh);
  }
}

/* ==========================================================================
   Below the 430px design frame
   ==========================================================================
   The scale above is the design spec: exactly 62/48/38/24/20/18/16 at the
   1440 desktop frame and 62/48/30/22/18/16/14 at the 430 mobile frame, with
   a linear interpolation between them. Those two frames are the whole of
   what the spec defines.

   A clamp floors at its minimum though, so on its own that spec renders a
   320px handset at the same size as a 430px one, in a container 110px
   narrower — which is why the hero headline ran to five lines there. This
   continues the ramp down to 320px and touches nothing at 430 or above: at
   exactly 430 every value below equals its spec figure, so the design frame
   is matched and only the undefined range beneath it is filled in.
   ========================================================================== */
@media (max-width: 430px) {
  :root {
    --fs-display: clamp(2.375rem, -1.9886rem + 21.8182vw, 3.875rem);
    --lh-display: clamp(2.85rem, -0.1318rem + 14.9091vw, 3.875rem);
    --fs-h1: clamp(2rem, -0.9091rem + 14.5455vw, 3rem);
    --lh-h1: clamp(2.4rem, -1.0909rem + 17.4545vw, 3.6rem);
    --fs-h2: clamp(1.5rem, 0.4091rem + 5.4545vw, 1.875rem);
    --lh-h2: clamp(1.8rem, 0.4909rem + 6.5455vw, 2.25rem);
    --fs-h3: clamp(1.1875rem, 0.6421rem + 2.7273vw, 1.375rem);
    --lh-h3: clamp(1.7812rem, 0.9631rem + 4.0909vw, 2.0625rem);
    --fs-body: clamp(1rem, 0.6364rem + 1.8182vw, 1.125rem);
    --lh-body: clamp(1.5rem, 0.9546rem + 2.7273vw, 1.6875rem);
    --fs-cta: clamp(0.9375rem, 0.7557rem + 0.9091vw, 1rem);
    --lh-cta: clamp(1.5rem, 1.1364rem + 1.8182vw, 1.625rem);
    --fs-caption: clamp(0.8125rem, 0.6307rem + 0.9091vw, 0.875rem);
    --lh-caption: clamp(1.25rem, 0.2318rem + 5.0909vw, 1.6rem);
    --hero-pill-fs: clamp(0.6875rem, 0.5057rem + 0.9091vw, 0.75rem);
    --fs-metrics: clamp(2.375rem, -0.8978rem + 16.3636vw, 3.5rem);
    --lh-metrics: clamp(2.375rem, -0.8978rem + 16.3636vw, 3.5rem);
    --fs-num-badge: clamp(1.0625rem, 0.5171rem + 2.7273vw, 1.25rem);
    --fs-offering-index: clamp(1.25rem, 0.5228rem + 3.6364vw, 1.5rem);
    --fs-stat-label: clamp(1.125rem, 0.3977rem + 3.6364vw, 1.375rem);
    --lh-stat-label: clamp(1.625rem, 0.5341rem + 5.4545vw, 2rem);
    --stat-badge-fs: clamp(2.5rem, 0.3182rem + 10.9091vw, 3.25rem);

    /* Ramp on down to 320px rather than flooring at the 430 figures: 24 -> 20
       and 64 -> 48. A 320px handset wraps the headline further, so the gaps
       around it have to give a little or the block runs past the fold. */
    --hero-title-gap: clamp(1.25rem, 0.5227rem + 3.6364vw, 1.5rem);
    --hero-body-gap: min(clamp(3rem, 0.0909rem + 14.5455vw, 4rem), 13vh);
  }
}
