/* ===== 00-tokens.css ===== */
/*
 * Link Prism design tokens.
 *
 * Derived from the Steep style reference (docs: DESIGN.md) with two corrections
 * made after measuring the real site, both of which the written reference omits
 * and both of which are what actually make it read as premium:
 *   1. The hero is NOT flat white — it sits on a soft chromatic gradient wash.
 *   2. A fractal-noise grain overlays the whole page at low opacity.
 * Everything else here matches the reference's documented scale.
 */
:root {
  /* — Ink & paper —————————————————————————————— */
  --ink: #17191c;
  /*
   * Paper is NOT pure white, deliberately. Two reasons, both measured:
   *  - `overlay` grain over #ffffff is an identity operation (overlay(1,x) === 1),
   *    so a pure-white page can carry no texture at all.
   *  - The reference's "white" is never actually white; every band sits on a
   *    faint warm ground, which is most of why it reads as paper and not screen.
   */
  --paper: #fdfcfa;
  --raised: #ffffff;        /* floating artifacts stay true white so they lift off the paper */
  --mist: #f2f2f3;
  --fog: #fafafb;
  /*
   * These three were taken from the reference palette and all FAILED WCAG AA on
   * our paper: slate 4.13:1, ash 2.84:1, smoke 2.37:1 against 4.5:1 for small
   * text. Every eyebrow, footnote and body paragraph on the site was below the
   * threshold. Darkened within the same family until they pass; the greys read
   * fractionally deeper and everything stays legible.
   */
  --slate: #636772;   /* 4.52:1 worst ground (peach) — body copy, ledes, muted text */
  --ash:   #686c76;   /* 4.70:1 worst ground (mist) — eyebrows, footnotes, labels  */
  --smoke: #7d818b;   /* 3.80:1 — LARGE type only (>=24px), never small text */

  /*
   * TEXT ON DARK SURFACES. The greys above are light-ground tokens; several
   * sections place a dark ink panel on the page and reused them inside it, where
   * mid-grey on near-black measures 3.4:1. These are the dark-surface equivalents
   * and are the ONLY muted colours permitted inside an ink panel.
   */
  --on-dark:        color-mix(in srgb, var(--paper) 92%, transparent);  /* body on ink   */
  --on-dark-muted:  color-mix(in srgb, var(--paper) 66%, transparent);  /* labels, ~7:1  */
  --on-dark-faint:  color-mix(in srgb, var(--paper) 48%, transparent);  /* LARGE type only */
  --peach: #fbe1d1;
  --sienna: #5d2a1a;
  --hair: #ececec;
  --hair-strong: rgba(23, 25, 28, 0.12);

  /* Warm tints for the gradient wash — same family as --peach, never used as text */
  --wash-1: #ffd9c2;
  --wash-2: #ffe9d6;
  --wash-3: #f0e2f2;
  --wash-4: #dfe6f5;

  /* — Type —————————————————————————————————————— */
  --serif: 'Source Serif 4', 'Iowan Old Style', Georgia, ui-serif, serif;
  --sans: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --t-caption: 15px;
  --t-body: 17px;
  --t-body-lg: 20px;
  --t-subhead: 22px;
  --t-h-sm: 26px;
  --t-h: 44px;
  --t-h-lg: 64px;
  --t-display: 90px;

  /* Tracking tightens as size grows — the typographic signature of the system */
  --tr-display: -0.025em;
  --tr-h-lg: -0.015em;
  --tr-h: -0.015em;
  --tr-h-sm: -0.009em;
  --tr-body-lg: -0.009em;

  /* — Space (4px base) ————————————————————————— */
  --s4: 4px;   --s8: 8px;   --s12: 12px; --s16: 16px; --s20: 20px;
  --s24: 24px; --s28: 28px; --s32: 32px; --s40: 40px; --s48: 48px;
  --s64: 64px; --s80: 80px; --s96: 96px; --s128: 128px; --s160: 160px;

  --nav-h: 76px;
  --page: 1200px;
  --gutter: 32px;

  /*
   * THREE SECTION RHYTHMS, AND ONLY THREE.
   *
   * Nineteen section files used to set their own band height, and they split
   * into two systems: multipliers of --section-y (0.66, 0.82, 1.2, 1.7 …) and
   * fixed pixels (104, 112, 136, 176 …). The two agree at exactly one viewport
   * width and separate everywhere else, so the page's vertical beat changed
   * with the window. Every band now picks one of these and nothing derives its
   * own.
   */
  --section-y-tight: 64px;   /* a strip: a logo rail, a short ledger */
  --section-y: 96px;         /* the normal band — most of the site */
  --section-y-loose: 128px;  /* a stage: the closing band, a tall drawing */

  /*
   * ONE HERO OPENING for all eight pages. The nav is sticky and 76px tall and
   * every hero is pulled up under it, so this figure INCLUDES the nav band:
   * 148 is 72px of visible air above the first mark, on every page. It used to
   * run 148 / 172 / 228 / 244 / 252 across eight heroes that share one nav.
   */
  --hero-y: 148px;

  /* One eyebrow, one gap under it. Seventeen instances used to set thirteen. */
  --eyebrow-gap: var(--s24);

  /* — Shape ——————————————————————————————————— */
  --r-card: 24px;
  --r-elevated: 20px;
  --r-input: 16px;
  --r-small: 16px;
  --r-pill: 9999px;

  /* — Drawings ————————————————————————————————
   * TWO sizes for the whole site, and no third. A set of drawings at six
   * different sizes is size used as hierarchy, which _src/ILLUSTRATION.md
   * items 3 and 7 forbid: a terminal and a printer are comparable objects and
   * must be drawn comparably. `card` is the mark that sits inside a card in a
   * grid; `feature` is the one drawing a section is built around. Both are
   * CEILINGS — `.illo--card` / `.illo--feature` pair them with width:100%, so a
   * narrow column still fits its drawing without inventing a third size.
   */
  --illo-card: 250px;
  --illo-feature: 500px;

  /* Only floating product artifacts earn elevation. Content cards stay flat. */
  --sh-artifact: 0 0 0 1px rgba(4, 23, 43, 0.05), 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
  --sh-overlay: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 8px 40px 0 rgba(0, 0, 0, 0.1);
  --sh-pop: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 24px 0 rgba(0, 0, 0, 0.08);

  /* — Motion ——————————————————————————————————— */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 160ms;
  --dur: 320ms;
  --dur-slow: 720ms;
}

/* The three rhythms and the hero opening ramp together, so the ratios between
   them hold at every width and no section has to re-tune itself. */
@media (max-width: 1080px) {
  :root { --t-display: 68px; --t-h-lg: 48px; --t-h: 36px; --gutter: 28px;
          --section-y-tight: 56px; --section-y: 80px; --section-y-loose: 104px;
          --hero-y: 124px; }
}
@media (max-width: 720px) {
  :root { --t-display: 44px; --t-h-lg: 34px; --t-h: 28px; --t-h-sm: 22px;
          --t-body-lg: 18px; --gutter: 20px; --r-card: 20px;
          --section-y-tight: 40px; --section-y: 64px; --section-y-loose: 80px;
          --hero-y: 104px; }
}

/* ===== 10-base.css ===== */
/* Reset + page substrate: the grain and the gradient wash live here. */
*, *::before, *::after { box-sizing: border-box; }
/*
 * `overflow-x: clip` on the ROOT, not `hidden` on body alone.
 * Sections intentionally crop product cards past the viewport edge; with only
 * body clipping, the document still grew (measured 1510px against a 1440px
 * viewport) and shipped a horizontal scrollbar. `clip` contains it WITHOUT
 * creating a scroll container, so the sticky nav keeps working — `hidden` would
 * silently break it.
 */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.35;
  font-weight: 400;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

