/* =========================================================================
   Public site design system
   =========================================================================
   Everything a signed-out visitor sees is built on this file: the homepage,
   the marketing pages, the policy pages and the sign-in journey.

   It is written as layers, in this order, and each one only depends on the
   ones above it:

     1  Tokens            colour, type, space, motion, elevation
     2  Reset and base    the document, headings, links, media
     3  Motion            reveal, float, shimmer, and the reduced-motion opt-out
     4  Layout            shells, sections, grids, the bento
     5  Surfaces          cards, glass, gradient borders, the dark split
     6  Controls          buttons, inputs, checks, alerts
     7  Components        nav, hero, stats, steps, plans, FAQ, marquee, footer
     8  Auth              the split-screen sign-in shape
     9  Prose             long-form CMS content
    10  Utilities         the small set worth having
    11  States            focus, selection, print, forced colours

   Two rules held throughout:

   - **Every colour is a token.** No literal outside the token block, so the
     whole site re-themes from one place and dark mode costs one override
     rather than an audit.
   - **Nothing decorative is in the layout.** Glows, auras and grids are
     painted in pseudo-elements and fixed layers, so none of them can reflow
     content or shift it while the page settles.

   Light and dark both, following the system setting, with an explicit
   [data-theme] override for the header toggle. The palette is the admin
   sign-in page's - Inter, zinc neutrals, near-black primary - so signing in
   does not feel like arriving at a different product.
   ====================================================================== */

/* =========================================================================
   1. Tokens
   ====================================================================== */

:root{
  /* ---- neutral ramp -------------------------------------------------- */
  --zinc-50:#fafafa;  --zinc-100:#f4f4f5; --zinc-200:#e4e4e7;
  --zinc-300:#d4d4d8; --zinc-400:#a1a1aa; --zinc-500:#71717a;
  --zinc-600:#52525b; --zinc-700:#3f3f46; --zinc-800:#27272a;
  --zinc-900:#18181b; --zinc-950:#09090b;

  /* ---- semantic surface ---------------------------------------------- */
  --bg:var(--zinc-50);
  --bg-2:#ffffff;
  --surface:#ffffff;
  --surface-2:var(--zinc-100);
  --surface-3:var(--zinc-200);
  --border:var(--zinc-200);
  --border-2:var(--zinc-300);
  --border-strong:var(--zinc-400);

  /* ---- semantic text -------------------------------------------------- */
  --text:var(--zinc-950);
  --muted:var(--zinc-600);
  --faint:var(--zinc-400);

  /* ---- action --------------------------------------------------------- */
  --primary:var(--zinc-900);
  --primary-h:var(--zinc-800);
  --primary-a:#000000;
  --invert:#ffffff;

  /* ---- accent, used sparingly ---------------------------------------- */
  --accent:#4f46e5;
  --accent-2:#0ea5e9;
  --accent-3:#8b5cf6;
  --accent-soft:color-mix(in srgb,var(--accent) 12%,transparent);

  /* ---- status --------------------------------------------------------- */
  --ok:#15803d;      --ok-bg:#f0fdf4;    --ok-border:#bbf7d0;
  --warn:#a16207;    --warn-bg:#fefce8;  --warn-border:#fde68a;
  --danger:#b91c1c;  --danger-bg:#fef2f2;--danger-border:#fecaca;
  --info:#1d4ed8;    --info-bg:#eff6ff;  --info-border:#bfdbfe;

  /* ---- radius --------------------------------------------------------- */
  --r-xs:6px; --r-sm:9px; --r:12px; --r-lg:16px; --r-xl:22px; --r-2xl:28px;
  --r-pill:999px;

  /* ---- elevation ------------------------------------------------------ */
  --sh-xs:0 1px 2px rgba(9,9,11,.05);
  --sh-sm:0 1px 3px rgba(9,9,11,.07),0 1px 2px rgba(9,9,11,.04);
  --sh:0 4px 14px -4px rgba(9,9,11,.10),0 2px 6px -2px rgba(9,9,11,.06);
  --sh-lg:0 14px 44px -14px rgba(9,9,11,.20),0 6px 16px -8px rgba(9,9,11,.10);
  --sh-xl:0 30px 80px -30px rgba(9,9,11,.32);
  --ring:0 0 0 3px color-mix(in srgb,var(--primary) 15%,transparent);

  /* ---- space ---------------------------------------------------------- */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:20px;
  --s-6:24px; --s-8:32px; --s-10:40px; --s-12:48px; --s-16:64px;
  --s-20:80px; --s-24:96px;

  /* ---- fluid type ------------------------------------------------------
     clamp() rather than breakpoints: the scale is continuous, so there is no
     width at which a heading is awkwardly between two sizes. */
  --t-xs:12px;
  --t-sm:13.5px;
  --t-base:15px;
  --t-md:16.5px;
  --t-lg:clamp(17px,1.1vw + 14px,19px);
  --t-xl:clamp(20px,1.6vw + 15px,24px);
  --t-2xl:clamp(24px,2.4vw + 16px,32px);
  --t-3xl:clamp(30px,3.4vw + 18px,44px);
  --t-4xl:clamp(36px,5vw + 18px,60px);

  --lh-tight:1.12;
  --lh-snug:1.3;
  --lh:1.65;
  --tr-tight:-.035em;
  --tr-snug:-.022em;
  --tr-wide:.08em;

  /* ---- motion ---------------------------------------------------------- */
  --e-out:cubic-bezier(.22,1,.36,1);
  --e-in-out:cubic-bezier(.65,0,.35,1);
  --e-spring:cubic-bezier(.34,1.56,.64,1);
  --d-fast:.14s; --d:.24s; --d-slow:.5s; --d-slower:.9s;

  /* ---- layout ---------------------------------------------------------- */
  --maxw:1160px;
  --maxw-narrow:46rem;
  --gutter:20px;
  --hdr-h:64px;

  color-scheme:light;
}

/* Dark, from the system setting, unless the toggle has said otherwise. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:var(--zinc-950);
    --bg-2:#0c0c0f;
    --surface:var(--zinc-900);
    --surface-2:var(--zinc-800);
    --surface-3:#323238;
    --border:var(--zinc-800);
    --border-2:var(--zinc-700);
    --border-strong:var(--zinc-600);
    --text:var(--zinc-50);
    --muted:var(--zinc-400);
    --faint:var(--zinc-500);
    --primary:var(--zinc-50);
    --primary-h:var(--zinc-200);
    --primary-a:#ffffff;
    --invert:var(--zinc-950);
    --accent:#818cf8;
    --accent-2:#38bdf8;
    --accent-3:#a78bfa;
    --ok:#4ade80;      --ok-bg:rgba(34,197,94,.13);   --ok-border:rgba(74,222,128,.30);
    --warn:#fbbf24;    --warn-bg:rgba(245,158,11,.13);--warn-border:rgba(251,191,36,.30);
    --danger:#f87171;  --danger-bg:rgba(239,68,68,.13);--danger-border:rgba(248,113,113,.30);
    --info:#60a5fa;    --info-bg:rgba(59,130,246,.13);--info-border:rgba(96,165,250,.30);
    --sh-xs:0 1px 2px rgba(0,0,0,.45);
    --sh-sm:0 1px 3px rgba(0,0,0,.5);
    --sh:0 4px 14px -4px rgba(0,0,0,.55);
    --sh-lg:0 14px 44px -14px rgba(0,0,0,.7);
    --sh-xl:0 30px 80px -30px rgba(0,0,0,.8);
    --ring:0 0 0 3px color-mix(in srgb,var(--primary) 22%,transparent);
    color-scheme:dark;
  }
}

/* The toggle wins over the system setting, in both directions. Duplicated
   rather than shared because a media query cannot be re-entered from an
   attribute selector. */
:root[data-theme="dark"]{
  --bg:var(--zinc-950);
  --bg-2:#0c0c0f;
  --surface:var(--zinc-900);
  --surface-2:var(--zinc-800);
  --surface-3:#323238;
  --border:var(--zinc-800);
  --border-2:var(--zinc-700);
  --border-strong:var(--zinc-600);
  --text:var(--zinc-50);
  --muted:var(--zinc-400);
  --faint:var(--zinc-500);
  --primary:var(--zinc-50);
  --primary-h:var(--zinc-200);
  --primary-a:#ffffff;
  --invert:var(--zinc-950);
  --accent:#818cf8;
  --accent-2:#38bdf8;
  --accent-3:#a78bfa;
  --ok:#4ade80;      --ok-bg:rgba(34,197,94,.13);   --ok-border:rgba(74,222,128,.30);
  --warn:#fbbf24;    --warn-bg:rgba(245,158,11,.13);--warn-border:rgba(251,191,36,.30);
  --danger:#f87171;  --danger-bg:rgba(239,68,68,.13);--danger-border:rgba(248,113,113,.30);
  --info:#60a5fa;    --info-bg:rgba(59,130,246,.13);--info-border:rgba(96,165,250,.30);
  --sh-xs:0 1px 2px rgba(0,0,0,.45);
  --sh-sm:0 1px 3px rgba(0,0,0,.5);
  --sh:0 4px 14px -4px rgba(0,0,0,.55);
  --sh-lg:0 14px 44px -14px rgba(0,0,0,.7);
  --sh-xl:0 30px 80px -30px rgba(0,0,0,.8);
  --ring:0 0 0 3px color-mix(in srgb,var(--primary) 22%,transparent);
  color-scheme:dark;
}