h1, h2, h3, h4, p, figure, blockquote { margin: 0; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

/*
 * THE GRAIN. A fractal-noise tile at low opacity in `overlay` blend, fixed to the
 * viewport so it never scrolls against the content. This is the single largest
 * contributor to the reference's "printed paper" quality and it is absent from
 * every written description of the system.
 */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  /*
   * `multiply`, not `overlay`. The noise tile is opaque-black-or-transparent, and
   * overlay leaves any near-white base untouched — the grain was mathematically
   * invisible across every light section. Multiply darkens the speckle instead,
   * so the texture reads on paper AND on the warm wash.
   */
  opacity: 0.13;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.91' numOctaves='2' seed='7' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='discrete' tableValues='0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
@media (prefers-reduced-motion: no-preference) { body::after { will-change: opacity; } }

/* Layout primitives.
   ONE page rail, and every headline block on the site sits on it. There used to
   be a second, wider container (`.wrap-wide`, 1400) used by three sections; at
   1440 it put their headlines on the 32px page gutter while their neighbours
   held 120, an 88px jump between consecutive sections. Full bleed is still
   legal — a drawing, a rule, a background band — but it is done per element,
   never by moving a headline off the rail. */
.wrap { width: min(var(--page), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: var(--section-y); position: relative; }
.section--fog { background: var(--fog); }
.section--mist { background: var(--mist); }

/* Type primitives */
.display, .h-lg, .h, .h-sm-serif {
  font-family: var(--serif);
  font-weight: 400;
  font-optical-sizing: auto;
  text-wrap: balance;
  /*
   * THE SIDEBEARING CORRECTION, ONCE, FOR THE WHOLE SITE.
   *
   * A serif cap set flush to a rail reads as indented: the stem sits inside the
   * glyph's left sidebearing, while the sans eyebrow above it and the sans lede
   * below it start on their own ink. Pulling the block back a hair of its own
   * size puts the STEM on the rail, and stated in em it re-derives itself at
   * every step of the type ramp instead of needing a value per breakpoint.
   * Measured on Source Serif 4: cap B, lowercase b and the italic a all land
   * within 1px of each other at -0.026em.
   *
   * This lived in hardware-hero.css as a private rule, bundled with a 64px
   * "hang" that pulled that one title to x=54 while its own eyebrow held 120.
   * The hang is gone; the correction is shared. Three more sections carried
   * near-duplicates of it (-0.02, -0.023, -0.03) and now inherit this one.
   *
   * A CENTRED serif block must switch it off — see .prh-title in pricing-hero —
   * because there the margin moves the centre rather than the left edge.
   */
  margin-left: -0.026em;
}
.display { font-size: var(--t-display); line-height: 1.06; letter-spacing: var(--tr-display); }
.h-lg    { font-size: var(--t-h-lg);   line-height: 1.1;  letter-spacing: var(--tr-h-lg); }
.h       { font-size: var(--t-h);      line-height: 1.16; letter-spacing: var(--tr-h); }
.h-sm-serif { font-size: var(--t-h-sm); line-height: 1.28; letter-spacing: var(--tr-h-sm); }
.display em, .h-lg em, .h em { font-style: italic; }

/*
 * THE ONE FIT-TO-WIDTH OPT-IN, AND THE ONLY ONE.
 *
 * A headline whose authored line genuinely cannot hold the phone column takes
 * this class on top of its scale class instead of inventing a divisor of its
 * own. Six inner heroes each invented one, and at 390px they rendered the same
 * rank at 31.8 / 41 / 41.6 / 42 / 44 and 48px — a 1.8x spread across six
 * elements that are the same thing.
 *
 * It can only ever make type SMALLER than the ramp: it is a min() against the
 * token, so it cannot be used to promote a headline past the class it wears.
 * The divisor is taken from the widest binding line on the site — "When
 * something breaks," which Source Serif sets at 10.47em once the optical axis
 * has opened the face up at small sizes — so one number covers every candidate.
 * Above about 414px of viewport it stops binding entirely and the token ramp is
 * the only thing sizing the line.
 */
.h-fit { font-size: min(var(--t-h-lg), calc((100vw - var(--gutter) * 2) / 11)); }

.h-sm { font-family: var(--sans); font-size: var(--t-h-sm); font-weight: 450;
        line-height: 1.22; letter-spacing: var(--tr-h-sm); }
.lede { font-size: var(--t-body-lg); line-height: 1.45; letter-spacing: var(--tr-body-lg);
        color: var(--slate); text-wrap: pretty; }
.body { font-size: 16px; line-height: 1.55; color: var(--slate); text-wrap: pretty; }
.caption { font-size: var(--t-caption); line-height: 1.5; color: var(--slate); }

/*
 * Ghost typographic tag — groups without visual weight. Never a badge.
 *
 * ONE COMPONENT: one size, one weight, one colour, and one gap to whatever it
 * labels. The gap used to take thirteen values across seventeen instances (2,
 * 16, 19, 24, 26, 28, 32, 38, 42, 45, 57 …) — even the four page-label eyebrows
 * that share the same hero pattern disagreed — and the colour ran --ash on 29
 * of them, --smoke on four, and full --ink at weight 500 on one.
 *
 * Where an eyebrow is a grid or flex participant whose spacing the container
 * already owns, it sets `margin-bottom: 0` and says so. That is the only legal
 * override.
 */
.eyebrow {
  font-size: 14px;
  font-weight: 400;
  color: var(--ash);
  letter-spacing: 0;
  margin-bottom: var(--eyebrow-gap);
}

.tnum { font-variant-numeric: tabular-nums; }
.muted { color: var(--slate); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
:where(a, button, input, [tabindex]):focus-visible {
  outline: 2px solid var(--ink); outline-offset: 3px; border-radius: 4px;
}

/*
 * A hero that carries a wash starts UNDER the transparent nav, so the wash paints
 * behind the logo and links instead of leaving a bald white strip across the top.
 *
 * THE OPENING IS SET HERE AND NOWHERE ELSE. Eight heroes used to compute their
 * own top padding off --section-y plus a private number — 148 / 172 / 228 / 244
 * / 252, a 104px spread on eight components that share one 76px nav — and eight
 * more numbers for the bottom (96 … 236). --hero-y includes the nav band, so
 * every page shows the same 72px of air above its first mark, and the hero
 * closes on the loose rhythm like any other stage.
 */
main > .section:first-child.has-wash {
  margin-top: calc(var(--nav-h) * -1);
  padding-top: var(--hero-y);
  padding-bottom: var(--section-y-loose);
}

/* A whisper of warmth for sections that would otherwise be an undifferentiated slab. */
.section--tint { background:
  radial-gradient(120% 80% at 50% 0%, rgba(251, 225, 209, 0.30) 0%, rgba(251, 225, 209, 0) 60%),
  var(--paper); }
.section--tint-b { background:
  radial-gradient(120% 80% at 50% 100%, rgba(251, 225, 209, 0.26) 0%, rgba(251, 225, 209, 0) 60%),
  var(--paper); }

/* ===== 20-components.css ===== */
/* ————————————————————————————————————————————————
   The gradient wash. Original composition in the brand's warm family — four
   soft radial blooms over paper. Sections opt in with .has-wash.
   ———————————————————————————————————————————————— */
.has-wash { position: relative; isolation: isolate; }
.has-wash > .wash {
  position: absolute; inset: -10% -5% 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(58% 44% at 74% 30%, var(--wash-1) 0%, rgba(255, 217, 194, 0) 62%),
    radial-gradient(46% 38% at 22% 46%, var(--wash-3) 0%, rgba(240, 226, 242, 0) 66%),
    radial-gradient(52% 40% at 46% 72%, var(--wash-2) 0%, rgba(255, 233, 214, 0) 68%),
    radial-gradient(40% 34% at 90% 74%, var(--wash-4) 0%, rgba(223, 230, 245, 0) 70%);
  filter: blur(8px) saturate(112%);
}
/* Fade the wash into paper at the seam so sections never end on a hard edge. */
.has-wash > .wash::after {
  content: ''; position: absolute; inset-inline: 0; bottom: 0; height: 200px;
  background: linear-gradient(to top, var(--paper), rgba(255, 255, 255, 0));
}

/* ————————————————————————————————————————————————
   Pills. Filled and ghost share geometry so they sit as a matched pair.
   ———————————————————————————————————————————————— */
.pill, .ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 48px; padding-inline: 26px; border-radius: var(--r-pill);
  font-size: 16px; font-weight: 450; letter-spacing: -0.005em;
  white-space: nowrap; cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.pill { background: var(--ink); color: var(--paper); border: 1px solid var(--ink); }
.pill:hover { background: #2b2e33; border-color: #2b2e33; }
.ghost { background: transparent; color: var(--ink); border: 1px solid var(--ink); }
.ghost:hover { background: var(--ink); color: var(--paper); }
.pill:active, .ghost:active { transform: translateY(1px); }
.pill--sm, .ghost--sm { height: 42px; padding-inline: 20px; font-size: 15px; }

/* Lowest-emphasis link: the arrow carries the affordance, not an underline. */
.alink {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 16px; font-weight: 450; color: var(--ink);
}
.alink svg { transition: transform var(--dur) var(--ease-out); }
.alink:hover svg { transform: translateX(4px); }
.alink:hover span { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ————————————————————————————————————————————————
   Surfaces
   ———————————————————————————————————————————————— */
/*
 * ONE CARD, TWO VARIANTS — and nothing else. The card is the most repeated
 * object on the site, and it had drifted into six grounds doing the same job:
 * mist, white-with-a-hairline, transparent-with-a-hairline, white-no-border,
 * white-with-a-top-only-radius and white-on-a-heavier-hairline. Two of them
 * shipped on ONE page, three sections apart, on the same six-card isometric
 * grid. Sections must not restate background, border, radius or padding here.
 *
 *   .card         mist, no border — the default, and what a grid of drawings
 *                 sits on, on paper and on fog alike.
 *   .card--paper  white and a hairline — reserved for the one case mist cannot
 *                 do: a card that has to lift off a filled ground. It is down
 *                 to a single user (customers-more); nothing else may take it,
 *                 and no section may invent a third.
 */
/* --illo-ground is the surface a drawing's occlusion silhouette is painted in.
   It is declared beside the background it has to match, so the two can never
   drift apart; see the illustration block below. */
.card { background: var(--mist); --illo-ground: var(--mist); border-radius: var(--r-card); padding: var(--s32); }
.card--paper { background: var(--raised); --illo-ground: var(--raised); border: 1px solid var(--hair); }
.card__title { font-size: var(--t-body-lg); font-weight: 500; letter-spacing: -0.01em; margin-bottom: 10px; }
/*
 * The ONE permitted louder card title, for the lead of a grid. Same family and
 * same weight as its siblings — a lead that changes typeface puts two families
 * at one rank inside a single grid, which is what three sections were doing.
 */
.card__title--lead { font-size: var(--t-h-sm); letter-spacing: var(--tr-h-sm); line-height: 1.22; }
.card__body { font-size: 16px; line-height: 1.55; color: var(--slate); }

/* Rationed to one per page. Warm ink on warm paper — never on a tinted section. */
.card--peach { background: var(--peach); color: var(--sienna); --illo-ground: var(--peach); }
.card--peach .card__title, .card--peach .card__body, .card--peach p { color: var(--sienna); }

/* The only elements with visible elevation. */
.artifact {
  background: var(--raised); border-radius: var(--r-elevated); box-shadow: var(--sh-artifact);
}

.rule { height: 1px; background: var(--hair); border: 0; margin: 0; }

/* ————————————————————————————————————————————————
   Nav
   ———————————————————————————————————————————————— */
.nav {
  position: sticky; top: 0; z-index: 100; height: 76px; display: flex; align-items: center;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out),
              backdrop-filter var(--dur) var(--ease-out);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: var(--hair);
}
/*
 * NO `width: 100%` HERE. .nav__inner also carries .wrap, and an equal-specificity
 * `width` declared later overrides the 1200px column .wrap exists to set — which
 * pushed the logo and the CTA hard against the viewport edges and left the nav
 * links misaligned against every other element on the page. Most visible on wide
 * displays, but it was wrong at every width.
 */
.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.nav__logo { display: inline-flex; align-items: center; gap: 9px; flex: 0 0 auto; white-space: nowrap;
             font-family: var(--serif); font-size: 21px; letter-spacing: -0.015em; }
.nav__logo em { font-style: italic; }
.nav__links { display: flex; align-items: center; gap: 34px; }
.nav__links a { font-size: 16px; font-weight: 400; color: var(--ink); position: relative; padding-block: 4px; }
.nav__links a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--ink); transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}
.nav__links a:hover::after, .nav__links a.is-active::after { transform: scaleX(1); }
.nav__cta { display: flex; align-items: center; gap: 22px; }
/* A text link in the nav is still a tap target: it was 21px tall, under the 24px
   floor and well under the 44px comfortable size on touch. */
.nav__cta .alink { min-height: 44px; }
.nav__burger { display: none; width: 44px; height: 44px; align-items: center; justify-content: center;
               background: none; border: 0; cursor: pointer; margin-right: -10px; }

@media (max-width: 940px) {
  .nav__links, .nav__cta .alink, .nav__cta .ghost { display: none; }
  .nav__burger { display: inline-flex; }
}
@media (max-width: 360px) {
  .nav__cta > .pill { display: none; }
}

.navdrawer {
  position: fixed; inset: 0; z-index: 200; background: var(--paper);
  display: flex; flex-direction: column; padding: 20px var(--gutter) 40px;
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out), visibility var(--dur);
}
.navdrawer.is-open { opacity: 1; visibility: visible; transform: none; }
.navdrawer__top { display: flex; align-items: center; justify-content: space-between; height: 56px; }
.navdrawer__links { display: flex; flex-direction: column; gap: 4px; margin-top: 32px; }
.navdrawer__links a { font-family: var(--serif); font-size: 34px; line-height: 1.5; letter-spacing: -0.015em; }
.navdrawer__foot { margin-top: auto; display: flex; flex-direction: column; gap: 12px; }
.navdrawer__foot .pill, .navdrawer__foot .ghost { width: 100%; }

/* ————————————————————————————————————————————————
   Footer
   ———————————————————————————————————————————————— */
.footer { border-top: 1px solid var(--hair); padding-block: 72px 56px; background: var(--paper); }
.footer__grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 48px; }
.footer__brand p { margin-top: 14px; max-width: 260px; font-size: 15px; line-height: 1.55; color: var(--slate); }
.footer__col .footer__coltitle { font-size: 14px; font-weight: 450; color: var(--ash); margin-bottom: 18px; }
.footer__col a { display: block; font-size: 15px; line-height: 1; padding-block: 9px; color: var(--ink); }
.footer__col a:hover { color: var(--slate); }
.footer__base { display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
                margin-top: 64px; padding-top: 28px; border-top: 1px solid var(--hair);
                font-size: 14px; color: var(--ash); }