/* =========================================================================
   2. Reset and base
   ====================================================================== */

*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--hdr-h) + var(--s-4));
  text-size-adjust:100%;
}
body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  font-size:var(--t-base);
  line-height:var(--lh);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-synthesis-weight:none;
  overflow-x:clip;
}
/* Inter's optical sizing and tabular figures, where the font is actually
   loaded; harmless when it is not. */
@supports (font-variation-settings:normal){
  body{font-optical-sizing:auto}
}
h1,h2,h3,h4{margin:0;line-height:var(--lh-tight);letter-spacing:var(--tr-tight);font-weight:700;text-wrap:balance}
h1{font-size:var(--t-4xl)}
h2{font-size:var(--t-3xl)}
h3{font-size:var(--t-md);letter-spacing:var(--tr-snug);line-height:var(--lh-snug)}
h4{font-size:var(--t-base);letter-spacing:var(--tr-snug)}
p{margin:0;text-wrap:pretty}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
img,svg,video{max-width:100%;height:auto;display:block}
strong,b{font-weight:650}
small{font-size:var(--t-sm)}
hr{height:1px;border:0;background:var(--border);margin:var(--s-8) 0}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,textarea,select{font:inherit;color:inherit}
::selection{background:color-mix(in srgb,var(--accent) 26%,transparent);color:var(--text)}

/* =========================================================================
   3. Motion
   =========================================================================
   Three primitives, all transform/opacity only so none of them triggers
   layout. The reveal is driven by a single IntersectionObserver in
   _site-foot.twig adding .is-in; with JavaScript off nothing is hidden,
   because the hidden state is applied by that script rather than by this
   sheet.
   ====================================================================== */

[data-reveal]{
  opacity:1;
  transform:none;
}
.js [data-reveal]{
  opacity:0;
  transform:translateY(14px);
  transition:opacity var(--d-slow) var(--e-out),transform var(--d-slow) var(--e-out);
}
.js [data-reveal].is-in{opacity:1;transform:none}
/* Stagger children of a revealed group without a class per child. */
.js [data-reveal-group].is-in > *{animation:rise var(--d-slow) var(--e-out) backwards}
.js [data-reveal-group].is-in > *:nth-child(1){animation-delay:.02s}
.js [data-reveal-group].is-in > *:nth-child(2){animation-delay:.07s}
.js [data-reveal-group].is-in > *:nth-child(3){animation-delay:.12s}
.js [data-reveal-group].is-in > *:nth-child(4){animation-delay:.17s}
.js [data-reveal-group].is-in > *:nth-child(5){animation-delay:.22s}
.js [data-reveal-group].is-in > *:nth-child(6){animation-delay:.27s}
.js [data-reveal-group].is-in > *:nth-child(7){animation-delay:.32s}
.js [data-reveal-group].is-in > *:nth-child(8){animation-delay:.37s}
.js [data-reveal-group].is-in > *:nth-child(9){animation-delay:.42s}

@keyframes rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes float{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@keyframes drift{0%{transform:translate3d(0,0,0) scale(1)}50%{transform:translate3d(2%,-3%,0) scale(1.06)}100%{transform:translate3d(0,0,0) scale(1)}}
@keyframes shimmer{from{background-position:-140% 0}to{background-position:240% 0}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes pulse-ring{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 45%,transparent)}
                      70%{box-shadow:0 0 0 7px transparent}
                      100%{box-shadow:0 0 0 0 transparent}}
@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* One switch for everything above. Motion is decoration here - nothing is
   only communicated by it - so it can all simply stop. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .js [data-reveal]{opacity:1;transform:none}
}

/* =========================================================================
   4. Layout
   ====================================================================== */

.wrap{
  width:100%;
  max-width:var(--maxw);
  margin-inline:auto;
  padding-inline:var(--gutter);
  position:relative;
}
.wrap--narrow{max-width:var(--maxw-narrow)}
.sec{padding-block:clamp(var(--s-10),6vw,var(--s-24));position:relative}
.sec--tight{padding-block:clamp(var(--s-8),4vw,var(--s-16))}
.sec--flush{padding-top:0}
.sec__head{max-width:var(--maxw-narrow);margin-bottom:clamp(var(--s-6),3vw,var(--s-10))}
.sec__head--center{margin-inline:auto;text-align:center}
.sec__head p{margin-top:var(--s-3);color:var(--muted);font-size:var(--t-md)}

/* The ambient field. Fixed, behind everything, and outside the flow, so it
   costs nothing in layout and cannot shift content. Deliberately faint in
   light and a little stronger in dark, where there is room for it. */
/* z-index 0 with the page content lifted to 1, rather than the usual
   z-index:-1 trick. A negative layer depends on the body background being
   propagated to the canvas, and anything that makes body a stacking context -
   a filter, a transform, a containment rule - drops the layer on top of the
   content instead of behind it. Lifting the content is the version that cannot
   be broken from a distance. `contain` is dropped for the same reason: paint
   containment makes this element its own stacking context. */
/* Absolute and anchored to the top of the document, not fixed to the
   viewport.
   ---------------------------------------------------------------------
   A design choice, not a bug fix: the aura belongs to the top of the page, so
   it scrolls away with the hero rather than following the reader down every
   section. It also keeps a large blurred layer out from under the sticky
   header's backdrop-filter, which is one less thing for a compositor to get
   wrong.

   (An earlier version of this comment blamed that pair for washing out the
   page. It does not - checked with elementFromPoint: the heading is the
   topmost element at its own coordinates, its colour computes to the token,
   and no ancestor carries an opacity or a filter. The washing was the preview
   tool's screenshot, not the page.) */
.ambient{
  position:absolute;
  inset:0 0 auto;
  height:min(1300px,150vh);
  z-index:0;pointer-events:none;overflow:hidden;
}
body{position:relative}
.ph,.sec,.sec--tight,.site-ft,.auth,.site-hdr{position:relative;z-index:1}
.site-hdr{z-index:40}
.ambient__grid{
  position:absolute;inset:0;
  background-image:
    linear-gradient(to right,color-mix(in srgb,var(--text) 5%,transparent) 1px,transparent 1px),
    linear-gradient(to bottom,color-mix(in srgb,var(--text) 5%,transparent) 1px,transparent 1px);
  background-size:56px 56px;
  -webkit-mask-image:radial-gradient(110% 70% at 50% 0%,#000 20%,transparent 70%);
  mask-image:radial-gradient(110% 70% at 50% 0%,#000 20%,transparent 70%);
  opacity:.7;
}
.ambient__blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.30;will-change:transform}
.ambient__blob--a{width:48vw;height:48vw;left:-14vw;top:-16vw;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent) 70%,transparent),transparent 68%);
  animation:drift 26s var(--e-in-out) infinite}
.ambient__blob--b{width:40vw;height:40vw;right:-12vw;top:-4vw;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent-2) 62%,transparent),transparent 68%);
  animation:drift 34s var(--e-in-out) infinite reverse}
.ambient__blob--c{width:52vw;height:52vw;left:26vw;top:58vh;
  background:radial-gradient(circle,color-mix(in srgb,var(--accent-3) 46%,transparent),transparent 70%);
  animation:drift 42s var(--e-in-out) infinite}
/* A touch stronger in dark, where there is room for it. */
:root[data-theme="dark"] .ambient__blob{opacity:.42}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .ambient__blob{opacity:.42}
}

/* ---- grids -------------------------------------------------------------- */
.grid{display:grid;gap:var(--s-4);grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.grid--wide{grid-template-columns:repeat(auto-fit,minmax(330px,1fr))}
.grid--tight{gap:var(--s-3)}

/* The bento. One column on a phone, and a deliberate arrangement once there
   is room - the first cell wide, the rest filling around it. */
.bento{display:grid;gap:var(--s-4);grid-template-columns:1fr}
@media (min-width:720px){
  .bento{grid-template-columns:repeat(2,1fr)}
  .bento > :first-child{grid-column:span 2}
}
@media (min-width:1000px){
  .bento{grid-template-columns:repeat(3,1fr)}
  .bento > :first-child{grid-column:span 2;grid-row:span 2}
  /* The sixth card used to span two columns, which left a hole. The lead fills
     four cells and the five that follow fill five, so six cards land exactly in
     a three by three - unless one of them is two wide, and then it cannot fit
     beside the fifth, drops to a row of its own, and leaves the third column of
     the row above empty. One card per cell closes it. */
}

/* =========================================================================
   5. Surfaces
   ====================================================================== */

.card{
  position:relative;
  padding:var(--s-6);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-xs);
  transition:border-color var(--d) var(--e-out),
             box-shadow var(--d) var(--e-out),
             transform var(--d) var(--e-out);
}
.card p{margin-top:var(--s-2);color:var(--muted);font-size:var(--t-sm)}
.card h3 + p{margin-top:var(--s-2)}

/* Lift only where there is a pointer. On a touch screen a hover transform is
   just a delay between the tap and the thing happening. */
@media (hover:hover){
  .card--lift:hover{
    transform:translateY(-3px);
    border-color:var(--border-2);
    box-shadow:var(--sh-lg);
  }
}

/* A hairline of light along the top edge - the cheapest way to make a flat
   rectangle read as a surface with a direction to it. */
.card--lit::before{
  content:"";
  position:absolute;inset:0 0 auto;height:1px;
  border-radius:inherit;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--text) 16%,transparent),transparent);
  pointer-events:none;
}

/* A border that is a gradient, done with a mask so the fill stays the card's
   own background rather than becoming part of the gradient. */
.card--edge{
  background:
    linear-gradient(var(--surface),var(--surface)) padding-box,
    linear-gradient(135deg,
      color-mix(in srgb,var(--accent) 55%,transparent),
      color-mix(in srgb,var(--accent-2) 45%,transparent) 45%,
      var(--border) 85%) border-box;
  border:1px solid transparent;
}

.glass{
  background:color-mix(in srgb,var(--surface) 74%,transparent);
  border:1px solid color-mix(in srgb,var(--text) 9%,transparent);
  border-radius:var(--r-lg);
  backdrop-filter:blur(14px) saturate(1.4);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
}

.card__icon{
  width:40px;height:40px;
  display:grid;place-items:center;
  margin-bottom:var(--s-4);
  border-radius:var(--r-sm);
  background:var(--surface-2);
  border:1px solid var(--border);
  color:var(--text);
  font-size:var(--t-sm);
}
.card--edge .card__icon,
.card__icon--accent{
  background:linear-gradient(135deg,
    color-mix(in srgb,var(--accent) 18%,transparent),
    color-mix(in srgb,var(--accent-2) 18%,transparent));
  border-color:color-mix(in srgb,var(--accent) 26%,transparent);
  color:var(--accent);
}

/* ---- the dark split, as on the admin sign-in page ---------------------- */
.split{
  display:grid;
  border:1px solid var(--border);
  border-radius:var(--r-xl);
  overflow:hidden;
  box-shadow:var(--sh);
}
@media (min-width:900px){.split{grid-template-columns:1fr 1fr}}
.split__dark{
  position:relative;
  background:var(--zinc-950);
  color:var(--zinc-50);
  padding:clamp(var(--s-6),4vw,var(--s-12));
  display:flex;flex-direction:column;justify-content:space-between;gap:var(--s-8);
  min-height:280px;
  isolation:isolate;
}
/* A single soft light source in the corner, so the panel is not a flat black
   rectangle. Behind the content, and it cannot be clicked. */
.split__dark::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(70% 60% at 12% 8%,
    color-mix(in srgb,var(--accent) 30%,transparent),transparent 70%);
}
.split__dark h2{color:var(--zinc-50)}
.split__dark p{margin-top:var(--s-3);color:var(--zinc-400)}
.split__light p{margin-top:var(--s-3)}
.split__dark .ticks li{color:var(--zinc-400)}
.split__dark .ticks i{color:#4ade80}
.split__light{background:var(--surface);padding:clamp(var(--s-6),4vw,var(--s-12))}

/* =========================================================================
   6. Controls
   ====================================================================== */

.btn{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;gap:var(--s-2);
  min-height:44px;padding:0 var(--s-5);
  border:1px solid transparent;border-radius:var(--r-sm);
  font-size:var(--t-sm);font-weight:650;letter-spacing:-.01em;
  white-space:nowrap;
  overflow:hidden;
  transition:background var(--d) var(--e-out),
             border-color var(--d) var(--e-out),
             color var(--d) var(--e-out),
             box-shadow var(--d) var(--e-out),
             transform var(--d-fast) var(--e-out);
}
.btn:active{transform:translateY(1px);transition-duration:60ms}
.btn--lg{min-height:50px;padding:0 var(--s-6);font-size:var(--t-base);border-radius:var(--r)}
.btn--sm{min-height:36px;padding:0 var(--s-3);font-size:var(--t-xs)}
.btn--block{width:100%}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.55;cursor:not-allowed;transform:none}

.btn--primary{
  background:var(--primary);color:var(--invert);
  box-shadow:inset 0 1px 0 color-mix(in srgb,var(--invert) 22%,transparent),var(--sh-sm);
}
.btn--primary:hover{background:var(--primary-h);box-shadow:inset 0 1px 0 color-mix(in srgb,var(--invert) 28%,transparent),var(--sh)}
/* One sheen, crossing on hover, pointer-events off so it can never eat the
   click it decorates. */
.btn--primary::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 24%,
    color-mix(in srgb,var(--invert) 26%,transparent) 50%,transparent 76%);
  transform:translateX(-130%);
  transition:transform .62s var(--e-out);
}
@media (hover:hover){
  .btn--primary:hover::after{transform:translateX(130%)}
  .btn--lift:hover{transform:translateY(-2px)}
}

.btn--ghost{background:var(--surface);color:var(--text);border-color:var(--border-2);box-shadow:var(--sh-xs)}
.btn--ghost:hover{background:var(--surface-2);border-color:var(--border-strong)}
.btn--quiet{background:transparent;color:var(--muted)}
.btn--quiet:hover{background:var(--surface-2);color:var(--text)}

.icon-btn{
  width:38px;height:38px;flex:none;
  display:inline-grid;place-items:center;
  border:1px solid var(--border-2);border-radius:var(--r-sm);
  background:var(--surface);color:var(--text);
  font-size:var(--t-sm);
  transition:background var(--d) var(--e-out),border-color var(--d) var(--e-out);
}
.icon-btn:hover{background:var(--surface-2)}

/* ---- fields ------------------------------------------------------------ */
.form-group{margin-bottom:var(--s-4)}
.control-label{display:block;margin-bottom:var(--s-2);font-size:var(--t-sm);font-weight:550}
.form-control{
  width:100%;min-height:46px;padding:0 var(--s-4);
  background:var(--surface-2);
  border:1px solid var(--border-2);border-radius:var(--r-sm);
  color:var(--text);font-size:var(--t-base);
  transition:background var(--d-fast) var(--e-out),
             border-color var(--d-fast) var(--e-out),
             box-shadow var(--d-fast) var(--e-out);
}
textarea.form-control{padding:var(--s-3) var(--s-4);min-height:120px;line-height:var(--lh);resize:vertical}
.form-control::placeholder{color:var(--faint)}
.form-control:hover{border-color:var(--border-strong)}
.form-control:focus{outline:none;background:var(--surface);border-color:var(--primary);box-shadow:var(--ring)}
.form-control:disabled{opacity:.65;cursor:not-allowed}
.form-control[aria-invalid="true"]{border-color:var(--danger)}
.form-text{display:block;margin-top:var(--s-2);font-size:var(--t-xs);color:var(--muted)}

.form-check{display:flex;align-items:flex-start;gap:var(--s-3);margin-bottom:var(--s-4)}
.form-check-input{flex:none;width:17px;height:17px;margin-top:3px;accent-color:var(--primary);cursor:pointer}
.form-check-label{font-size:var(--t-sm);color:var(--muted);cursor:pointer}
.form-check-label a{color:var(--text);text-decoration:underline}
.d-grid{display:grid}
.d-grid > .btn{width:100%}

/* ---- alerts ------------------------------------------------------------
   Colour never carries the meaning on its own - each one has an icon, so it
   still reads for anyone the colour does not reach. */
.alert{
  display:flex;align-items:flex-start;gap:var(--s-3);
  margin:0 0 var(--s-4);padding:var(--s-3) var(--s-4);
  border:1px solid transparent;border-radius:var(--r-sm);
  font-size:var(--t-sm);line-height:1.55;
}
.alert i{margin-top:3px;flex:none}
.alert .close{
  margin-left:auto;flex:none;width:26px;height:26px;
  display:inline-grid;place-items:center;border-radius:var(--r-xs);
  color:inherit;font-size:17px;line-height:1;opacity:.6;
  transition:opacity var(--d-fast) var(--e-out),background var(--d-fast) var(--e-out);
}
.alert .close:hover{opacity:1;background:color-mix(in srgb,currentColor 14%,transparent)}
.alert-danger{background:var(--danger-bg);border-color:var(--danger-border);color:var(--danger)}
.alert-success{background:var(--ok-bg);border-color:var(--ok-border);color:var(--ok)}
.alert-warning{background:var(--warn-bg);border-color:var(--warn-border);color:var(--warn)}
.alert-info{background:var(--info-bg);border-color:var(--info-border);color:var(--info)}