@media (max-width: 860px) {
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 40px 24px; }
  .footer__brand { grid-column: 1 / -1; }
}

/* ————————————————————————————————————————————————
   THE ILLUSTRATION SYSTEM
   Every drawing on the site must obey these, or the page reads as clip-art
   assembled by six different people — which is exactly what reviewers found:
   "five different conventions" across six cards in one section.
   ———————————————————————————————————————————————— */
.illo {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
  color: var(--ink);
  /* Strokes must survive the warm ground. A floor plan drawn at low contrast was
     measured as "effectively does not exist" — opacity belongs on the wrapper,
     never on individual strokes. */
  opacity: 0.78;
}
.illo--quiet { opacity: 0.52; }
.card--peach .illo,
.illo--sienna { color: var(--sienna); }
.illo--invert { color: var(--raised); }

/* One stroke weight for the whole site. Anything thinner disappears on paper;
   anything heavier reads as an icon rather than a drawing. */
.illo [stroke],
.illo path, .illo line, .illo circle, .illo rect, .illo ellipse, .illo polyline, .illo polygon {
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  vector-effect: non-scaling-stroke;   /* weight stays 1.4 at any scale */
}
/* The single permitted fill: a solid accent mark, used sparingly for emphasis. */
.illo .illo-fill { fill: currentColor; stroke: none; }
/* Construction lines — hidden faces, guides — sit back without changing weight. */
.illo .illo-back { opacity: 0.34; }

/* ————————————————————————————————————————————————
   HIDDEN-LINE REMOVAL — and it lives HERE, not in a section file.

   ILLUSTRATION.md item 5 makes occlusion mandatory: where one object sits in
   front of another, the object behind must BREAK, or the drawing is an x-ray.
   The tool that does it is an opaque silhouette painted in whatever surface the
   drawing stands on, laid down immediately before the object it belongs to.

   It used to be declared locally, in two section files out of thirteen, and
   that is most of why eleven sections carried no occlusion at all: an author
   who copied class="illo-mask" anywhere else got `fill: none` from the generic
   rule above and the drawing silently rendered as an x-ray. No error, no
   missing style — just a worse drawing. Declared globally, the class works
   wherever it is written.

   The surface comes from --illo-ground, set once per card beside its own
   background (.card / .card--paper / .card--peach above). A drawing standing on
   bare paper needs to set nothing; the fallback is the page.
   ———————————————————————————————————————————————— */
.illo .illo-mask { fill: var(--illo-ground, var(--paper)); stroke: none; }

/* ————————————————————————————————————————————————
   TWO SIZES, AND NO THIRD.

   Measured across the site, .illo boxes ran from 45px to 1102px — a 24x range
   under one class, which makes the class mean nothing, and inside a grid of
   peers makes size read as importance (ILLUSTRATION.md items 3 and 7).
   A drawing is now either a card mark or a section's feature. Both are
   CEILINGS paired with width:100%, so a narrow column shrinks its drawing
   instead of earning a size of its own.
   ———————————————————————————————————————————————— */
.illo--card { width: 100%; max-width: var(--illo-card); }
.illo--feature { width: 100%; max-width: var(--illo-feature); }

/* ————————————————————————————————————————————————
   BLEED STAGE — for absolutely-positioned decoration around a content column.
   `position:absolute; inset:0` on a full-bleed section anchors children to the
   VIEWPORT, so on a wide display the floating cards fly out to the edges and
   lose all relationship to the headline they are meant to frame. This bounds the
   layer to the content column plus a fixed bleed, centred, so the composition
   holds at any width and only ever crops by --bleed.
   ———————————————————————————————————————————————— */
.stage {
  position: absolute;
  top: 0; bottom: 0; left: 0; right: 0;
  width: min(100%, calc(var(--page) + var(--bleed, 240px) * 2));
  margin-inline: auto;
  pointer-events: none;
}

/* ===== 30-motion.css ===== */
/*
 * Motion primitives. Everything is opt-in via a data attribute so a section
 * author never writes keyframes — and everything collapses to "already visible"
 * under prefers-reduced-motion, which is the accessible default, not an afterthought.
 */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* Headline reveal: lines rise from a clipped baseline, staggered. */
[data-reveal-lines] .line-mask { display: block; overflow: hidden; }
[data-reveal-lines] .line-mask > span {
  display: block;
  transform: translateY(105%);
  transition: transform 900ms var(--ease-out);
  transition-delay: var(--line-delay, 0ms);
}
[data-reveal-lines].is-in .line-mask > span { transform: none; }

/* Floating artifacts drift in from their resting offset. */
[data-float] {
  opacity: 0;
  transform: translate3d(var(--float-x, 0), var(--float-y, 26px), 0) scale(0.985);
  transition: opacity 1000ms var(--ease-out), transform 1000ms var(--ease-out);
  transition-delay: var(--float-delay, 0ms);
}
[data-float].is-in { opacity: 1; transform: translate3d(0, 0, 0) scale(1); }

/* Idle bob for hero artifacts, once they have landed. */
@keyframes lp-bob {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -7px, 0); }
}
[data-float].is-in[data-bob] {
  animation: lp-bob var(--bob-dur, 7s) var(--ease-in-out) infinite;
  animation-delay: var(--bob-delay, 0s);
}

/* Counters and bars */
[data-count] { font-variant-numeric: tabular-nums; }
[data-bar] { transform: scaleX(0); transform-origin: left; transition: transform 1100ms var(--ease-out); }
[data-bar].is-in { transform: scaleX(1); }

/* Drawn SVG strokes */
[data-draw] {
  stroke-dasharray: var(--len, 1000);
  stroke-dashoffset: var(--len, 1000);
  transition: stroke-dashoffset 1600ms var(--ease-out);
}
[data-draw].is-in { stroke-dashoffset: 0; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], [data-float], [data-bar], [data-draw],
  [data-reveal-lines] .line-mask > span {
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
    transition: none !important;
    animation: none !important;
  }
}

/* ===== section:support-hero ===== */
/* ============================================================================
   support-hero — one rule across the frame, broken by the answer.

   Anchored hard to the left rail. The only offset element is the italic clause; the only thing touching either
   frame edge is a 1px hairline, in two segments that the phrase interrupts.
   Nothing here is a slab and nothing is a card: the section's mass is the serif
   headline and nothing else competes with it.
   ============================================================================ */

.sec-support-hero {
  /* Both ends of the stage come from the shared hero rule in 10-base.css.
     This file used to add 72px on top and 24 underneath, which made it the
     joint-tallest opening on the site. */

  /*
   * CLIP THE X AXIS ONLY, as every other hero on this site already does — and
   * this file was the ONE that did not. `.has-wash > .wash` is inset -5% on
   * both flanks, so on a 1440 frame it runs -72 → 1512, and an element
   * overhanging to the RIGHT still counts toward scrollWidth even under the
   * root's own overflow-x: clip. Measured, support.html was the only page of
   * the eight whose body reported 1512 instead of 1440, and a full-page capture
   * of it came back 1512 wide with 72px of bald paper past the wash's right
   * edge — the root clip stops the page SCROLLING, it does not stop a capture
   * measuring the overflow.
   *
   * Y stays visible so the wash's 200px bottom fade is never guillotined into a
   * hard grey band at the seam with the section below. `clip` + `visible` is
   * the one legal mixed pair; `hidden` here would make the section a scroll
   * container and break the sticky nav.
   */
  overflow-x: clip;

  /*
   * THE STEP, AS A LENGTH THE PILL ROW CAN ALSO USE.
   *
   * The headline keeps its indent in `em` (see --sph-indent below) because
   * .h-fit may shrink the type under 414px and the step has to follow it. The
   * pill row cannot share that: `em` under .sph-ways resolves against 16px body
   * type, not the 64px headline, so 2.5em there would be a 40px nudge and not
   * the section's step at all. This is the same figure stated in px per band.
   */
  --sph-hang: 160px;   /* 2.5 × 64 */
}

/* ---------------------------------------------------------------------------
   THE HEADLINE
   --------------------------------------------------------------------------- */

.sec-support-hero .sph-title {
  position: relative;

  /*
   * THE STEP. 2.5em of the headline's own size, so the indent scales with the
   * type instead of being a pixel constant that drifts at every breakpoint.
   *
   * At the 64px ceiling that is 160px, and the figure is chosen against the
   * measured ink: line one runs 630px from the rail, line two 160 + 423, so the
   * two close 47px apart. Enough that the step reads as displacement rather than
   * a soft rag, and short of the ~190px that would bring the right edges flush —
   * a flush pair has to be exact to look intended, and at this size a 10px miss
   * would read as a mistake where a 47px step reads as a decision.
   */
  --sph-indent: 2.5em;
}

/*
 * OPTICAL OVERHANG ON THE W.
 *
 * A diagonal cap set at 3.5× the body size needs to start left of the rail or it
 * reads as inset next to the flat-sided "S" of the eyebrow beneath... above it.
 * Measured before this line, the 64px W apex sat at x=121 against an eyebrow S at
 * 120.5 and a pill edge at 120 — no correction at all.
 *
 * MARGIN, NOT text-indent, AND THAT IS LOAD-BEARING. .line-mask carries
 * `overflow: hidden` (30-motion.css) to clip the reveal, and it clips both axes:
 * a negative text-indent would push the apex outside its own mask and the clip
 * would shave the 1.28px straight back off. Moving the mask box itself takes the
 * clip with it. Width stays auto, so the right edge does not move and nothing
 * overflows the wrap.
 */
.sec-support-hero .sph-l1 { margin-left: -0.02em; }

.sec-support-hero .sph-row2 {
  display: flex;
  /* Bottom edges together, so both the mask and the outbound rule measure their
     offsets from the same horizontal — the line box's bottom, which is also the
     h1's bottom and therefore the datum the inbound segment is positioned from. */
  align-items: flex-end;
}

.sec-support-hero .sph-l2 {
  flex: 0 0 auto;
  padding-left: var(--sph-indent);
}

/* ---------------------------------------------------------------------------
   THE RULE

   THE HEIGHT IS THE BASELINE, AND THE FIGURE IS MEASURED, NOT GUESSED.
   Source Serif 4 is ascent 1.036em / descent 0.335em, so its content area is
   1.371em — TALLER than 1em — and at line-height 1.1 the half-leading is
   NEGATIVE: (1.1 − 1.371) / 2 = −0.1355em. The baseline therefore sits
   1.1 − (1.036 − 0.1355) = 0.1995em off the bottom of the line box, which is
   where both segments sit.

   An earlier pass put them on the x-height midline (0.437em by the same
   arithmetic) and it was wrong twice over: a rule that resumes on both sides of
   a phrase at mid-height reads as a strikethrough, and striking through "a
   person answers" says the opposite of the headline. The very first pass used
   0.53em, from the textbook (1 − line-height) / 2 half-leading that only holds
   for a face whose content area is exactly 1em, and sat a visible 6px high.

   0.34em of clearance at each terminal. The italic's left sidebearing widens the
   inbound gap a little and the full stop's right sidebearing widens the outbound
   one, so the two read as roughly equal on the page rather than in the box.
   --------------------------------------------------------------------------- */

.sec-support-hero .sph-lead {
  height: 1px;
  background: var(--hair-strong);
  transform-origin: left center;
}

/*
 * INBOUND. `50% - 50vw` resolves 50% against this h1 (which fills the page
 * measure) and 50vw against the screen, so the left end lands exactly on the
 * viewport edge at any width and the rule always starts hard off frame — the
 * one element in the section that crosses a boundary.
 */
.sec-support-hero .sph-lead--in {
  position: absolute;
  left: calc(50% - 50vw);
  bottom: 0.1995em;
  width: calc(50vw - 50% + var(--sph-indent) - 0.34em);
  /* Lands after the italic has risen: 150ms line delay + the rise, then this. */
  transition-delay: 420ms;
}

/*
 * OUTBOUND. A flex item, so it begins wherever the italic ends rather than at a
 * constant that a font fallback would invalidate.
 *
 * It ends on the viewport's right edge, and the negative margin is how — not
 * 100vw. A fixed `flex: 0 0 100vw` starting ~700px in genuinely widened the
 * document to 2165px. Sized instead as `flex: 1 1 auto` with
 * `margin-right: calc(50% - 50vw)` — 50% against the row's 1200px measure, 50vw
 * against the screen — the free space handed to the item is exactly the outer
 * margin, so its right edge lands ON the frame at every width and nothing
 * overflows anything.
 *
 * It grows away from the phrase on a later delay than the inbound segment, so
 * the line reads as travelling through rather than as two rules appearing.
 */
.sec-support-hero .sph-lead--out {
  flex: 1 1 auto;
  min-width: 0;
  margin-left: 0.34em;
  margin-right: calc(50% - 50vw);
  margin-bottom: 0.1995em;
  transition-delay: 620ms;
}

/* ---------------------------------------------------------------------------
   THE PARAGRAPH
   --------------------------------------------------------------------------- */

/*
 * 600, not the 640 ceiling the brief allows, and the 40px buys a better rag.
 * Measured, 640 breaks the paragraph 65/35 — "…including evenings —" against
 * "because a till fails during service." — with the em dash left as the last
 * mark on line one. 620 moves the dash to the head of line two, which is worse:
 * a dash may end a line, it should not begin one. At 600 the break falls after
 * "including", the two lines run 55/45, and the dash sits inside the clause it
 * belongs to. `text-wrap: pretty` does not do this on its own; it balances the
 * last line and has no opinion about where a dash lands.
 *
 * THE MEASURE IS STEPPED WITH THE TYPE RAMP, AND THAT IS NOT DECORATION.
 * The headline's ink is fixed per band — 630px at the 64px ceiling, 487 at 48,
 * 356 at 34 — while a single 600px cap on the paragraph does not move at all.
 * Left alone it inverted the hierarchy across a 600px-wide band of viewports:
 * measured at 720, the headline set 356px of serif and the LEDE set 569px, so
 * the widest ink in the frame was the grey supporting paragraph and the eye
 * went to it first. Each step below caps the paragraph at or just under its own
 * band's headline width, so the serif is always the widest mark in the section
 * and the two blocks close on a near-shared right edge instead of crossing.
 */
.sec-support-hero .sph-sub {
  max-width: 600px;
  /*
   * 38, not the 30 this used to run. The RULE sits 13.7px above the h1's
   * bottom edge — it is on the baseline of line two, not under its descenders —
   * so a 30px margin left only 44px of air between the section's one structural
   * line and the cap line of the paragraph under it. At that distance the rule
   * read as the paragraph's ceiling rather than as the line the headline stands
   * on. 38 puts 52px under it, which is the same clearance the eyebrow gets
   * above the headline, and the rule reads as the spine of the section again.
   */
  margin-top: 38px;
}

/* ---------------------------------------------------------------------------
   THE THREE WAYS IN

   One geometry — matched height, matched padding, matched icon box — and ONE
   difference in weight: WhatsApp is filled, the other two are hairline. See the
   note in the markup for why "same rank, so identical treatment" was wrong.
   --------------------------------------------------------------------------- */

.sec-support-hero .sph-ways {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s12);
  margin-top: 54px;
  /* Hangs off the headline's step, so the row's left edge lands on the same
     vertical as the break in the rule and the start of the italic clause. */
  margin-left: var(--sph-hang);
}

.sec-support-hero .sph-way {
  gap: 10px;
  font-weight: 450;
}

/*
 * DRAWN IN THE SECTION'S OWN LINE.
 *
 * .ghost ships `border: 1px solid var(--ink)` — right for a page whose hairlines
 * are --hair at #ececec, wrong here, where the only structural mark in the frame
 * is --hair-strong at twelve percent. Left inherited it made these two the
 * darkest line in the section, above the rule the entire headline is built on.
 * Overridden at (0,3,0) so it beats .ghost without !important.
 *
 * Hover still inverts to the full ink fill the component defines — the border
 * comes back to --ink with it, so the filled state keeps a crisp edge instead of
 * bleeding a whisper-grey ring around a black pill.
 */
.sec-support-hero .ghost.sph-way { border-color: var(--hair-strong); }
.sec-support-hero .ghost.sph-way:hover,
.sec-support-hero .ghost.sph-way:focus-visible { border-color: var(--ink); }

.sec-support-hero .sph-way svg {
  width: 16px;
  height: 16px;
  flex: none;
  /* Full currentColor: paper inside the filled pill, ink inside the hairline
     ones, and no third value between border and label in either. */
}

/* The 48px band. Headline ink 487px, so the paragraph stops at 480. */
@media (max-width: 1080px) {
  .sec-support-hero { --sph-hang: 120px; }   /* 2.5 × 48 */
  .sec-support-hero .sph-sub { max-width: 480px; }
}

/* ===========================================================================
   NARROW — 900px and down.

   The step survives but shortens. The SIZE is not this section's to set: the
   h1 carries .h-fit (see 10-base), which is the site's ONE fit-to-width opt-in
   and the only reason this headline may be smaller than the ramp — "When
   something breaks," is the widest authored line on the site and it is 6px too
   wide for a 390px column at the ramp's 34px, so line one wrapped and the
   two-line step became three lines. The helper takes it to 31.8px there and
   stops binding above about 414px of viewport; nothing else about the size is
   local. The indent stays in em, so the step scales with whatever it lands on.
   =========================================================================== */

@media (max-width: 900px) {
  .sec-support-hero { --sph-hang: 77px; }    /* 1.6 × 48 */
  .sec-support-hero .sph-title { --sph-indent: 1.6em; }
  .sec-support-hero .sph-sub { margin-top: 32px; }
  .sec-support-hero .sph-ways { margin-top: 44px; }
}

/* The 34px band, where the ramp also drops the lede to 18px. Headline ink is
   356px here, so the paragraph stops at 360 — a hair over, which reads as two
   blocks closing on one edge rather than as one sticking out past the other. */
@media (max-width: 720px) {
  .sec-support-hero { --sph-hang: 54px; }    /* 1.6 × 34 */
  .sec-support-hero .sph-sub { max-width: 360px; }
}

@media (max-width: 560px) {

  /*
   * THE ROW BECOMES A COLUMN, AND THE STEP GOES BACK TO ZERO.
   *
   * This band used to wrap. Measured at 390, that gave a first row packed to
   * 353 of the 370px column and a second row holding one 76px pill at 22% full —
   * reflow, not layout: nobody chose either of those edges, the flex algorithm
   * did. A stub row is the one thing a three-item set cannot survive, because it
   * makes the last item look left over rather than offered.
   *
   * Stacked and shrink-to-fit — NOT full-width bars, which would read as a
   * navigation menu — the three hang off the one rail the whole section is
   * measured from, with the filled pill at the head. The step is dropped here
   * because at this width it is 54px against a 350px column: an indent that
   * large on a column that narrow stops reading as displacement and starts
   * reading as a margin error, and the stack has its own left edge to hold.
   */
  .sec-support-hero { --sph-hang: 0px; }
  .sec-support-hero .sph-way { height: 42px; padding-inline: 18px; font-size: 15px; }
  .sec-support-hero .sph-ways {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    margin-top: 38px;
  }

  /* 340, not the 34ch this used to run. `ch` tracks the font, not the headline,
     and at 480 it resolved to 379px against a 356px headline — the one width
     left where the grey paragraph was still the widest ink in the frame. Below
     about 400 the column is narrower than this anyway and takes over. */
  .sec-support-hero .sph-sub { max-width: 340px; }
}