/* ---- range ------------------------------------------------------------- */
input[type=range]{
  -webkit-appearance:none;appearance:none;
  width:100%;height:6px;border-radius:var(--r-pill);
  border:1px solid var(--border);
  background:linear-gradient(90deg,var(--primary) 0%,var(--primary) var(--pct,20%),var(--surface-2) var(--pct,20%));
  cursor:pointer;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:22px;height:22px;border-radius:50%;
  background:var(--surface);border:2px solid var(--primary);
  box-shadow:var(--sh-sm);cursor:grab;
  transition:transform var(--d-fast) var(--e-spring),box-shadow var(--d-fast) var(--e-out);
}
input[type=range]::-webkit-slider-thumb:active{transform:scale(1.12);cursor:grabbing}
input[type=range]::-moz-range-thumb{
  width:22px;height:22px;border-radius:50%;
  background:var(--surface);border:2px solid var(--primary);
  box-shadow:var(--sh-sm);cursor:grab;
}
input[type=range]:focus-visible{box-shadow:var(--ring)}

/* =========================================================================
   7. Components
   ====================================================================== */

/* ---- header ------------------------------------------------------------ */
.site-hdr{
  position:sticky;top:0;z-index:40;
  background:color-mix(in srgb,var(--bg) 82%,transparent);
  backdrop-filter:blur(12px) saturate(1.5);
  -webkit-backdrop-filter:blur(12px) saturate(1.5);
  border-bottom:1px solid transparent;
  transition:border-color var(--d) var(--e-out),background var(--d) var(--e-out);
}
/* The rule only appears once the page has moved, so the header does not draw
   a line under itself over a hero it is sitting on. .is-stuck is set by the
   scroll listener in _site-foot.twig. */
.site-hdr.is-stuck{border-bottom-color:var(--border);background:color-mix(in srgb,var(--bg) 92%,transparent)}
.site-hdr__in{display:flex;align-items:center;gap:var(--s-4);height:var(--hdr-h)}

.mark{display:flex;align-items:center;gap:var(--s-3);font-weight:650;letter-spacing:var(--tr-snug)}
.mark__box{
  flex:none;width:34px;height:34px;
  display:grid;place-items:center;border-radius:var(--r-sm);
  background:var(--primary);color:var(--invert);
  font-size:var(--t-sm);font-weight:700;letter-spacing:-.02em;
}

.site-nav{display:none;margin-left:auto;gap:2px}
.site-nav a{
  position:relative;
  padding:var(--s-2) var(--s-3);border-radius:var(--r-xs);
  font-size:var(--t-sm);font-weight:500;color:var(--muted);
  transition:color var(--d-fast) var(--e-out),background var(--d-fast) var(--e-out);
}
.site-nav a:hover{color:var(--text);background:var(--surface-2)}
.site-nav a[aria-current="page"]{color:var(--text)}
/* The current page is marked by a rule under it as well as by colour, so it
   is not colour alone doing the work. */
.site-nav a[aria-current="page"]::after{
  content:"";position:absolute;left:var(--s-3);right:var(--s-3);bottom:2px;height:2px;
  border-radius:2px;background:var(--primary);
}
.site-hdr__cta{display:none;gap:var(--s-2);margin-left:var(--s-2)}
.burger{margin-left:auto}
.site-drawer{display:none;flex-direction:column;gap:var(--s-2);padding-bottom:var(--s-4)}
.site-drawer.is-open{display:flex;animation:rise var(--d) var(--e-out)}
.site-drawer a:not(.btn){padding:var(--s-3) 2px;color:var(--muted);border-bottom:1px solid var(--border)}
@media (min-width:880px){
  .site-nav,.site-hdr__cta{display:flex}
  .burger,.site-drawer{display:none !important}
}

/* ---- page head --------------------------------------------------------- */
.ph{padding-block:clamp(var(--s-10),8vw,var(--s-20)) clamp(var(--s-6),3vw,var(--s-10));position:relative}
.ph__in{max-width:var(--maxw-narrow)}
.ph p{margin-top:var(--s-4);color:var(--muted);font-size:var(--t-md)}
/* The sentence under a hero heading. Capped at ~34rem because a lead running
   the full width of a 1160px shell is past the 75-character line the rest of
   the page is set to. */
.lead{margin-top:var(--s-4);max-width:34rem;color:var(--muted);font-size:var(--t-md)}
/* An inline link inside body copy, where underline is the only thing marking
   it - colour alone would not. */
.link{text-decoration:underline;text-underline-offset:2px}
.ph__cta{display:flex;flex-wrap:wrap;gap:var(--s-3);margin-top:var(--s-6)}
.ph__cta--center{justify-content:center}

.eyebrow{
  display:inline-flex;align-items:center;gap:var(--s-2);
  margin-bottom:var(--s-4);
  padding:5px var(--s-3) 5px var(--s-2);
  border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--border);
  box-shadow:var(--sh-xs);
  font-size:var(--t-xs);font-weight:650;letter-spacing:var(--tr-wide);text-transform:uppercase;
  color:var(--muted);
}
.eyebrow::before{
  content:"";width:6px;height:6px;border-radius:50%;background:var(--ok);
  animation:pulse-ring 2.6s var(--e-out) infinite;
}

/* Gradient headline text. The -webkit- pair comes first so that where
   background-clip:text is unsupported the text keeps --text and stays
   readable, rather than clipping to nothing and vanishing. */