/* ===== section:support-integrations ===== */
/* ============================================================================
   support-integrations — one card leads, and the two columns land on one line.

   The section's structure is one diagonal of air: a void top-right beside the
   header, the quilt of four cards leaning through the middle, a void
   bottom-left beside the closing line. Nothing crosses the frame — the two
   bands either side of this one already do, on the same edge — and nothing
   resolves onto the page's centre axis.

   WHAT CHANGED, AND WHY. The quilt used to be four cards at one ground, one
   size, one title rank and one internal anatomy, offset into two columns. Both
   the tops AND the bottoms drifted, so the offset read as drift rather than as
   intent, and with the H2 at 44px and the card titles, the sub and the close
   all at 20px there was nothing in the frame telling the eye where to begin.
   Three corrections, all structural:

     1. RANK. Payments leads — wider column, taller card, the louder title, the
        only line of copy under a title, and the only drawing in warm ink.
     2. THE BOTTOMS LOCK. The far column still drops a full --s96, but both
        columns now stretch to one row height, so the tops stagger and the
        bottoms land on a single y. That is what makes an offset read as a
        decision; two drifting edges read as a grid that failed to settle.
     3. FOUR RANKS OF TYPE, NOT ONE. 64px serif headline, 26px lead card title,
        22px card titles, 20px sub, and a 26px serif close with a true italic.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   HEAD — held to the left rail; the right of this band carries nothing, and
   that emptiness is the top of the section's diagonal. The rail is wide enough
   that the 64px line sets on two lines and still leaves ~380px of void, so the
   void is a proportion rather than the remainder of a short headline.
   --------------------------------------------------------------------------- */

.sec-support-integrations .si-head {
  max-width: 820px;
}

.sec-support-integrations .si-sub {
  margin-top: 22px;
  max-width: 640px;
}

/* ---------------------------------------------------------------------------
   THE FIELD

   Two flex columns rather than a grid of cells. In a grid the second row starts
   at one y in BOTH columns, so the interlock survives only until one card grows
   a chip row — and then three of four card tops line up and the quilt reads as
   a grid with a typo in it. Two columns with an offset cannot align at all.
   --------------------------------------------------------------------------- */

.sec-support-integrations .si-field {
  margin-top: 64px;
  display: grid;
  /* Unequal on purpose, and now the wider column is genuinely the lead's: 1.32
     against 1 puts Payments at ~660px beside ~500px peers, which is a ratio the
     eye reads instantly rather than the 1.16 nudge it used to be. */
  grid-template-columns: 1.32fr 1fr;
  gap: var(--s24);
  /*
   * STRETCH, NOT START. This is the whole of fix 2. `align-items: start` let
   * each column size to its own content, so the two columns ended 96px and
   * 130px apart and the lower half of the quilt had nothing catching either
   * edge. Stretched, both columns are exactly the row's height; the --s96
   * margin below takes that much off the far column's box, so the far column
   * STARTS 96px lower and both still FINISH on the same line.
   */
  align-items: stretch;
}

.sec-support-integrations .si-col {
  display: flex;
  flex-direction: column;
  gap: var(--s24);
}

/* The interlock. A full --s96 drop is far past anything that could read as a
   misalignment, so the two columns are unmistakably two columns rather than a
   grid that failed to settle. */
.sec-support-integrations .si-col--far {
  margin-top: var(--s96);
}

/* Shared card anatomy: title on top, drawing in the flexible middle band,
   hairline, list on the bottom edge. `flex: 1 1 auto` is what passes the
   column's stretch down to the cards — without it the cards keep their content
   height and the locked bottom becomes a gap under the last card instead. The
   middle band is the part that takes the slack, so a taller card grows air
   around its object rather than opening a hole under it. */
.sec-support-integrations .si-card {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
}

/*
 * TITLES. 22px, not the component's 20px: the sub, the close and these were all
 * at --t-body-lg, so a card title, the opening sentence and the section's
 * closing argument carried identical typographic weight and the section had one
 * rank below the H2 instead of three.
 */
.sec-support-integrations .si-card .card__title {
  font-size: var(--t-subhead);
  letter-spacing: -0.012em;
  line-height: 1.2;
  margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
   THE LEAD

   Four differences, and each one is a device the system already owns:
   the wider column (above), the extra height (flex-grow + a deeper art band),
   `.card__title--lead` — 20-components.css's ONE permitted louder card title,
   same family and weight as its siblings — and the body line. The fifth,
   `.illo--sienna`, is on the drawing in the HTML: warm ink, because the warm
   GROUND (`.card--peach`) is rationed to one surface per page, is owned by
   support-security below, and is barred from a tinted section like this one.
   Nothing here invents a ground, a colour or a third card variant.
   --------------------------------------------------------------------------- */

.sec-support-integrations .si-card--lead {
  /* The lead soaks the column's slack first, so any free height in the row
     lands on the card the eye is supposed to start on. */
  flex-grow: 1.6;
  /* The one padding override in the file, and it is the lead's — the same move
     home-barriers makes for its lead card. */
  padding: var(--s40);
}

.sec-support-integrations .si-card--lead .card__title {
  font-size: var(--t-h-sm);
  letter-spacing: var(--tr-h-sm);
  line-height: 1.22;
}

/* The only line of copy under a title in the set. Measure is short so it reads
   as a statement rather than as a paragraph the other cards are missing. */
.sec-support-integrations .si-body {
  margin-top: 10px;
  max-width: 30ch;
}

/*
 * THE RULE BETWEEN THE OBJECT AND ITS INDEX. Same value as the chip borders, so
 * each card carries one hairline weight and not two, and the chips read as a
 * list under a specimen rather than as loose type at the bottom of a box.
 */
.sec-support-integrations .si-art {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-block: 28px;
  border-bottom: 1px solid var(--hair-strong);
}

/*
 * The lead's specimen stands in more air than the peers' — the drawing itself is
 * the same size on all four (see below); only the plate it sits on is deeper.
 *
 * THE MIN-HEIGHT IS LOAD-BEARING, AND NOT ONLY FOR RANK. With every card at its
 * content height the two columns happened to sum to within a pixel of each
 * other, so the quilt's INTERIOR seam landed at y=813 on the left and y=814 on
 * the right: the bottoms locked, and then row two started on one line in both
 * columns, which is the grid this composition exists to avoid. Deepening the
 * lead's plate drives the row taller than the far column's content, the far
 * column's two cards share the slack, and the interior seams separate by ~60px
 * while the outer bottoms stay locked. Tops stagger, middles stagger, bottoms
 * land on one line.
 */
.sec-support-integrations .si-card--lead .si-art {
  padding-block: 44px;
  min-height: 420px;
}

/*
 * ...and the far column spends that slack UNEVENLY. An even split moved both
 * seams together and left them 26px apart, which is a near-miss rather than an
 * offset; weighting the slack onto Hardware pulls the far seam up to ~80px clear
 * of the near one. The far column therefore reads bottom-heavy against a
 * top-heavy near column — the second stagger in the quilt, and the reason no two
 * horizontals in this field are ever within a hair of each other.
 */
.sec-support-integrations .si-col--far > .si-card:nth-child(1) { flex-grow: 0.55; }
.sec-support-integrations .si-col--far > .si-card:nth-child(2) { flex-grow: 1.45; }

/*
 * ONE drawing size for all four, and it is not a number typed here: `.illo--card`
 * (20-components.css) pins them to --illo-card, the site's single card-drawing
 * size. Rank in this section is carried by the card, never by the object —
 * ILLUSTRATION.md items 3 and 7 forbid size as hierarchy across a set.
 * Occlusion silhouettes use the GLOBAL `.illo-mask`, which paints itself in the
 * card's own --illo-ground; this file used to declare a private class for the
 * same job, which is exactly the trap ILLUSTRATION.md item 5 describes.
 */

/* ---------------------------------------------------------------------------
   THE CHIPS — the section's texture, and the thing that makes a list a surface.
   Tokens only: a name, a format, a device. A sentence in a pill is not an index
   entry, and the one that used to be here is now the note below.
   --------------------------------------------------------------------------- */

.sec-support-integrations .si-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 0;
  padding: 20px 0 0;
  list-style: none;
}

.sec-support-integrations .si-chips li {
  font-size: 13px;
  line-height: 1.35;
  font-weight: 450;
  letter-spacing: -0.002em;
  color: var(--slate);
  border: 1px solid var(--hair-strong);
  border-radius: var(--r-pill);
  padding: 5px 11px;
}

/* The qualifier that used to be set as a 45-character pill. It is an annotation
   ON the index, so it sits under it, at caption rank and in --ash — not a body
   line under a title, which is the lead's alone. */
.sec-support-integrations .si-note {
  margin-top: 12px;
  font-size: var(--t-caption);
  line-height: 1.45;
  color: var(--ash);
  max-width: 32ch;
}

/* ---------------------------------------------------------------------------
   THE CLOSE — off the right rail, opposite the header's rail on the left, and
   set in the display face. `.h-sm-serif` carries the site's serif sidebearing
   correction as a negative left margin; this block is hung off the RIGHT rail,
   so `margin-left: auto` overrides it and no stem lands on a rail it should be
   aligning to.
   --------------------------------------------------------------------------- */

.sec-support-integrations .si-close {
  max-width: 640px;
  margin-top: var(--s64);
  margin-left: auto;
}

/* The one italic accent in the close; the headline has its own. `.h-sm-serif`
   is not in the global `em` italic list, so it is stated here. */
.sec-support-integrations .si-close em {
  font-style: italic;
}

/* ===========================================================================
   NARROW
   =========================================================================== */

@media (max-width: 1040px) {
  .sec-support-integrations .si-head { max-width: 700px; }
  .sec-support-integrations .si-field { gap: var(--s20); }
  .sec-support-integrations .si-col { gap: var(--s20); }
  .sec-support-integrations .si-col--far { margin-top: var(--s64); }
  .sec-support-integrations .si-card { padding: var(--s24); }
  .sec-support-integrations .si-card--lead { padding: var(--s32); }
  .sec-support-integrations .si-art { padding-block: 22px; }
  .sec-support-integrations .si-card--lead .si-art { padding-block: 34px; }
  .sec-support-integrations .si-chips { padding-top: 18px; }
}

/*
 * Below 860 the narrower column sets under 340px, which is tighter than the
 * drawing wants. One column instead, and the offset goes with it — an interlock
 * needs two columns to interlock with, and a 64px indent on a phone reads as a
 * stray margin rather than as a decision.
 */
@media (max-width: 860px) {
  .sec-support-integrations .si-head { max-width: none; }

  /*
   * `display: contents` dissolves the two columns so all four cards become
   * direct children of one stack, and `order` interleaves them back into the
   * reading sequence — Payments, Delivery, Accounting, Hardware. Without it the
   * phone gets a whole column and then the other one, which puts Accounting
   * above Delivery and silently reorders the argument. The reveal delays
   * written on the cards were authored for this order, so the stagger runs top
   * to bottom on a phone exactly as it runs left-right-left-right on a desk.
   */
  .sec-support-integrations .si-field {
    display: flex;
    flex-direction: column;
    gap: var(--s20);
    margin-top: 44px;
  }
  .sec-support-integrations .si-col { display: contents; }
  .sec-support-integrations .si-col--near > .si-card:nth-child(1) { order: 1; }
  .sec-support-integrations .si-col--far  > .si-card:nth-child(1) { order: 2; }
  .sec-support-integrations .si-col--near > .si-card:nth-child(2) { order: 3; }
  .sec-support-integrations .si-col--far  > .si-card:nth-child(2) { order: 4; }

  /*
   * THE PHONE KEEPS THE RANK, AND GETS ITS RHYTHM FROM IT. Four identical
   * full-width cards down 4,000px is honest and not designed; here the lead
   * keeps its 26px title, its body line, its warm ink and a deeper plate, and
   * the three peers are pulled TIGHTER than they were on the desk, so the beat
   * is one long card and then three short ones rather than the same bar four
   * times. ALL FOUR DRAWINGS STAY THE SAME SIZE — the plate around the object
   * changes, never the object, because size as rank across a set is what
   * ILLUSTRATION.md items 3 and 7 forbid.
   */
  .sec-support-integrations .si-card { flex: 0 0 auto; }
  .sec-support-integrations .si-art { padding-block: 14px 18px; }
  /* The deep desktop plate would be ~200px of bare card on a phone, where the
     column is 350px wide and there is no neighbouring card to be measured
     against; a third of it is enough to keep the lead the long card in the
     stack. */
  .sec-support-integrations .si-card--lead .si-art { padding-block: 30px; min-height: 300px; }

  .sec-support-integrations .si-close { margin-top: 48px; margin-left: 0; }
}

@media (max-width: 560px) {
  .sec-support-integrations .si-sub { margin-top: 16px; max-width: 34ch; }
  .sec-support-integrations .si-chips { gap: 6px; }
  .sec-support-integrations .si-chips li { padding: 5px 10px; }
}

/* ————————————————————————————————————————————————
   THE LEAD IS A DIFFERENT SURFACE, NOT JUST A BIGGER ONE.
   All four cards sat on the same grey — a measured 3% delta against the section
   ground — with identical anatomy, so rank was asserted by size alone and the
   set read as four equal tiles, one of which happened to be large. Payments is
   the card an operator checks first, so it becomes this page's single heavy
   element: ink ground, inverted drawing, dark-surface text tokens.
   ———————————————————————————————————————————————— */
.sec-support-integrations .si-card--lead {
  background: var(--ink);
  border-color: transparent;
  /*
   * Occlusion masks paint themselves in --illo-ground so a drawing can sit on any
   * surface. Without this the paper-filled silhouettes that do the hidden-line
   * removal render as solid white shapes on ink, and the line drawing collapses
   * into a filled mass.
   */
  --illo-ground: var(--ink);
}
.sec-support-integrations .si-card--lead .card__title { color: var(--paper); }
.sec-support-integrations .si-card--lead .card__body,
.sec-support-integrations .si-card--lead p { color: var(--on-dark-muted); }
.sec-support-integrations .si-card--lead .illo { color: var(--raised); opacity: 0.62; }
.sec-support-integrations .si-card--lead .si-chips { border-top-color: color-mix(in srgb, var(--paper) 18%, transparent); }
.sec-support-integrations .si-card--lead .si-chips li {
  color: var(--on-dark-muted);
  border-color: color-mix(in srgb, var(--paper) 22%, transparent);
}

/* ===== section:support-security ===== */
/* ============================================================================
   support-security — "the statement is the surface".

   The section is three objects and a lot of paper: a headline on the left
   rail, four hairline-ruled facts in the right column offset below it, and one
   peach panel hung off the left rail that runs past the screen's left edge.
   Nothing else is added. The empty top-right quadrant is the composition, not
   a gap waiting to be filled.

   TWO CROPS, IN OPPOSITE DIRECTIONS. The peach carries off the left of the
   frame; each of the four rules carries off the right of it. That pairing is
   what holds the section together across the empty channel between the two
   columns — with the rules stopping dead on the page rail the fact column read
   as a card suspended in air, because nothing in it touched an edge.

   The peach panel is this page's ONE chromatic surface (support-hero and
   cta-band carry none), which is why the honesty line — the only sentence here
   that is a promise rather than a fact — is what sits inside it.
   ============================================================================ */

.sec-support-security {
  /* A little extra under the panel so a colour field that bleeds off one edge
     does not appear to be leaning on the closing band below it. */
  padding-bottom: var(--section-y);
  /*
   * THE CROPS ARE CLIPPED HERE, NOT BY THE ROOT. `<html>` already carries
   * `overflow-x: clip`, and that is enough to stop the page scrolling — but it
   * does NOT stop the overflow being counted: with the rules running a full
   * viewport past the right rail, documentElement.scrollWidth measured 2760 on
   * a 1440 window, and every full-page capture came back twice as wide as the
   * design with the right-hand half blank. The section is a full-bleed block,
   * so its own border box is exactly the viewport and clipping on it costs the
   * left-hand bleed nothing. `clip` rather than `hidden` because `hidden` would
   * force the block axis to `auto` and turn the section into a scroll port.
   */
  overflow-x: clip;
}

/* ---------------------------------------------------------------------------
   THE GRID

   Twelve columns so the two blocks can be placed on real page columns rather
   than on percentages: the panel takes 1–6 (584px at the 1200 measure), the
   facts take 8–12 (481px), and column 7 plus its two gaps leaves a 135px
   channel between them. Row 1 holds the headline alone, so the facts start
   BELOW its altitude and the top-right quadrant stays empty.
   --------------------------------------------------------------------------- */

.sec-support-security .ss {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gutter);
  row-gap: 76px;
}

.sec-support-security .ss__h {
  grid-column: 1 / 7;
  grid-row: 1;
  /* Row 2 stretches its items; the headline must not, or its box would grow to
     the row height and the panel would start lower than the rail suggests. */
  align-self: start;
}

/*
 * Both body blocks sit in row 2 and STRETCH, which is the only reason the
 * bottom edges relate to each other at all: the panel's natural height (about
 * 470px) and the four facts' (about 455px) are within one line of each other,
 * so whichever is taller sets the row and the panel fills it exactly. The
 * honesty line is pushed to the bottom of that box with margin-top:auto, so it
 * lands on the row's baseline rather than floating with slack beneath it.
 */
.sec-support-security .ss__note { grid-column: 1 / 7;  grid-row: 2; }

/*
 * The facts hang from the BOTTOM of the row, not the top. Top-aligned they
 * floated: empty paper above them beside the headline AND empty paper below
 * them once the panel ran on past — two voids, and a column apparently
 * suspended between them. Bottom-aligned, the last sentence lands on the same
 * line as the panel's bottom edge (a real alignment, the only one in the
 * section), and the two voids merge into one field of air in the upper right
 * that the headline sits at the edge of.
 */
.sec-support-security .ss__list {
  grid-column: 8 / 13;
  grid-row: 2;
  align-self: end;
}

/* ---------------------------------------------------------------------------
   THE PEACH PANEL

   Left padding is ZERO on purpose. The panel's own left edge sits exactly on
   the page rail, so the drawing and the sentence align with the headline
   above them, and the colour is carried off-screen by a pseudo-element instead
   of by a negative margin.

   WHY NOT `margin-left: calc(50% - 50vw)`: 50% would resolve against the grid
   AREA, not the page, so the bleed would be wrong at every width; and 100vw
   includes the scrollbar, so any vw-derived padding used to push the content
   back onto the rail lands ~7px off it. A `right: 100%` pseudo-element is
   exact at every width, needs no vw arithmetic for the alignment, and is
   contained by the `overflow-x: clip` already set on <html>.
   --------------------------------------------------------------------------- */

.sec-support-security .ss__note {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 46px 40px 48px 0;
  /* The left corners are off-screen, so they are not rounded — a radius there
     would only ever show up as a notch if the bleed were ever miscalculated. */
  border-radius: 0 var(--r-card) var(--r-card) 0;
}

.sec-support-security .ss__note::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 100%;
  width: 100vw;
  background: var(--peach);
  /* Positioned, so it paints above the in-flow text — harmless here because it
     is entirely to the left of the padding box and can never overlap it. */
}

/*
 * THE DRAWING. Offset in from the rail so the object does not stand on the
 * same x as the sentence beneath it — the panel then has a small internal
 * stagger instead of two flush-left blocks — and the offset is deliberately
 * NOT half the slack (48 left against 96 right), so the drawing sits left of
 * the panel's centre and never lines up on an axis with anything.
 *
 * 400px is measured against the field it stands in: at 348 the safe read as a
 * spot illustration parked in a lot of colour rather than as the object the
 * panel is about, and the fix for that is a bigger drawing, not more marks in
 * it. It is a CEILING under `.illo--feature`'s 500 — the section lowers the
 * site size to fit its plate, it does not invent one.
 */
.sec-support-security .ss__illo {
  width: min(400px, 74%);
  margin-left: 48px;
}

/*
 * The honesty line. 480px breaks it three ways with a full last line; at the
 * panel's full 544px it sets two-and-a-short-third and the rag goes ragged in
 * the wrong place. margin-top:auto is what puts it on the bottom of the
 * stretched row, and the padding-top is the minimum air it keeps from the
 * drawing when the row is short.
 */
.sec-support-security .ss__say {
  margin-top: auto;
  padding-top: 46px;
  max-width: 480px;
}