.grad{
  background:linear-gradient(103deg,var(--text) 4%,var(--accent) 52%,var(--accent-2) 96%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
}

/* ---- ticks ------------------------------------------------------------- */
.ticks{display:flex;flex-direction:column;gap:var(--s-3)}
.ticks li{display:flex;gap:var(--s-3);color:var(--muted);font-size:var(--t-sm)}
.ticks i{color:var(--ok);margin-top:.3em;font-size:var(--t-xs);flex:none}
.ticks--row{flex-direction:row;flex-wrap:wrap;gap:var(--s-3) var(--s-6)}

/* ---- stats ------------------------------------------------------------- */
.stats{display:grid;gap:var(--s-4);grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.stat{padding:var(--s-5);background:var(--surface);border:1px solid var(--border);border-radius:var(--r)}
.stat__v{display:block;font-size:var(--t-2xl);font-weight:750;letter-spacing:var(--tr-tight);font-variant-numeric:tabular-nums}
.stat__k{display:block;margin-top:var(--s-1);color:var(--muted);font-size:var(--t-xs);letter-spacing:.04em;text-transform:uppercase}

/* ---- steps ------------------------------------------------------------- */
.steps{display:grid;gap:var(--s-4);counter-reset:s;grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.step{position:relative;padding:var(--s-6);background:var(--surface);border:1px solid var(--border);border-radius:var(--r-lg)}
.step::before{
  counter-increment:s;content:counter(s);
  display:grid;place-items:center;width:30px;height:30px;margin-bottom:var(--s-4);
  border-radius:var(--r-xs);background:var(--primary);color:var(--invert);
  font-weight:700;font-size:var(--t-sm);
}
.step p{margin-top:var(--s-2);color:var(--muted);font-size:var(--t-sm)}

/* ---- plans ------------------------------------------------------------- */
.plan-tag{
  position:absolute;top:-10px;left:var(--s-6);
  padding:3px var(--s-3);border-radius:var(--r-pill);
  background:var(--primary);color:var(--invert);
  font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
}
.plan-amt{font-size:var(--t-2xl);font-weight:800;letter-spacing:var(--tr-tight);font-variant-numeric:tabular-nums}
.plan-per{font-size:var(--t-sm);font-weight:500;color:var(--muted)}
.card--match{border-color:var(--primary);box-shadow:0 0 0 1px var(--primary),var(--sh-lg)}

/* ---- calculator -------------------------------------------------------- */
.calc{max-width:660px;margin-inline:auto;margin-bottom:var(--s-8);padding:var(--s-6)}
.calc__label{display:block;text-align:center;color:var(--muted);font-size:var(--t-sm);margin-bottom:var(--s-4)}
.calc__out{text-align:center;margin-top:var(--s-5)}
.calc__band{color:var(--muted);font-size:var(--t-sm);font-variant-numeric:tabular-nums}
.calc__name{margin-top:var(--s-1);font-size:var(--t-xl);font-weight:750;letter-spacing:var(--tr-tight)}
.calc__price{font-size:var(--t-3xl);font-weight:800;letter-spacing:var(--tr-tight);font-variant-numeric:tabular-nums}
.calc__per{font-size:var(--t-base);font-weight:500;color:var(--muted);letter-spacing:0}
.calc__manual{margin-top:var(--s-5);padding-top:var(--s-5);border-top:1px solid var(--border);text-align:center}
.calc__manual .form-control{max-width:260px;margin-inline:auto;text-align:center;font-weight:650;font-variant-numeric:tabular-nums}

/* ---- FAQ --------------------------------------------------------------- */
.faq{display:flex;flex-direction:column;gap:var(--s-3);max-width:var(--maxw-narrow)}
.faq details{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:var(--s-4) var(--s-5);
  transition:border-color var(--d) var(--e-out),box-shadow var(--d) var(--e-out);
}
.faq details[open]{border-color:var(--border-2);box-shadow:var(--sh-xs)}
.faq summary{
  cursor:pointer;font-weight:600;list-style:none;
  display:flex;align-items:center;gap:var(--s-3);
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{
  content:"";margin-left:auto;flex:none;width:10px;height:10px;
  border-right:2px solid var(--faint);border-bottom:2px solid var(--faint);
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--d) var(--e-out);
}
.faq details[open] summary::after{transform:rotate(-135deg) translateY(-2px)}
.faq details[open] > p{animation:rise var(--d) var(--e-out)}
.faq p{margin-top:var(--s-3);color:var(--muted);font-size:var(--t-sm)}
.faq a{color:var(--text);text-decoration:underline}

/* ---- rows (contact details) -------------------------------------------- */
.rows{display:flex;flex-direction:column}
.row{display:flex;flex-wrap:wrap;gap:var(--s-2) var(--s-5);align-items:baseline;
     padding:var(--s-4) 0;border-bottom:1px solid var(--border)}
.row:last-child{border-bottom:0}
.row__k{min-width:132px;color:var(--muted);font-size:var(--t-sm)}
.row__v{font-weight:550;word-break:break-word}

/* ---- marquee ------------------------------------------------------------
   Duplicated content and a -50% translation, so the loop is seamless. The
   copy is aria-hidden on the duplicate so a screen reader hears it once. */
.marquee{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
         mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.marquee__track{display:flex;width:max-content;gap:var(--s-8);animation:marquee 34s linear infinite}
.marquee:hover .marquee__track{animation-play-state:paused}
.marquee__item{display:flex;align-items:center;gap:var(--s-2);color:var(--muted);font-size:var(--t-sm);white-space:nowrap}
.marquee__item i{color:var(--faint)}

/* ---- footer ------------------------------------------------------------ */
.site-ft{border-top:1px solid var(--border);margin-top:var(--s-10);padding-block:var(--s-8);color:var(--muted);font-size:var(--t-sm)}
.site-ft__in{display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-6);align-items:center;justify-content:space-between}
.site-ft nav{display:flex;flex-wrap:wrap;gap:var(--s-4)}
.site-ft a{transition:color var(--d-fast) var(--e-out)}
.site-ft a:hover{color:var(--text)}

/* =========================================================================
   8. Auth
   ====================================================================== */

.auth{display:grid;min-height:100vh;min-height:100svh}
@media (min-width:960px){.auth{grid-template-columns:1fr 1fr}}
.auth__brand{
  position:relative;display:none;
  background:var(--zinc-950);color:var(--zinc-50);
  padding:clamp(var(--s-8),4vw,var(--s-12));
  flex-direction:column;justify-content:space-between;gap:var(--s-10);
  isolation:isolate;overflow:hidden;
}
@media (min-width:960px){.auth__brand{display:flex}}
.auth__brand::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(60% 50% at 10% 6%,color-mix(in srgb,var(--accent) 32%,transparent),transparent 70%),
             radial-gradient(50% 40% at 90% 96%,color-mix(in srgb,var(--accent-2) 22%,transparent),transparent 70%);
}
.auth__brand .mark__box{background:var(--zinc-50);color:var(--zinc-950)}
.auth__brand h2{color:var(--zinc-50);font-size:var(--t-2xl)}
.auth__brand .ticks li{color:var(--zinc-400)}
.auth__brand .ticks i{color:#4ade80}
.auth__panel{display:flex;flex-direction:column;align-items:center;justify-content:center;
             padding:clamp(var(--s-8),5vw,var(--s-10)) var(--gutter);background:var(--bg)}
.auth__card{width:100%;max-width:400px}
.auth__card .mark{margin-bottom:var(--s-6)}
.auth__title{margin:0 0 var(--s-1);font-size:var(--t-xl);letter-spacing:var(--tr-snug)}
.auth__lead{margin:0 0 var(--s-6);color:var(--muted);font-size:var(--t-sm)}
.auth__alt{margin-top:var(--s-4);text-align:center;font-size:var(--t-sm);color:var(--muted)}
.auth__alt a{color:var(--text);font-weight:550;text-decoration:underline}
.auth__sep{display:flex;align-items:center;gap:var(--s-3);margin-block:var(--s-5);
           color:var(--faint);font-size:var(--t-xs);letter-spacing:var(--tr-wide)}
.auth__sep::before,.auth__sep::after{content:"";flex:1;height:1px;background:var(--border)}
.auth__foot{margin-top:var(--s-6);text-align:center;color:var(--faint);font-size:var(--t-xs)}
.code-input{text-align:center;font-size:26px;font-weight:700;letter-spacing:.35em;
            font-variant-numeric:tabular-nums;min-height:58px}

/* =========================================================================
   9. Prose
   ====================================================================== */

.prose{max-width:var(--maxw-narrow);color:var(--muted);font-size:var(--t-base);line-height:1.75}
.prose > :first-child{margin-top:0}
.prose h1,.prose h2,.prose h3,.prose h4{color:var(--text);margin:var(--s-8) 0 var(--s-3)}
.prose h2{font-size:var(--t-xl)}
.prose h3{font-size:var(--t-md)}
.prose p{margin:0 0 var(--s-4)}
.prose ul,.prose ol{margin:0 0 var(--s-4);padding-left:var(--s-5);list-style:revert}
.prose li{margin-bottom:var(--s-2)}
.prose li::marker{color:var(--faint)}
.prose a{color:var(--text);text-decoration:underline;text-underline-offset:2px}
.prose img{border-radius:var(--r);margin:var(--s-4) 0;border:1px solid var(--border)}
.prose blockquote{margin:0 0 var(--s-4);padding-left:var(--s-4);border-left:3px solid var(--border-2);color:var(--muted)}
.prose code{padding:2px 6px;border-radius:var(--r-xs);background:var(--surface-2);
            font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em}
.prose pre{padding:var(--s-4);border-radius:var(--r);background:var(--surface-2);
           border:1px solid var(--border);overflow-x:auto;margin:0 0 var(--s-4)}
.prose pre code{padding:0;background:none}
/* Tables scroll inside their own box, so a wide one never makes the page
   itself scroll sideways. */
.prose .table-scroll,.prose table{display:block;max-width:100%;overflow-x:auto}
.prose table{border-collapse:collapse;margin:0 0 var(--s-4);font-size:var(--t-sm)}
.prose th,.prose td{padding:var(--s-2) var(--s-3);border:1px solid var(--border);text-align:left;white-space:nowrap}
.prose th{background:var(--surface-2);color:var(--text)}

/* =========================================================================
   10. Utilities
   ====================================================================== */

.muted{color:var(--muted)}
.faint{color:var(--faint)}
.center{text-align:center}
.nowrap{white-space:nowrap}
.tabular{font-variant-numeric:tabular-nums}
.stack{display:flex;flex-direction:column}
.cluster{display:flex;flex-wrap:wrap;align-items:center}
.gap-2{gap:var(--s-2)} .gap-3{gap:var(--s-3)} .gap-4{gap:var(--s-4)} .gap-6{gap:var(--s-6)}
.mt-2{margin-top:var(--s-2)} .mt-3{margin-top:var(--s-3)} .mt-4{margin-top:var(--s-4)}
.mt-6{margin-top:var(--s-6)} .mt-8{margin-top:var(--s-8)}
.mb-0{margin-bottom:0} .mb-4{margin-bottom:var(--s-4)} .mb-6{margin-bottom:var(--s-6)}
.full{width:100%}
.hide{display:none !important}
/* Available to a screen reader, invisible on screen - and it becomes visible
   again when focused, which is what makes a skip link work. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.skip{
  position:absolute;left:var(--s-4);top:var(--s-4);z-index:100;
  transform:translateY(-200%);
  transition:transform var(--d) var(--e-out);
}
.skip:focus{transform:none}

/* =========================================================================
   11. States
   ====================================================================== */

:where(a,button,input,textarea,select,summary,[tabindex]):focus-visible{
  outline:2px solid var(--primary);
  outline-offset:2px;
  border-radius:var(--r-xs);
}

/* Windows high-contrast mode throws the palette away, so anything drawn only
   as a background disappears. These give those elements a real border. */
@media (forced-colors:active){
  .btn,.card,.form-control,.icon-btn,.step,.stat{border:1px solid ButtonBorder}
  .btn--primary{background:ButtonText;color:ButtonFace;forced-color-adjust:none}
  .ambient{display:none}
  .grad{-webkit-text-fill-color:currentColor;color:CanvasText}
}

@media print{
  .site-hdr,.site-ft,.ambient,.site-drawer,.ph__cta,.btn,.marquee{display:none !important}
  body{background:#fff;color:#000;font-size:11pt}
  .card,.split,.step,.stat{border:1px solid #ccc;box-shadow:none;break-inside:avoid}
  .split__dark{background:#fff;color:#000}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:9pt;color:#555}
}

/* =========================================================================
   12. Showcase
   =========================================================================
   The hero's visual anchor. It replaces a screenshot: drawn entirely from
   tokens, so it themes with everything else, weighs nothing, cannot 404, and
   never goes out of date the way a picture of a UI does the moment the UI
   changes.
   ====================================================================== */

.hero{display:grid;gap:clamp(var(--s-8),5vw,var(--s-16));align-items:center}
@media (min-width:1000px){
  .hero{grid-template-columns:1.02fr .98fr}
}
.hero__copy{min-width:0}

.showcase{
  position:relative;
  padding:var(--s-4);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r-xl);
  box-shadow:var(--sh-lg);
  isolation:isolate;
}
/* A soft cast underneath, so the panel sits on the page rather than floating
   on it. Behind everything and unclickable. */
.showcase::before{
  content:"";position:absolute;inset:12% 6% -6%;z-index:-1;pointer-events:none;
  border-radius:var(--r-2xl);
  background:radial-gradient(60% 60% at 50% 50%,
    color-mix(in srgb,var(--accent) 30%,transparent),transparent 72%);
  filter:blur(42px);opacity:.55;
}
/* No perpetual float. A panel that never stops moving keeps the compositor
   awake for the whole visit - it costs battery on the phones this site is
   aimed at, and it is motion that says nothing. The panel arrives with the
   reveal and then holds still. */

.showcase__bar{
  display:flex;align-items:center;gap:var(--s-2);
  padding-bottom:var(--s-3);margin-bottom:var(--s-3);
  border-bottom:1px solid var(--border);
}
.showcase__dot{width:10px;height:10px;border-radius:50%;background:var(--surface-3)}
.showcase__dot--live{background:var(--ok);animation:pulse-ring 2.6s var(--e-out) infinite}
.showcase__url{
  margin-left:var(--s-2);padding:3px var(--s-3);
  border-radius:var(--r-pill);background:var(--surface-2);
  color:var(--muted);font-size:var(--t-xs);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
}

.showcase__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s-3)}
.showcase__tile{
  padding:var(--s-4);border-radius:var(--r);
  background:var(--surface-2);border:1px solid var(--border);
}
.showcase__k{display:block;color:var(--muted);font-size:11px;letter-spacing:.05em;text-transform:uppercase}
.showcase__v{display:block;margin-top:var(--s-1);font-size:var(--t-xl);font-weight:750;letter-spacing:var(--tr-tight)}

.showcase__rows{display:flex;flex-direction:column;gap:var(--s-2);margin-top:var(--s-3)}
.showcase__row{
  display:flex;align-items:center;gap:var(--s-3);
  padding:var(--s-3) var(--s-4);border-radius:var(--r);
  background:var(--surface-2);border:1px solid var(--border);
  font-size:var(--t-sm);
}
.showcase__row i{color:var(--accent);flex:none}
.pill{
  margin-left:auto;flex:none;
  padding:2px var(--s-3);border-radius:var(--r-pill);
  background:var(--ok-bg);border:1px solid var(--ok-border);color:var(--ok);
  font-size:11px;font-weight:650;white-space:nowrap;
}
/* A bar that fills once, when the panel is revealed - the one piece of motion
   here that carries meaning rather than decoration. */
.showcase__meter{height:5px;border-radius:var(--r-pill);background:var(--surface-3);overflow:hidden;margin-top:var(--s-3)}
.showcase__meter span{
  display:block;height:100%;width:0;border-radius:inherit;
  background:linear-gradient(90deg,var(--accent),var(--accent-2));
  transition:width 1.4s var(--e-out) .25s;
}
.is-in .showcase__meter span,
html:not(.js) .showcase__meter span{width:72%}

/* ---- bento tiles -------------------------------------------------------
   The first cell is the wide one, so it carries the heading treatment while
   the rest stay plain cards. */
.bento .card{height:100%}
.bento__lead{
  display:flex;flex-direction:column;justify-content:space-between;gap:var(--s-6);
  background:
    linear-gradient(var(--surface),var(--surface)) padding-box,
    linear-gradient(135deg,
      color-mix(in srgb,var(--accent) 50%,transparent),
      color-mix(in srgb,var(--accent-2) 40%,transparent) 50%,
      var(--border) 88%) border-box;
  border:1px solid transparent;
}
.bento__lead h3{font-size:var(--t-xl);letter-spacing:var(--tr-tight)}
.bento__lead p{font-size:var(--t-base)}

/* ---- section label ------------------------------------------------------ */
.sec__label{
  display:flex;align-items:center;gap:var(--s-3);
  margin-bottom:var(--s-3);
  color:var(--faint);font-size:var(--t-xs);font-weight:650;
  letter-spacing:var(--tr-wide);text-transform:uppercase;
}
.sec__label::after{content:"";flex:1;height:1px;background:var(--border)}

/* =========================================================================
   13. Flow
   =========================================================================
   The "getting started" steps. They were three flat cards with a number on
   each, which says "here are three things" rather than "these happen in this
   order" - and order is the entire point of that section.

   This is a connected sequence: numbered nodes on a rail, horizontal once
   there is room and vertical on a phone, with the rail drawn between the
   nodes rather than through them. The connector is a pseudo-element on each
   step, so the markup stays a plain list and nothing has to be positioned by
   hand.
   ====================================================================== */

.flow{display:grid;gap:var(--s-6);counter-reset:flow}
@media (min-width:860px){
  .flow{grid-template-columns:repeat(3,1fr);gap:var(--s-8)}
}

/* Each step is a surface, not floating text.
   ---------------------------------------------------------------------
   It was three columns of bare paragraphs on the page background, which left
   the one section that explains the product looking like a gap between two
   designed ones. The numbered node now sits on the card's top edge rather than
   above empty space, and the rail runs between the nodes across the gap. */
.flow__step{
  position:relative;
  padding:var(--s-8) var(--s-5) var(--s-5);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-xs);
  transition:border-color var(--d) var(--e-out),box-shadow var(--d) var(--e-out),transform var(--d) var(--e-out);
}
@media (hover:hover){
  .flow__step:hover{border-color:var(--border-2);box-shadow:var(--sh);transform:translateY(-2px)}
}

/* The node, straddling the top edge. The ring is the page background rather
   than a colour, so it reads as the card being punched through. */
.flow__step::before{
  counter-increment:flow;content:counter(flow);
  position:absolute;top:-19px;left:var(--s-5);
  width:38px;height:38px;
  display:grid;place-items:center;
  border-radius:var(--r-pill);
  background:var(--primary);color:var(--invert);
  font-size:var(--t-sm);font-weight:750;
  box-shadow:0 0 0 5px var(--bg),var(--sh-sm);
  z-index:1;
}

/* The rail, at the node's centre line, reaching across the gap to the next
   card. Suppressed after the last step so the sequence ends. */
.flow__step::after{
  content:"";position:absolute;
  left:calc(var(--s-5) + 46px);
  top:0;
  right:calc(var(--s-8) * -1);
  height:2px;
  /* --border-strong, not --border. The rail is the one element that says these
     are a sequence rather than three cards, and at the border colour it was the
     faintest thing in the section - present, and invisible. */
  background:linear-gradient(90deg,var(--border-strong),var(--border-2));
  display:none;
}
@media (min-width:860px){
  .flow__step::after{display:block}
  .flow__step:last-child::after{display:none}
}
/* On a phone the rail is vertical, running down the left between one node and
   the next. */
@media (max-width:859.98px){
  .flow{gap:var(--s-8)}
  .flow__step::after{
    display:block;
    left:calc(var(--s-5) + 18px);
    top:auto;bottom:calc(var(--s-8) * -1);right:auto;
    width:2px;height:var(--s-8);
    background:linear-gradient(180deg,var(--border-strong),var(--border-2));
  }
  .flow__step:last-child::after{display:none}
}

/* A quiet icon above the heading, so a step has something to look at as well
   as read. */
.flow__icon{
  width:34px;height:34px;
  display:grid;place-items:center;
  margin-bottom:var(--s-3);
  border-radius:var(--r-sm);
  background:var(--surface-2);
  border:1px solid var(--border);
  color:var(--muted);
  font-size:var(--t-sm);
}

.flow__step h3{font-size:var(--t-lg);letter-spacing:var(--tr-snug)}
.flow__step p{margin-top:var(--s-2);color:var(--muted);font-size:var(--t-sm)}
/* Two name servers means two chips; without this they sit flush against each
   other and read as one. */
.flow__note + .flow__note{margin-left:var(--s-2)}
.flow__note{
  display:inline-flex;align-items:center;gap:var(--s-2);
  margin-top:var(--s-3);padding:4px var(--s-3);
  border-radius:var(--r-pill);
  background:var(--surface-2);border:1px solid var(--border);
  color:var(--muted);font-size:var(--t-xs);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
}

/* =========================================================================
   14. Bento, second pass
   =========================================================================
   The tiles were uniform cards in a varied grid, which wastes the shape: a
   wide cell and a small cell looked the same apart from their size. These
   give the lead cell something to hold and let every tile answer a hover.
   ====================================================================== */

.bento .card{display:flex;flex-direction:column;gap:var(--s-2)}
/* No margin-top:auto on the heading. It pushed every heading to the bottom of
   its tile, which in a grid of unequal heights left a hole under each icon.
   Content reads from the top; only the lead tile's link is pinned down. */
.bento__lead > a{margin-top:auto}

/* Chips inside the lead tile: the specifics behind the headline, without a
   second paragraph to read. */
.chips{display:flex;flex-wrap:wrap;gap:var(--s-2);margin-top:var(--s-4)}
.chip{
  display:inline-flex;align-items:center;gap:6px;
  padding:4px var(--s-3);border-radius:var(--r-pill);
  background:var(--surface-2);border:1px solid var(--border);
  color:var(--muted);font-size:var(--t-xs);font-weight:550;white-space:nowrap;
  transition:border-color var(--d) var(--e-out),color var(--d) var(--e-out);
}
.chip i{color:var(--accent);font-size:10px}
@media (hover:hover){
  .card:hover .chip{border-color:var(--border-2);color:var(--text)}
}

/* A tint that arrives on hover, from the accent rather than a grey - it is
   the one place the accent is allowed to touch a whole surface. Behind the
   content and unclickable. */
.card--tint{isolation:isolate}
.card--tint::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  border-radius:inherit;
  background:radial-gradient(120% 100% at 0% 0%,
    color-mix(in srgb,var(--accent) 12%,transparent),transparent 60%);
  opacity:0;transition:opacity var(--d) var(--e-out);
}
@media (hover:hover){
  .card--tint:hover::after{opacity:1}
}

/* An arrow that only appears where a card actually leads somewhere. */
.card__more{
  margin-top:var(--s-4);
  display:inline-flex;align-items:center;gap:var(--s-2);
  color:var(--text);font-size:var(--t-sm);font-weight:600;
}
.card__more i{transition:transform var(--d) var(--e-out)}
@media (hover:hover){
  .card:hover .card__more i{transform:translateX(3px)}
}

/* =========================================================================
   15. Plans
   =========================================================================
   The plan cards were generic cards with a price inside them, so the three
   things a buyer compares - name, price, what is included - carried the same
   weight as everything else on the page. These give the price a band of its
   own, put the list on a shared baseline so the cards line up row for row,
   and pin the button to the bottom regardless of how many features a plan
   lists.
   ====================================================================== */

.plans{display:grid;gap:var(--s-4);align-items:stretch;
       grid-template-columns:repeat(auto-fit,minmax(258px,1fr))}

.plan{
  position:relative;
  display:flex;flex-direction:column;
  padding:0;overflow:hidden;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r-lg);
  box-shadow:var(--sh-xs);
  transition:border-color var(--d) var(--e-out),box-shadow var(--d) var(--e-out),transform var(--d) var(--e-out);
}
.plan__head{padding:var(--s-6) var(--s-6) var(--s-5);border-bottom:1px solid var(--border)}
.plan__name{font-size:var(--t-md);letter-spacing:var(--tr-snug)}
.plan__price{display:flex;align-items:baseline;gap:6px;margin-top:var(--s-3)}
.plan__amt{font-size:var(--t-3xl);font-weight:800;letter-spacing:var(--tr-tight);font-variant-numeric:tabular-nums;line-height:1}
.plan__per{font-size:var(--t-sm);color:var(--muted)}
.plan__meta{margin-top:var(--s-2);color:var(--faint);font-size:var(--t-xs)}