/* ---------------------------------------------------------------------------
   THE FOUR FACTS

   Identical in every dimension — same width, same rule, same padding, same
   title size and weight. The only difference between them is the length of
   the sentence. Rules are top-only, per brief; the last row drops its bottom
   padding so the column terminates on the last descender rather than on 42px
   of nothing, which is what lets the two columns close together.

   THE RULE IS NOT A BORDER. A `border-top` can only be as wide as its box, and
   a box that stops on the page rail makes four rules that stop on the page
   rail — a tidy edge, and the reason the column read as a floating card. Drawn
   as a pseudo-element the rule keeps its left end registered to the column and
   runs a full viewport past its right end, out of the frame. `<html>` already
   carries `overflow-x: clip`, so nothing is added to the scroll width.
   --------------------------------------------------------------------------- */

.sec-support-security .ss__list {
  margin: 0;
}

.sec-support-security .ss__row {
  position: relative;
  padding: 30px 0 42px;
}
.sec-support-security .ss__row:last-child { padding-bottom: 0; }

.sec-support-security .ss__row::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: calc(100% + 100vw);
  height: 1px;
  background: var(--hair-strong);
}

.sec-support-security .ss__t {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--t-body-lg);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.sec-support-security .ss__d {
  /* <dd> ships a 40px inline-start margin in every UA stylesheet. */
  margin: 10px 0 0;
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--slate);
  text-wrap: pretty;
}

/* ===========================================================================
   NARROW

   1040 and down: the columns keep their page positions — the channel between
   them is the thing that stops a coloured panel and a column of type reading
   as one block, so it is the last thing to go, not the first. What gives is
   the drawing and the panel's own padding.
   =========================================================================== */

@media (max-width: 1040px) {
  .sec-support-security .ss { row-gap: 60px; }
  .sec-support-security .ss__note { padding: 40px 32px 42px 0; }
  .sec-support-security .ss__illo { width: min(330px, 78%); margin-left: 34px; }
  .sec-support-security .ss__say { padding-top: 38px; }
}

/* ===========================================================================
   STACKED — 860 and down.

   One column. DOM order takes over, so the reading order the markup already
   has (headline → four facts → honesty line) is exactly what renders: the
   caveat closes the section, which is what it is for.

   Both crops survive the stack, and they still point opposite ways: the rules
   run off the right of the phone, the panel off the left of it. On a phone the
   gutter is only 20px, so each overhang is small — but a warm field and a set
   of rules that run out of frame read as generous where an inset card and four
   tidy borders read as one more stack of boxes.
   =========================================================================== */

@media (max-width: 860px) {
  .sec-support-security .ss {
    display: block;
  }
  .sec-support-security .ss__h { max-width: 12em; }
  .sec-support-security .ss__list { margin-top: 54px; }
  .sec-support-security .ss__note { margin-top: 54px; }

  /*
   * THE PANEL TURNS ON ITS SIDE. Stacked, it is suddenly the full page
   * measure — 748px of colour at a 820 window — and the desktop arrangement
   * cannot fill that: a drawing capped at `.illo--feature`'s 500 and a
   * sentence held to a readable measure left 270px of bare peach down the
   * right-hand side, with the object floating in the middle of it. Between
   * 640 and 860 the panel is therefore a ROW — object left, sentence beside
   * it on the optical centre — which is the shape a wide short field wants.
   * Below 640 there is no longer room for two columns and it stacks again.
   */
  .sec-support-security .ss__note {
    flex-direction: row;
    align-items: center;
    column-gap: 40px;
    padding: 44px 36px 44px 0;
  }
  .sec-support-security .ss__illo {
    width: min(340px, 46%);
    margin-left: 28px;
    flex: 0 0 auto;
  }
  /* `margin-top: auto` is cross-axis in a row and would drop the sentence to
     the bottom edge; centring is what pairs it with the drawing. */
  .sec-support-security .ss__say { margin-top: 0; padding-top: 0; max-width: none; }
}

@media (max-width: 640px) {
  .sec-support-security .ss__list { margin-top: 44px; }
  .sec-support-security .ss__note {
    flex-direction: column;
    margin-top: 44px;
    padding: 34px 24px 36px 0;
  }
  .sec-support-security .ss__illo { width: min(262px, 84%); margin-left: 5%; }
  .sec-support-security .ss__say { padding-top: 30px; max-width: 19em; }
  .sec-support-security .ss__row { padding: 22px 0 30px; }
}

/* ===== section:cta-band ===== */
/* ————————————————————————————————————————————————
   cta-band — the closing punctuation, shared by all eight pages.

   Round 4. Round 3 lost on FINISH, not on idea: the two largest objects in the
   frame were hand-drawn placeholder-bar SVGs (a 264×426 field and a 290×214
   fragment), so a third of the composition read as content-TBD; every surface
   in the band sat between #FFF and #EAEAEA, so there was no mass anywhere; and
   ~550×290 of empty gradient sat between the headline's descender and the
   card's left edge. Three changes, in order of size:

   1. THE SLAB. The card is now the only dark mass in any page's closing band —
      var(--ink), white keys, paper values, no shadow (elevation is reserved for
      .artifact and this is not one). It is the "one genuinely heavy element"
      the band never had.
   2. REAL TYPE, NOT BARS. The menu inside it is SET: 29 priced rows under six
      small-caps category headers, prices on one shared tabular column per
      column of the menu. The kitchen ticket at the other corner is set the same
      way. Nothing in this section is a placeholder bar any more, and the slab
      earns its area with character density rather than filling it.
   3. INTERLOCK. The slab is taller (768px against a ~690px band) and pinned so
      its top rides ABOVE the headline's first line rather than starting below
      it, and the file tile is now a CHILD of the slab, hung across its left
      edge — so the overlap is measured from the slab and holds at every width.
      The hole in the middle is closed by the tile, not by moving the rail.

   The crop is still measured: the slab overhangs the right edge by 108px and
   its inner padding-right is that overhang plus 28px, so every price and every
   value ends 28px inside the cut and the edge falls through row whitespace.
   ———————————————————————————————————————————————— */
.sec-cta-band {
  padding-block: var(--section-y-loose);
  border-top: 1px solid var(--hair);
  /* Every object here is meant to be cut by these edges, and the bloom must
     never bleed onto whichever section happens to precede us. */
  overflow: hidden;
}

/* — The light —————————————————————————————————
   Recomposed for a left-anchored frame: the warm primary bloom sits behind the
   display head at 30/26 rather than on the axis, a lilac holds the object half,
   and a low warm one sits under the cut cards so the bottom of the band never
   flattens out. The cool --wash-4 stays dropped (it read as a blue-grey corner
   on --fog) and the component's paper-coloured bottom fade is removed — this
   band sits on --fog, so that fade would paint a white shelf across the close
   of every page. */
.sec-cta-band > .wash {
  inset: 0;
  opacity: 0.72;
  filter: blur(18px) saturate(106%);
  background:
    radial-gradient(38% 46% at 24% 20%, var(--wash-1) 0%, transparent 66%),
    radial-gradient(48% 54% at 58% 32%, var(--wash-2) 0%, transparent 70%),
    radial-gradient(40% 46% at 14% 76%, var(--wash-3) 0%, transparent 72%),
    radial-gradient(40% 46% at 88% 80%, var(--wash-1) 0%, transparent 72%);
}
.sec-cta-band > .wash::after { content: none; }

/* — Stacking ———————————————————————————————————
   Type above everything; the objects above the closing rule; the rule beneath
   both. That ordering is what lets the full-measure hairline disappear under
   the slab instead of drawing a grey line across it. */
.sec-cta-band .ctab__wrap { position: relative; z-index: 2; }
.sec-cta-band .ctab__footwrap { position: relative; z-index: 0; }

/* — The rail ———————————————————————————————— */
.sec-cta-band .ctab {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  max-width: 760px;
}

.sec-cta-band .ctab__h {
  /* SECTION-HEAD SCALE, NOT DISPLAY. This partial is byte-identical on all
     eight pages, so a display-scale sign-off made the last words on six of them
     the loudest words on the page — louder than the page's own H1. The site's
     one display is the home hero; every section headline, this one included,
     sits on .h. The measure still makes the two decks read as a natural break
     off the rail rather than as a balanced pair of centred lines. */
  font-size: var(--t-h);
  line-height: 1.16;
  letter-spacing: var(--tr-h);
  max-width: 15ch;
}
/* Give the clipped line masks room for the italic 'y' descender, then take the
   extra leading back so the two decks keep the rhythm .h sets for them. */
.sec-cta-band .ctab__h .line-mask { padding-bottom: 0.14em; margin-bottom: -0.14em; }

/* Dropped from --t-body-lg. At 20px the lede competed with the headline; at
   17px it becomes the quiet second voice, and at 44ch it sets three short lines
   against the rail instead of two long centred ones. */
/* The measure is also a CLEARANCE. The slab's left edge marches left as the
   viewport narrows (it is 53vw wide against a fixed 108px overhang) while the
   rail's text stays pinned at the gutter, so the lede is the line that would
   meet the file tile first. Every step below is set to keep ~40px of air
   between the end of this paragraph and the tile's send button. */
.sec-cta-band .ctab__sub {
  margin: var(--s24) 0 0;
  font-size: var(--t-body);
  line-height: 1.5;
  max-width: 40ch;
}

/* One filled pill and one plain link, both flush to the rail. */
.sec-cta-band .ctab__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s12) var(--s28);
  margin-top: var(--s40);
}
.sec-cta-band .ctab__wa {
  /* .alink is a text link; give it a real hit target anyway. */
  min-height: 44px;
  padding-inline: 4px;
}

/* — The close ————————————————————————————————
   Full page measure, flush left, with a 2px ink tab thickening its left end and
   the fine print hanging off exactly that end. */
.sec-cta-band .ctab__foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-top: var(--s48);
}
.sec-cta-band .ctab__rule {
  position: relative;
  display: block;
  width: 100%;
  height: 1px;
  background: var(--hair-strong);
}
.sec-cta-band .ctab__rule::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 76px;
  height: 2px;
  background: var(--ink);
}
.sec-cta-band .ctab__fine { margin-top: var(--s20); color: var(--ash); }

/* — The objects ———————————————————————————————
   Placed against the section, not the wrap, so their crops are measured from
   the viewport edge and stay identical at every desktop width. */
.sec-cta-band .ctab__stage {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

/* THE SLAB. Anchored to the BOTTOM, never the top: the shared shell gives a
   first-child section 44px of extra top padding, and bottom anchoring is the
   only way the crop and the offset against the type read identically on a real
   page and in the isolated preview. Its HEIGHT is declared rather than derived,
   because the menu inside deliberately overruns it — that overrun is what
   guarantees the slab is never a part-empty dark field at any width. */
.sec-cta-band .ctab__art {
  position: absolute;
  right: -108px;
  bottom: -130px;
  /* 53vw keeps the overhang constant while the slab narrows with the viewport,
     so it can never reach across into the rail. At 1440 the slab's left edge
     lands at x=788, ~200px off the headline's ragged right — the hole the last
     round left between the two masses was 550px wide. */
  width: min(760px, 53vw);
  height: 768px;
}
.sec-cta-band .ctab__card {
  /* Overhang + 28px, so the price column ends well inside the cut and the edge
     always falls through whitespace. */
  --crop: 136px;
  /* The one dark mass. No shadow: elevation belongs to .artifact, and a slab
     this heavy separates on value alone. */
  --slab-hair: color-mix(in srgb, var(--paper) 58%, transparent);
  height: 100%;
  background: var(--ink);
  color: var(--paper);
  border-radius: var(--r-card);
  text-align: left;
  overflow: hidden;
}

.sec-cta-band .ctab__card-top {
  display: flex;
  align-items: center;
  gap: var(--s16);
  padding: 24px var(--crop) 20px 30px;
  border-bottom: 1px solid var(--slab-hair);
}
.sec-cta-band .ctab__card-title {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: -0.008em;
  color: var(--paper);
  white-space: nowrap;
}
/* The single confirmation beat in the whole band, so it is the highest-contrast
   thing in it: paper on ink, on the same flush right column as every value and
   every price below it. */
.sec-cta-band .ctab__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  height: 24px;
  padding-inline: 11px;
  border-radius: var(--r-pill);
  background: var(--paper);
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: -0.004em;
  white-space: nowrap;
}

.sec-cta-band .ctab__list { list-style: none; margin: 0; padding: 0; }
.sec-cta-band .ctab__list li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 13px var(--crop) 13px 30px;
  font-size: 13.5px;
  line-height: 1.3;
}
.sec-cta-band .ctab__list li + li { border-top: 1px solid var(--slab-hair); }
.sec-cta-band .ctab__k { color: var(--smoke); white-space: nowrap; }
/* One flush right edge shared by the chip, every value here and every price in
   the menu below — the column that makes the slab read as one object. */
.sec-cta-band .ctab__v {
  margin-left: auto;
  color: var(--paper);
  font-weight: 450;
  white-space: nowrap;
}

/* — The menu, set ————————————————————————————
   28 priced rows under six small-caps headers. It overruns the slab's declared
   height by ~70px at 1440 and by more as the columns narrow, so the band always
   cuts it mid-row rather than leaving dark air at the bottom. */
.sec-cta-band .ctab__menu {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: 36px;
  border-top: 1px solid var(--slab-hair);
  padding: 24px var(--crop) 0 30px;
}
.sec-cta-band .ctab__cat {
  font-size: 10.5px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--smoke);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--slab-hair);
}
.sec-cta-band .ctab__rows { list-style: none; margin: 9px 0 22px; padding: 0; }
.sec-cta-band .ctab__rows li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-block: 4.5px;
  font-size: 12.5px;
  line-height: 1.34;
  letter-spacing: -0.002em;
  color: var(--paper);
}
.sec-cta-band .ctab__it { min-width: 0; }
/* The qualifier is part of the item name, not a second field — set in the same
   line at the same size, one step down in value. */
.sec-cta-band .ctab__it i { font-style: normal; color: var(--smoke); }
.sec-cta-band .ctab__pr { margin-left: auto; color: var(--paper); white-space: nowrap; }

/* — The file tile ————————————————————————————
   A CHILD of the slab wrapper, hung across the slab's left edge at a fixed
   offset, so the object-on-object overlap is measured from the slab and cannot
   drift into the rail as the viewport narrows. It is also what closes the
   ~550px hole that used to sit between the headline and the card. */
.sec-cta-band .ctab__art3 {
  position: absolute;
  /* Crosses the slab's edge by 30px — exactly the slab's own left padding, so
     the overlap occludes surface and never a glyph. Vertically it straddles the
     hairline between the fact table and the menu, so it cuts a structural line
     rather than a row of type. */
  left: -192px;
  top: 232px;
  width: 214px;
}
.sec-cta-band .ctab__tile {
  display: flex;
  align-items: center;
  gap: 11px;
  /* Raised white, ringed rather than shadowed — elevation is reserved for
     .artifact. Most of the tile lies on the pale gradient, where an unringed
     white card has no edge at all. */
  background: var(--raised);
  border: 1px solid var(--hair-strong);
  border-radius: var(--r-small);
  padding: 12px 14px;
  transform: rotate(-2.5deg);
}
.sec-cta-band .ctab__tile-ico {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: var(--mist);
  color: var(--slate);
}
.sec-cta-band .ctab__tile-txt { min-width: 0; }
.sec-cta-band .ctab__tile-name {
  display: block;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.006em;
  color: var(--ink);
  white-space: nowrap;
}
.sec-cta-band .ctab__tile-meta {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.3;
  color: var(--slate);
  white-space: nowrap;
}
/* The second ink mass, hanging off the tile's left edge onto the gradient — a
   third overlap, at a third scale. */
.sec-cta-band .ctab__send {
  position: absolute;
  left: -19px;
  top: 12px;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--paper);
}

/* — The ticket ————————————————————————————————
   What the built shop prints: light, flat, no elevation, cut by the OPPOSITE
   edge and by the bottom. It sits below every line of type, so it can never
   collide with the rail at any viewport width. */
.sec-cta-band .ctab__art2 {
  position: absolute;
  left: -60px;
  width: 400px;
  /* Height is declared so the standing part is EXACTLY 130px at every width.
     The band's bottom padding is a constant 160px, so the ticket's top edge is
     always 30px clear of the fine print however the type above it reflows —
     anchoring by content height alone let it climb over the closing line at
     1024. */
  height: 260px;
  bottom: -130px;
}
.sec-cta-band .ctab__slip {
  height: 100%;
  background: var(--mist);
  border: 1px solid var(--hair-strong);
  border-radius: var(--r-card);
  /* Left padding is deeper than the 60px crop, so the viewport edge cuts empty
     card and never a glyph — the object is cropped, the type is not. */
  padding: 20px 24px 0 88px;
  overflow: hidden;
  /* Pivoted on its top-right corner, so the rotation can only ever drop the
     ticket away from the fine print, never lift it into the text. */
  transform: rotate(-4deg);
  transform-origin: 100% 0;
}
.sec-cta-band .ctab__slip-top {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding-bottom: 9px;
  border-bottom: 1px solid var(--hair-strong);
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--slate);
}
.sec-cta-band .ctab__slip-top span:last-child { margin-left: auto; }
.sec-cta-band .ctab__slip-rows { list-style: none; margin: 10px 0 0; padding: 0; }
.sec-cta-band .ctab__slip-rows li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding-block: 5px;
  font-size: 12.5px;
  line-height: 1.34;
  letter-spacing: -0.002em;
  color: var(--ink);
  white-space: nowrap;
}
.sec-cta-band .ctab__q { flex: none; width: 12px; color: var(--slate); }
.sec-cta-band .ctab__slip-rows i { font-style: normal; color: var(--slate); }

/* — Narrower desktops —————————————————————————
   The objects are anchored to the viewport, so the crops hold all the way down;
   only the type measure and the menu's column count need to give. */
@media (max-width: 1180px) {
  .sec-cta-band .ctab { max-width: 620px; }
  .sec-cta-band .ctab__sub { max-width: 32ch; }
  .sec-cta-band .ctab__menu { column-gap: 28px; }
}
@media (max-width: 1080px) {
  .sec-cta-band .ctab { max-width: 500px; }
  .sec-cta-band .ctab__sub { max-width: 30ch; }
  .sec-cta-band .ctab__card { --crop: 126px; }
  .sec-cta-band .ctab__art3 { left: -166px; top: 206px; width: 196px; }
}

/* — Stacked ————————————————————————————————————
   Below 980 there is no room beside the rail, so the slab drops into flow
   between the CTA and the closing line. It is NOT a full-width block inside
   both gutters: it keeps its left edge on the rail, runs 24px past the right
   edge of the screen, and keeps the file tile lying across its top-left corner
   — the crop-and-overlap idea survives the breakpoint instead of being deleted
   at it. The stage is a sibling BETWEEN the two wraps in source for exactly
   this reason, so the page still ends on the closing line. */
@media (max-width: 980px) {
  .sec-cta-band .ctab { max-width: none; }
  .sec-cta-band .ctab__sub { max-width: 46ch; }

  .sec-cta-band .ctab__stage {
    position: relative;
    inset: auto;
    width: 100%;
  }
  .sec-cta-band .ctab__art {
    position: relative;
    inset: auto;
    width: auto;
    /* Tuned so the cut lands mid-row, never on a category header — an orphan
       header at the crop reads as a bug, a half-row reads as a crop. */
    height: 620px;
    /* Left edge on the rail; right edge 24px past the screen, cropped by the
       section's own overflow. */
    margin: var(--s64) -24px 0 var(--gutter);
    animation: none;
  }
  /* Room above the title for the tile to cross the corner without covering it. */
  .sec-cta-band .ctab__card { --crop: 48px; }
  .sec-cta-band .ctab__card-top { padding: 52px 48px 18px 26px; }
  .sec-cta-band .ctab__list li { padding: 13px 48px 13px 26px; }
  .sec-cta-band .ctab__menu {
    grid-template-columns: minmax(0, 1fr);
    padding: 22px 48px 0 26px;
  }
  .sec-cta-band .ctab__mcol:last-child { display: none; }

  .sec-cta-band .ctab__art3 {
    left: 10px;
    top: -30px;
    width: 200px;
    animation: none;
  }
  .sec-cta-band .ctab__art2 { display: none; }

  .sec-cta-band .ctab__foot { margin-top: var(--s64); }
}

/* — Phones ————————————————————————————————————
   The action row is capped to the measure of the copy above it, so it can never
   bulge wider than the sentence it belongs to. */
@media (max-width: 720px) {
  .sec-cta-band .ctab__h { max-width: 13ch; }
  .sec-cta-band .ctab__sub { margin-top: var(--s16); max-width: 32ch; }
  .sec-cta-band .ctab__actions {
    margin-top: var(--s32);
    max-width: 34ch;
    gap: var(--s8) var(--s20);
  }
  .sec-cta-band .ctab__art { margin-top: var(--s48); height: 480px; }
  .sec-cta-band .ctab__art3 { left: 6px; top: -28px; width: 184px; }
  .sec-cta-band .ctab__foot { margin-top: var(--s48); }
  .sec-cta-band .ctab__rule::before { width: 56px; }
}