.plan__body{padding:var(--s-5) var(--s-6);display:flex;flex-direction:column;gap:var(--s-4);flex:1}
.plan__body .ticks{flex:1}
.plan__body .btn{margin-top:auto}

/* The recommended plan, and the one the calculator has landed on. Same
   treatment for both, because to a reader they mean the same thing: this is
   the one for you. */
.plan--featured,.plan--match{
  border-color:var(--primary);
  box-shadow:0 0 0 1px var(--primary),var(--sh-lg);
}
@media (min-width:900px){
  .plan--featured{transform:translateY(-6px)}
  .plan--featured.plan--match{transform:translateY(-6px)}
}
.plan__tag{
  position:absolute;top:var(--s-4);right:var(--s-4);
  padding:3px var(--s-3);border-radius:var(--r-pill);
  background:var(--primary);color:var(--invert);
  font-size:10.5px;font-weight:750;letter-spacing:.06em;text-transform:uppercase;
}
/* Said in text as well as by the ring, so it is not styling alone carrying
   the message. */
.plan__match{
  display:none;align-items:center;gap:6px;
  margin-top:var(--s-2);color:var(--ok);font-size:var(--t-xs);font-weight:650;
}
.plan--match .plan__match{display:inline-flex}

/* ---- calculator, restated on the plan surface -------------------------- */
.calc{
  max-width:680px;margin-inline:auto;margin-bottom:var(--s-8);
  padding:var(--s-6);
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-lg);box-shadow:var(--sh-sm);
}
.calc__scale{
  display:flex;justify-content:space-between;
  margin-top:var(--s-2);color:var(--faint);font-size:var(--t-xs);
  font-variant-numeric:tabular-nums;
}

/* =========================================================================
   16. Closing CTA
   =========================================================================
   The last thing on the page, and the only place it asks for a decision.

   It was a second .split - the same device already used higher up - with two
   headings of equal weight and two buttons of equal weight beside them. A
   closing panel that offers two equally-sized choices is a closing panel that
   does not close: there is nothing for the eye to land on. This is one panel,
   one heading, one button, with the secondary route present but quiet, and
   the reassurances underneath as small print rather than as a column.
   ====================================================================== */

.cta{
  position:relative;
  padding:clamp(var(--s-10),7vw,var(--s-20)) clamp(var(--s-5),4vw,var(--s-12));
  border-radius:var(--r-xl);
  background:var(--zinc-950);
  color:var(--zinc-50);
  text-align:center;
  overflow:hidden;
  isolation:isolate;
  box-shadow:var(--sh-xl);
}
/* Two light sources and a grid, all behind the content and unclickable. The
   grid is masked so it fades before it reaches the edges rather than stopping
   at a hard line. */
.cta::before{
  content:"";position:absolute;inset:0;z-index:-2;pointer-events:none;
  background:
    radial-gradient(60% 70% at 20% 0%,color-mix(in srgb,var(--accent) 42%,transparent),transparent 70%),
    radial-gradient(50% 60% at 85% 100%,color-mix(in srgb,var(--accent-2) 30%,transparent),transparent 70%);
}
.cta::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(to right,rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:48px 48px;
  -webkit-mask-image:radial-gradient(70% 70% at 50% 50%,#000,transparent 75%);
  mask-image:radial-gradient(70% 70% at 50% 50%,#000,transparent 75%);
}

.cta__eyebrow{
  display:inline-flex;align-items:center;gap:var(--s-2);
  margin-bottom:var(--s-5);padding:5px var(--s-4);
  border-radius:var(--r-pill);
  background:rgba(255,255,255,.07);
  border:1px solid rgba(255,255,255,.14);
  color:var(--zinc-300);
  font-size:var(--t-xs);font-weight:650;letter-spacing:var(--tr-wide);text-transform:uppercase;
}
.cta__eyebrow i{color:#4ade80}

.cta h2{color:var(--zinc-50);font-size:var(--t-4xl);max-width:16ch;margin-inline:auto}
.cta__lead{
  margin:var(--s-4) auto 0;max-width:44ch;
  color:var(--zinc-400);font-size:var(--t-md);
}

.cta__actions{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:var(--s-4);margin-top:var(--s-8);
}
/* Inverted, because on this panel the page's near-black primary would
   disappear into the background. */
.cta .btn--primary{
  background:var(--zinc-50);color:var(--zinc-950);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 10px 34px -10px rgba(255,255,255,.35);
}
.cta .btn--primary:hover{background:#fff}
.cta .btn--primary::after{
  background:linear-gradient(100deg,transparent 24%,rgba(9,9,11,.14) 50%,transparent 76%);
}
/* The second route is a link, not a rival button. */
.cta__quiet{
  color:var(--zinc-300);font-size:var(--t-sm);font-weight:550;
  text-decoration:underline;text-underline-offset:3px;
  transition:color var(--d-fast) var(--e-out);
}
.cta__quiet:hover{color:var(--zinc-50)}

.cta__reassure{
  display:flex;flex-wrap:wrap;justify-content:center;
  gap:var(--s-3) var(--s-6);margin-top:var(--s-8);
  color:var(--zinc-400);font-size:var(--t-sm);
}
.cta__reassure span{display:inline-flex;align-items:center;gap:var(--s-2)}
.cta__reassure i{color:#4ade80;font-size:var(--t-xs)}

/* =========================================================================
   17. Small pieces the content pages needed
   =========================================================================
   Each of these replaced an inline style that appeared on several pages. They
   are here rather than in a style attribute so the measure, the card padding
   and the post layout are one decision instead of ten.
   ====================================================================== */

/* A readable measure. Long-form cards were carrying max-width:620px, 660px and
   46rem - three guesses at the same thing. */
.measure{max-width:var(--maxw-narrow)}

/* ---- blog ---------------------------------------------------------------- */
.post{padding:0;overflow:hidden;display:flex;flex-direction:column}
.post__media{
  width:100%;aspect-ratio:16/9;object-fit:cover;
  border-bottom:1px solid var(--border);
  transition:transform var(--d-slow) var(--e-out);
}
@media (hover:hover){
  .post:hover .post__media{transform:scale(1.03)}
}
/* The image is cropped by the card, so the scale on hover has to be clipped
   by something - the card sets overflow:hidden for exactly that. */
.post__body{padding:var(--s-5);display:flex;flex-direction:column;gap:var(--s-3);flex:1}
.post__title{font-size:var(--t-md);line-height:var(--lh-snug)}
.post__body .btn{margin-top:auto;align-self:flex-start}

/* ---- back link ----------------------------------------------------------- */
.backlink{
  display:inline-flex;align-items:center;gap:var(--s-2);
  color:var(--muted);font-size:var(--t-sm);
  transition:color var(--d-fast) var(--e-out);
}
.backlink:hover{color:var(--text)}
.backlink i{font-size:var(--t-xs)}

/* ---- a figure inside prose ----------------------------------------------- */
.figure{
  max-width:var(--maxw-narrow);
  border-radius:var(--r);border:1px solid var(--border);
  margin-bottom:var(--s-6);
}

/* ---- auth brand column, and the disclosure on confirm_email ------------- */
/* The wordmark on the dark half of the sign-in split. It was carrying
   style="color:#fafafa" on five pages. */
.auth__brand .mark{color:var(--zinc-50)}
.auth__brand p{margin-top:var(--s-3);color:var(--zinc-400)}
.auth__brand .ticks{margin-top:var(--s-5)}
.auth__card .prose{margin-bottom:var(--s-5)}
.auth__card .prose--after{margin:var(--s-5) 0 0}
.auth strong{color:var(--text)}

/* A disclosure that looks like the cards around it. Native <details>, so it
   works with JavaScript off - which the Bootstrap modal it replaced did not. */
.disclose{
  margin-top:var(--s-4);
  padding:var(--s-4) var(--s-4);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r);
}
.disclose > summary{
  cursor:pointer;list-style:none;
  display:flex;align-items:center;gap:var(--s-3);
  font-size:var(--t-sm);font-weight:600;
}
.disclose > summary::-webkit-details-marker{display:none}
.disclose > summary::after{
  content:"";margin-left:auto;flex:none;width:9px;height:9px;
  border-right:2px solid var(--faint);border-bottom:2px solid var(--faint);
  transform:rotate(45deg) translateY(-2px);
  transition:transform var(--d) var(--e-out);
}
.disclose[open] > summary::after{transform:rotate(-135deg) translateY(-2px)}
.disclose form{margin-top:var(--s-4)}
.disclose .hint{margin-bottom:var(--s-4);color:var(--muted);font-size:var(--t-xs)}

/* =========================================================================
   19. Features index
   =========================================================================
   /features is thirty items in seven groups, and it was seven identical
   grids stacked on each other - the same card at the same width in the same
   rhythm, thirty times. Nothing told you which group you were in, how many
   were in it, or how much was left.

   So it is laid out as a contents page rather than a pitch. A sticky index
   runs across the top, and each group gets a rail carrying its number, its
   name and its count. The rail is what makes one group distinguishable from
   the next; it sticks beside its own cards on a wide screen and folds into
   an ordinary heading on a narrow one.
   ====================================================================== */

/* ---- the hero's contents card ------------------------------------------
   Used by /features, /pricing, /how-it-works and /contact. Where the home
   page's .showcase invents a panel to look at, this one mirrors the page it
   sits on - its areas, its plans, its steps - so the hero previews the page
   instead of decorating it.

   Rows are tighter than the home page's: those pages carry up to seven, and at
   the home page's padding the card outgrew the copy beside it and dragged the
   whole hero taller than a laptop viewport.

   The count is a neutral pill, not the green .pill: green is this site's "on /
   issued / connected", and a number is not a status. Neutral also keeps the
   accent rare, which is what makes it mean something where it is used. */
.showcase--map .showcase__row{padding:var(--s-2) var(--s-3);gap:var(--s-2)}

/* Desktop only, unlike the home page's showcase. The point of this one is to
   fill the half of a wide hero that was empty; below 1000px the hero is a
   single column, so it fills nothing and instead adds a card's worth of scroll
   repeating what sits immediately underneath it - and what sits underneath is
   real text and real links a reader can actually use. */
@media (max-width:999.98px){ .showcase--map{display:none} }
.pill--n{
  background:var(--surface-3);border-color:var(--border-2);color:var(--muted);
  font-variant-numeric:tabular-nums;
}

/* ---- the tally under the hero ------------------------------------------ */
.fx-tally{
  display:flex;flex-wrap:wrap;gap:var(--s-3);
  margin-top:var(--s-8);padding:0;list-style:none;
}
.fx-tally li{
  display:flex;align-items:baseline;gap:var(--s-2);
  padding:var(--s-3) var(--s-4);
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:var(--r);
  box-shadow:var(--sh-xs);
}
.fx-tally b{
  font-size:var(--t-xl);font-weight:700;
  letter-spacing:var(--tr-tight);
  font-variant-numeric:tabular-nums;
}
.fx-tally span{color:var(--muted);font-size:var(--t-sm)}

/* ---- the sticky index --------------------------------------------------
   Under the header rather than over it: .site-hdr is sticky at 0 and
   --hdr-h tall, so this sits at exactly that offset and one z-index below. */
.fx-index{
  position:sticky;top:var(--hdr-h);z-index:30;
  background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:blur(12px) saturate(1.5);
  -webkit-backdrop-filter:blur(12px) saturate(1.5);
  border-block:1px solid var(--border);
}
.fx-index__in{
  display:flex;gap:var(--s-2);
  padding-block:var(--s-3);
  overflow-x:auto;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
}
.fx-index__in::-webkit-scrollbar{display:none}
.fx-index a{
  flex:none;
  display:inline-flex;align-items:center;gap:var(--s-2);
  padding:6px var(--s-3);
  border:1px solid var(--border);
  border-radius:var(--r-pill);
  background:var(--surface);
  color:var(--muted);
  font-size:var(--t-sm);font-weight:550;
  text-decoration:none;white-space:nowrap;
  transition:color var(--d) var(--e-out),
             border-color var(--d) var(--e-out),
             background var(--d) var(--e-out);
}
.fx-index a em{
  font-style:normal;
  font-variant-numeric:tabular-nums;
  color:var(--faint);
  font-size:var(--t-xs);font-weight:650;
  letter-spacing:var(--tr-wide);
}
@media (hover:hover){
  .fx-index a:hover{color:var(--text);border-color:var(--border-2)}
}
.fx-index a.is-here{background:var(--primary);border-color:var(--primary);color:var(--invert)}
.fx-index a.is-here em{color:color-mix(in srgb,var(--invert) 62%,transparent)}

/* ---- a group ------------------------------------------------------------ */
.fx-sec{
  position:relative;z-index:1;
  padding-block:clamp(var(--s-10),5vw,var(--s-16));
  border-top:1px solid var(--border);
  /* Clear the header and the index bar when a chip jumps here. */
  scroll-margin-top:calc(var(--hdr-h) + 58px);
}
.fx-sec:first-of-type{border-top:0}

.fx-sec__in{display:grid;gap:var(--s-6)}
@media (min-width:1040px){
  .fx-sec__in{grid-template-columns:250px minmax(0,1fr);gap:var(--s-12)}
}

.fx-rail{align-self:start}
@media (min-width:1040px){
  .fx-rail{position:sticky;top:calc(var(--hdr-h) + 76px)}
}
.fx-rail__num{
  display:block;
  font-size:var(--t-3xl);font-weight:750;
  line-height:1;letter-spacing:var(--tr-tight);
  font-variant-numeric:tabular-nums;
  color:var(--border-2);
}
.fx-rail h2{margin-top:var(--s-3);font-size:var(--t-2xl);letter-spacing:var(--tr-tight)}
.fx-rail p{margin-top:var(--s-3);color:var(--muted);font-size:var(--t-sm);max-width:34ch}
.fx-rail__count{
  display:inline-block;margin-top:var(--s-4);
  padding:3px var(--s-3);border-radius:var(--r-pill);
  background:var(--surface-2);border:1px solid var(--border);
  color:var(--muted);font-size:var(--t-xs);font-weight:650;
  letter-spacing:var(--tr-wide);text-transform:uppercase;
}

/* One column on a phone, two once there is room, three on a wide screen -
   the rail takes 250px of it, so the count is set by what is left. */
.fx-grid{
  display:grid;gap:var(--s-4);
  grid-template-columns:repeat(auto-fit,minmax(232px,1fr));
}
