/* ===========================================================================
   Impulse Cart — landing page
   ---------------------------------------------------------------------------
   Retheme 2026-08-31 to the "frosted glass cathedral at midnight" system in
   DESIGN.md. The LAYOUT and the COPY are untouched: this file swaps the design
   system underneath them and nothing else, which is why the whole retheme is a
   token block plus an atmosphere layer rather than a rewrite.

   THE THREE THINGS THAT MAKE IT THIS AND NOT JUST "DARK MODE":

     1. Surfaces are GLASS, not paper. Every card is a barely-there frost tint
        over the canvas with an inset hairline, lit from behind. There are no
        solid panel fills and no hard borders anywhere.
     2. Elevation is INSET GLOW plus a cool dark halo, never a conventional drop
        shadow. A card should read as a lit plate, not a raised sheet.
     3. ONE chromatic accent, the violet, and it is spent on the primary action
        only. Everything else lives in the blue-white progression.

   Dark-first and dark-only. The old light/dark toggle stays in the markup and
   still works, but both states are now the same midnight room: the design is
   dark by definition and a light variant would be a different product.
   =========================================================================== */

:root{
  /* ---- Palette (DESIGN.md tokens, named as this file already named them) --- */
  --canvas:#070707;          /* the base: true neutral near-black               */
  --steel:#353535;           /* elevated fill for ghost buttons                 */
  --ice:#e8e8e8;             /* headings                                        */
  --frost:#e2e2e2;           /* default foreground                              */
  --mist:#d2d2d2;            /* muted body                                      */
  --fog:#a7a7a7;             /* helper copy                                     */
  /* THE ACCENT. Was a #663af3 violet, which is the single most-generated
     colour on the web and read as exactly that. Orange is the complement of the
     blue-white this whole page is built from, so it is the one hue that lifts
     off this canvas instead of sitting in it, and almost nothing reaches for it.

     It carries near-black text, never white: white on an orange bright enough to
     look good measures 2.9:1 and fails. Dark-on-bright measures 6.8:1, and it is
     also what stops the button reading as a stock call to action. */
  --violet:#00779C;
  /* White, now that the accent is dark enough to carry it: 5.1:1. The
     brighter blue could not - white on it measured 3.39 and failed - which is
     why the earlier accents wore a near-black instead. */
  --violet-ink:#ffffff;
  /* Hover lifts, but only as far as white still passes on it (4.58:1).
     Any brighter and the button gets more attractive and less readable at the
     same moment. */
  --violet-hi:#007FA6;
  --blueprint:#d8d8d8;

  /* The universal hairline. Never a solid stroke: an inset frosted edge is the
     border language of the whole system. */
  --hair:rgba(232,232,232,.12);
  --hair-strong:rgba(232,232,232,.24);
  --frost-wash:rgba(232,232,232,.06);
  --frost-tint:rgba(232,232,232,.03);
  --lumen:rgba(210,210,210,.12);

  /* Skywash: reserved for the wordmark and the largest headings. Never on body
     text and never on a button. */
  /* Emphasis inside a headline. A second flat colour, one step brighter than
     the heading colour, so <em> reads as a lift rather than a wash. */
  --frost-em:#4EC3E8;

  /* ---- Mapped onto the names the existing stylesheet already uses --------- */
  --blue:var(--violet);
  --blue-2:var(--violet-hi);
  --indigo:var(--violet);
  --purple:var(--violet-hi);
  --gradient:linear-gradient(135deg,#00779C 0%,#2F52A4 100%);
  --blue-text:var(--frost);
  --blue-line:var(--hair);

  --ink:var(--ice);
  --body:var(--mist);
  --muted:var(--mist);
  --faint:var(--fog);

  --bg:var(--canvas);
  --surface:var(--frost-tint);
  --surface-alt:rgba(232,232,232,.045);
  --blue-soft:rgba(0,119,156,.14);
  --border:var(--hair);
  --border-2:rgba(232,232,232,.06);

  /* Success keeps a hue only where it means "this is done", never decoratively. */
  --green:#5ad1a8; --green-ink:#8fe3c6;
  --green-soft:rgba(90,209,168,.10); --green-line:rgba(90,209,168,.26);

  /* ELEVATION IS INSET, per DESIGN.md. The outer halo is cool and dark rather
     than neutral black, so lift reads as tinted light instead of a shadow. */
  --shadow-sm:inset 0 0 0 1px rgba(232,232,232,.12), 0 8px 20px rgba(7,7,7,.55);
  --shadow-md:inset 0 1px 1px rgba(210,210,210,.12),
              inset 0 24px 48px rgba(210,210,210,.05),
              0 24px 32px rgba(7,7,7,.7);
  --shadow-lg:inset 0 1px 1px rgba(235,235,235,.2),
              inset 0 24px 48px rgba(220,220,220,.06),
              0 16px 32px rgba(0,0,0,.3);
  --shadow-blue:0 0 6px rgba(232,232,232,.32), 0 0 18px rgba(0,119,156,.28);

  /* Radius families, kept apart on purpose: pill for anything you press, 16px
     for cards, 6px for badges and inputs. Mixing them is the fastest way to
     lose the look. */
  --r-sm:6px; --r-md:999px; --r-lg:16px; --r-xl:16px;
  --r-card:16px; --r-badge:6px; --r-input:6px; --r-pill:999px;

  --font:'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --display:'Space Grotesk', var(--font);
  --mono:'JetBrains Mono', ui-monospace, 'Cascadia Code', Consolas, monospace;

  --maxw:1200px;
  --ease:cubic-bezier(.22,1,.36,1);
  --z-nav:40; --z-top:50;

  --tint1:transparent; --tint2:transparent;

  color-scheme:dark;
}

/* The toggle stays in the markup and still flips, but both states are midnight:
   this design IS dark. A light variant is a different product, not a setting. */
:root[data-theme="dark"]{ color-scheme:dark; }

*{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion: reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0; color:var(--body);
  background:
    radial-gradient(circle at 12% -4%, var(--tint1), transparent 30%),
    radial-gradient(circle at 88% -6%, var(--tint2), transparent 28%),
    var(--bg);
  font-family:var(--font); font-size:17px; line-height:1.65; letter-spacing:-.006em;
  /* TWO THINGS DELIBERATELY NOT SET HERE.

     -webkit-font-smoothing:antialiased is a Mac habit that does real damage on
     Windows: it turns ClearType subpixel rendering off and every letter on the
     page goes soft.

     text-rendering:optimizeLegibility used to be here too. It asks the browser
     for ligatures and kerning it would otherwise skip, and on Windows that
     pushes glyph positions off the pixel grid - the same softening, arrived at
     from a different direction, and for a gain nobody can see at these sizes.

     Left alone, the OS renders type the way that OS renders type, which is
     always sharper than us overriding it. */
}
h1,h2,h3,h4{ color:var(--ink); font-family:var(--font); }
a{ color:inherit; text-decoration:none; }
b,strong{ color:var(--ink); font-weight:650; }
img,svg{ display:block; max-width:100%; }
html, body{ overflow-x:clip; }
.wrap{ max-width:var(--maxw); margin:0 auto; padding:0 clamp(22px,5.5vw,40px); }
.mono-num{ font-variant-numeric:tabular-nums; font-feature-settings:'tnum' 1; }

:focus-visible{ outline:2px solid var(--blue); outline-offset:3px; border-radius:4px; }

.icon{ width:22px; height:22px; stroke:currentColor; stroke-width:1.7; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }

/* ---- Buttons (equal heights everywhere) --------------------------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  height:48px; padding:0 26px; border-radius:var(--r-md); border:0;
  font:inherit; font-size:1rem; font-weight:650; letter-spacing:-.008em;
  cursor:pointer; white-space:nowrap;
  transition:transform .2s var(--ease), box-shadow .2s ease, border-color .2s ease, filter .2s ease;
}
.btn svg{ width:18px; height:18px; stroke:currentColor; stroke-width:2; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.btn-primary{ background:var(--gradient); color:#fff; box-shadow:var(--shadow-blue); }
.btn-primary:hover{ transform:translateY(-2px); box-shadow:0 12px 26px rgba(0,119,156,.3); }
.btn-ghost{ background:var(--surface); color:var(--ink); border:1px solid var(--border); box-shadow:var(--shadow-sm); }
.btn-ghost:hover{ transform:translateY(-2px); border-color:color-mix(in srgb, var(--blue) 32%, var(--border)); box-shadow:var(--shadow-md); }
.btn-white{ background:#fff; color:var(--indigo); box-shadow:0 10px 24px rgba(19,19,19,.22); }
.btn-white:hover{ transform:translateY(-2px); box-shadow:0 14px 30px rgba(19,19,19,.28); }
.btn .fx-a{ display:inline-block; transition:transform .25s var(--ease); }
.btn:hover .fx-a{ transform:translateX(4px); }
@media (prefers-reduced-motion: reduce){
  .btn:hover{ transform:none; }
  .btn:hover .fx-a{ transform:none; }
}

/* ---- Nav ---------------------------------------------------------------- */
.nav{
  position:sticky; top:0; z-index:var(--z-nav);
  background:transparent;
  border-bottom:1px solid var(--border-2);
}
/* THE TINT AND THE BLUR SIT ON A PSEUDO-ELEMENT, NOT ON THE BAR ITSELF.

   backdrop-filter promotes its own element to a compositing layer, and Chrome
   on Windows renders every DESCENDANT of a composited layer with grayscale
   antialiasing instead of ClearType subpixel. With the filter on .nav, the nav
   links and the Get Impulse Cart button lost subpixel rendering and read
   visibly soft against crisp body text one line below. Owner, 2026-09-01:
   *"button text look blurry as hell"* - and it was, on exactly those words.

   Blurring a SIBLING instead of an ancestor fixes it. The pseudo-element
   carries the tint and the blur behind the row; the text stays on the ordinary
   layer and keeps its subpixel edges. The bar looks identical.

   This is why .nav must stay transparent: ::before sits at z-index -1, so a
   background on .nav itself would paint straight over it. */
.nav::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:color-mix(in srgb, var(--bg) 80%, transparent);
  -webkit-backdrop-filter:saturate(160%) blur(12px);
          backdrop-filter:saturate(160%) blur(12px);
}
.nav-in{ max-width:var(--maxw); margin:0 auto; padding:0 clamp(20px,4vw,40px);
  height:68px; display:flex; align-items:center; gap:28px; }
.logo{ display:inline-flex; align-items:center; gap:11px; color:var(--ink);
  font-weight:750; letter-spacing:-.025em; font-size:1.08rem; }
.logo-mark{ display:grid; place-items:center; color:var(--blue-text); flex:0 0 auto; }
.logo-mark svg{ width:27px; height:27px; stroke:currentColor; stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.nav-links{ display:flex; gap:4px; margin-left:auto; }
.nav-links a{ padding:9px 14px; border-radius:9px; color:var(--body); font-size:.95rem;
  font-weight:550; transition:color .15s ease, background .15s ease; }
.nav-links a:hover{ color:var(--ink); background:var(--surface-alt); }
.nav .btn{ height:42px; padding:0 20px; font-size:.93rem; }
.theme-btn{ display:inline-flex; align-items:center; gap:7px; height:42px; padding:0 14px;
  border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface); color:var(--body);
  font:inherit; font-size:.88rem; cursor:pointer; transition:border-color .15s ease, color .15s ease; }
.theme-btn:hover{ border-color:color-mix(in srgb, var(--blue) 32%, var(--border)); color:var(--ink); }
.theme-btn svg{ width:15px; height:15px; stroke:currentColor; stroke-width:1.9; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
/* Hamburger: mobile only. Same 42px height as the theme button beside it. */
.nav-toggle{ display:none; width:42px; height:42px; padding:0; place-items:center;
  border:1px solid var(--border); border-radius:var(--r-md); background:var(--surface);
  color:var(--body); cursor:pointer; transition:border-color .15s ease, color .15s ease; }
.nav-toggle:hover{ border-color:color-mix(in srgb, var(--blue) 32%, var(--border)); color:var(--ink); }
.nav-toggle svg{ width:20px; height:20px; stroke:currentColor; stroke-width:2; fill:none;
  stroke-linecap:round; }

/* Menu panel. Fixed, not absolute: the nav's backdrop-filter creates a
   containing block, so an absolute panel would be clipped by it. */
.nav-menu{ position:fixed; top:68px; left:0; right:0; z-index:var(--z-nav);
  display:flex; flex-direction:column; gap:2px;
  padding:10px clamp(20px,4vw,40px) 18px;
  background:var(--bg); border-bottom:1px solid var(--border-2); box-shadow:var(--shadow-lg);
  transform:translateY(-8px); opacity:0; transition:transform .22s var(--ease), opacity .18s ease; }
.nav-menu[hidden]{ display:none; }
.nav-menu.open{ transform:none; opacity:1; }
.nav-menu a{ display:flex; align-items:center; min-height:48px; padding:0 12px;
  border-radius:10px; color:var(--body); font-size:1rem; font-weight:550;
  transition:color .15s ease, background .15s ease; }
.nav-menu a:hover{ color:var(--ink); background:var(--surface-alt); }
/* The links above scroll within this page; the ones below leave it. A hairline
   marks the change so the two kinds don't read as one undifferentiated list. */
.nav-menu-sep{ margin-top:8px; padding-top:10px !important;
  border-top:1px solid var(--border-2); border-radius:10px 10px 0 0 !important; }
.nav-menu .btn{ justify-content:center; margin-top:12px; height:48px; }
.nav-menu .btn:hover{ transform:none; }

.nav-scrim{ position:fixed; inset:68px 0 0; z-index:calc(var(--z-nav) - 1);
  background:rgba(19,19,19,.32); opacity:0; transition:opacity .18s ease; }
.nav-scrim[hidden]{ display:none; }
.nav-scrim.open{ opacity:1; }

@media (prefers-reduced-motion: reduce){
  .nav-menu{ transition:opacity .01ms; transform:none; }
  .nav-scrim{ transition:opacity .01ms; }
}

/* The nav CTA is dropped below 820px: logo + theme button + hamburger already
   fill a 360px viewport, and keeping it forced the page to scroll sideways.
   The same CTA lives inside the menu, so nothing is lost. */
@media (max-width:820px){
  .nav-links{ display:none; }
  .nav-cta{ display:none; }
  .nav-toggle{ display:grid; }
  .nav-in{ gap:12px; }
  .logo{ margin-right:auto; min-width:0; }
}
@media (min-width:821px){
  .nav-menu, .nav-scrim{ display:none !important; }
}
@media (max-width:400px){
  .theme-btn #tlbl{ display:none; }
  .theme-btn{ width:42px; padding:0; justify-content:center; }
}

/* ---- Hero --------------------------------------------------------------- */
.hero{ padding:clamp(56px,9vw,104px) clamp(22px,5.5vw,40px) clamp(28px,4vw,44px); text-align:center; }
.hero-badge{
  display:inline-flex; align-items:center; gap:9px; padding:8px 16px;
  border-radius:999px; background:var(--surface); border:1px solid var(--border);
  box-shadow:var(--shadow-sm); color:var(--body); font-size:.88rem; font-weight:550;
}
.hero-badge .beat{ width:8px; height:8px; border-radius:50%; background:var(--green); flex:0 0 auto; }
.hero-badge b{ font-weight:650; }
.hero h1{
  margin:clamp(22px,3.4vw,34px) auto 0; max-width:15ch;
  font-size:clamp(2.7rem,1.5rem + 5vw,4.6rem); line-height:1.02;
  letter-spacing:-.038em; font-weight:750; text-wrap:balance;
}
.hero h1 em{ font-style:normal; color:var(--blue-text); }
.hero .sub{
  margin:clamp(20px,2.6vw,28px) auto 0; max-width:56ch;
  font-size:clamp(1.05rem,1rem + .4vw,1.22rem); line-height:1.6; text-wrap:pretty;
}
.hero .sub b{ font-weight:650; }
.hero-price{ display:flex; flex-direction:column; align-items:center; gap:8px;
  margin:clamp(26px,3.6vw,38px) 0 0; }
.hp-num{ font-weight:750; font-size:clamp(2.8rem,2rem + 3.6vw,4rem); line-height:1;
  letter-spacing:-.04em; color:var(--ink); font-variant-numeric:tabular-nums; font-feature-settings:'tnum' 1; }
.hp-per{ font-size:.36em; font-weight:600; color:var(--muted); letter-spacing:normal; margin-left:9px; }
.hp-tag{ color:var(--muted); font-size:1rem; }
.hero-cta{ display:flex; flex-wrap:wrap; justify-content:center; gap:14px;
  margin-top:clamp(24px,3.2vw,34px); }

/* ---- Device stage ------------------------------------------------------- */
.stage{ position:relative; padding:clamp(20px,3.4vw,44px) 0 clamp(48px,7vw,84px); }

/* Real screenshot, anchored to the top so the shop nav is always in frame. */

/* storefront drawn inside the laptop */
.s-nav .on{ color:var(--blue); position:relative; }
.s-nav .on::after{ content:""; position:absolute; height:1.5px; background:var(--blue); left:0; right:0; bottom:-13px; }
.s-nav .s-ico{ display:flex; gap:9px; color:#646464; }
.s-nav .s-ico svg{ width:9px; height:9px; stroke-width:2; }
.s-card{ border:1px solid #e6e6e6; border-radius:6px; padding:5px; background:#fff; }
.s-thumb{ background:linear-gradient(145deg,#ffffff,#f4f4f4); border-radius:4px; display:grid; place-items:center; padding:6%; }
.s-thumb svg{ width:82%; height:auto; }
.s-card b{ display:block; margin-top:6px; font-size:clamp(5.5px,.85vw,7.5px); color:#242424; }
.s-card span{ display:block; margin-top:2px; font-size:clamp(5.5px,.85vw,7.5px); font-weight:750; color:#131313; }

/* Real phone screenshot, kept at its own proportions so nothing is cropped. */
@media (max-width:640px){ .phone{ display:none; } .laptop-screen{ aspect-ratio:16/11; } }

/* ---- Vendor strip ------------------------------------------------------- */
/* THE SIDE PADDING REPEATS .wrap ON PURPOSE. This element carries both
   classes, and a shorthand `padding` here with 0 on the sides silently
   cancelled the gutter .wrap had already set - so on a phone the vendor pills
   ran to within 9px of both screen edges while every other block on the page
   sat 28px in. Restating the same clamp keeps the shorthand and the gutter. */
.vendors{ padding:clamp(10px,2vw,20px) clamp(22px,5.5vw,40px) clamp(40px,6vw,64px);
  text-align:center; }
.vendors p{ margin:0 0 20px; color:var(--muted); font-size:.9rem; font-weight:550; }
.vendor-row{ display:flex; flex-wrap:wrap; justify-content:center; gap:10px 12px; }
.vendor{ display:inline-flex; align-items:center; gap:9px; height:44px; padding:0 18px;
  border:1px solid var(--border); border-radius:999px; background:var(--surface);
  color:var(--ink); font-weight:650; font-size:.95rem; letter-spacing:-.012em; box-shadow:var(--shadow-sm); }
.vendor svg{ width:16px; height:16px; stroke:var(--blue-text); stroke-width:1.9; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
.vendor small{ font-weight:500; color:var(--muted); font-size:.8em; }

/* ---- Stat band ---------------------------------------------------------- */
.stats{ margin-bottom:clamp(56px,8vw,96px); }
.stats-in{ display:grid; grid-template-columns:repeat(4,1fr); border-radius:var(--r-lg);
  background:var(--surface); border:1px solid var(--border); box-shadow:var(--shadow-sm); overflow:hidden; }
.stat{ padding:clamp(20px,3vw,30px) clamp(18px,2.6vw,30px); }
.stat + .stat{ border-left:1px solid var(--border-2); }
.stat .v{ font-weight:750; font-size:clamp(1.8rem,3vw,2.4rem); letter-spacing:-.035em; color:var(--ink); line-height:1.1; }
.stat .v .u{ font-size:.55em; color:var(--muted); font-weight:650; letter-spacing:normal; }
.stat .k{ margin-top:6px; color:var(--muted); font-size:.88rem; line-height:1.4; }
@media (max-width:820px){
  .stats-in{ grid-template-columns:1fr 1fr; }
  .stat:nth-child(3){ border-left:0; }
  .stat:nth-child(-n+2){ border-bottom:1px solid var(--border-2); }
}

/* ---- Section headers ---------------------------------------------------- */
.sec-head{ max-width:720px; margin:0 auto clamp(34px,5vw,52px); text-align:center; }
.sec-head h2{ margin:0; font-size:clamp(1.9rem,1.3rem + 2.6vw,2.9rem); line-height:1.08;
  letter-spacing:-.032em; font-weight:750; text-wrap:balance; }
.sec-head p{ margin:16px auto 0; max-width:58ch; color:var(--muted);
  font-size:clamp(1rem,1.3vw,1.12rem); text-wrap:pretty; }

/* ---- Bento highlights --------------------------------------------------- */
.bento-sec{ padding-bottom:clamp(56px,8vw,96px); }
.bento{ display:grid; grid-template-columns:repeat(6,1fr); gap:14px; }
.bcard{ grid-column:span 2; border:1px solid var(--border); border-radius:var(--r-lg);
  background:var(--surface); box-shadow:var(--shadow-sm); padding:26px 26px 24px;
  display:flex; flex-direction:column; gap:8px; overflow:hidden;
  transition:transform .25s var(--ease), box-shadow .25s ease; }
.bcard:hover{ transform:translateY(-4px); box-shadow:var(--shadow-md); }
@media (prefers-reduced-motion: reduce){ .bcard:hover{ transform:none; } }
.bcard.wide{ grid-column:span 3; }
.bcard h3{ margin:0; font-size:1.14rem; letter-spacing:-.018em; font-weight:700; }
.bcard p{ margin:0; color:var(--muted); font-size:.95rem; line-height:1.55; text-wrap:pretty; }
.bico{ width:40px; height:40px; border-radius:11px; margin-bottom:8px;
  display:grid; place-items:center; background:var(--blue-soft); color:var(--blue-text);
  border:1px solid var(--blue-line); }
.bviz{ margin-top:auto; padding-top:18px; }
@media (max-width:960px){ .bcard, .bcard.wide{ grid-column:span 3; } }
@media (max-width:640px){ .bcard, .bcard.wide{ grid-column:span 6; } }

.bcard.full{ grid-column:span 6; flex-direction:row; align-items:center; gap:clamp(24px,4vw,56px); }
.bcard.full .full-copy{ flex:1 1 52%; display:flex; flex-direction:column; gap:8px; }
.bcard.full .bviz{ flex:1 1 48%; margin-top:0; padding-top:0; }
@media (max-width:860px){ .bcard.full{ flex-direction:column; align-items:stretch; }
  .bcard.full .bviz{ padding-top:14px; } }

/* small graphics inside bento cards */
.viz-products{ display:grid; grid-template-columns:repeat(3,1fr); gap:11px; }
.viz-products .s-card{ padding:10px; border-radius:10px; border-color:var(--border-2); }
.viz-products .s-thumb{ border-radius:8px; padding:10%; }
.viz-products .s-card b{ font-size:.82rem; margin-top:9px; }
.viz-products .s-card span{ font-size:.82rem; margin-top:2px; }
.viz-types{ display:grid; grid-template-columns:repeat(3,1fr); gap:9px; }
.viz-type{ border:1px solid var(--border-2); border-radius:10px; background:var(--surface-alt);
  padding:12px 10px; text-align:center; }
.viz-type svg{ width:20px; height:20px; margin:0 auto 7px; stroke:var(--blue-text); stroke-width:1.7;
  fill:none; stroke-linecap:round; stroke-linejoin:round; }
.viz-type b{ display:block; font-size:.78rem; color:var(--ink); letter-spacing:-.01em; }
.viz-type span{ display:block; margin-top:2px; font-size:.72rem; color:var(--muted); line-height:1.35; }
.viz-blocks{ display:grid; gap:7px; }
.viz-block{ display:flex; align-items:center; gap:10px; border:1px solid var(--border-2);
  background:var(--surface-alt); border-radius:9px; padding:9px 12px; font-size:.8rem; color:var(--body); }
.viz-block i{ font-style:normal; color:var(--faint); font-size:.85rem; letter-spacing:1px; }
.viz-block b{ font-weight:600; font-size:.8rem; }
.viz-block span{ margin-left:auto; font-size:.7rem; color:var(--muted);
  border:1px solid var(--border); border-radius:5px; padding:2px 7px; background:var(--surface); }
.viz-checkout{ border:1px solid var(--border-2); border-radius:12px; background:var(--surface-alt); padding:14px 15px; }
.viz-checkout .row{ display:flex; justify-content:space-between; font-size:.8rem; color:var(--body); padding:4px 0; }
.viz-checkout .row.total{ border-top:1px solid var(--border); margin-top:6px; padding-top:9px;
  font-weight:700; color:var(--ink); }
.viz-pay{ margin-top:11px; height:34px; border-radius:8px; background:var(--gradient); color:#fff;
  display:flex; align-items:center; justify-content:center; gap:7px; font-size:.8rem; font-weight:700; }
.viz-pay svg{ width:13px; height:13px; stroke:currentColor; stroke-width:2; fill:none; stroke-linecap:round; }
.viz-chart{ display:flex; align-items:flex-end; gap:7px; height:86px; padding:4px 2px 0; }
.viz-chart i{ flex:1; border-radius:5px 5px 2px 2px; background:linear-gradient(180deg, rgba(210,210,210,.34), rgba(210,210,210,.6));
  min-height:12%; }
.viz-chart i:nth-child(4){ background:linear-gradient(180deg, var(--violet-hi), var(--violet)); }
.viz-dl{ display:grid; gap:8px; }
.viz-file{ display:flex; align-items:center; gap:10px; border:1px solid var(--border-2);
  background:var(--surface-alt); border-radius:9px; padding:10px 12px; font-size:.8rem; color:var(--body); }
.viz-file svg{ width:15px; height:15px; stroke:var(--blue-text); stroke-width:1.9; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
.viz-file b{ font-weight:600; font-size:.8rem; }
.viz-file span{ margin-left:auto; font-size:.7rem; color:var(--green-ink); background:var(--green-soft);
  border:1px solid var(--green-line); border-radius:5px; padding:2px 8px; white-space:nowrap; }

/* ---- Feature manifest --------------------------------------------------- */
.manifest{ padding-bottom:clamp(56px,8vw,96px); }
.areas{ display:grid; gap:12px; }
.area{ border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface);
  box-shadow:var(--shadow-sm); overflow:hidden; }
.area summary{ list-style:none; cursor:pointer; display:flex; align-items:center; gap:16px;
  padding:20px 24px; transition:background .15s ease; }
.area summary::-webkit-details-marker{ display:none; }
.area summary:hover{ background:var(--surface-alt); }
.a-ico{ width:38px; height:38px; border-radius:10px; flex:0 0 auto;
  display:grid; place-items:center; background:var(--blue-soft); color:var(--blue-text); border:1px solid var(--blue-line); }
.a-ico svg{ width:19px; height:19px; stroke:currentColor; stroke-width:1.7; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.a-name{ min-width:0; }
.a-name h3{ margin:0; font-size:1.05rem; letter-spacing:-.015em; font-weight:700; }
.a-name span{ display:block; color:var(--muted); font-size:.85rem; margin-top:1px; }
.a-count{ margin-left:auto; flex:0 0 auto; color:var(--muted); font-size:.82rem; font-weight:600;
  background:var(--surface-alt); border:1px solid var(--border-2); border-radius:999px; padding:4px 12px; }
.a-chev{ flex:0 0 auto; width:20px; height:20px; color:var(--faint); transition:transform .25s var(--ease); }
.a-chev svg{ width:20px; height:20px; stroke:currentColor; stroke-width:2; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.area[open] .a-chev{ transform:rotate(180deg); }
.a-body{ display:grid; grid-template-columns:1fr 1fr; gap:2px 28px;
  padding:6px 24px 22px; border-top:1px solid var(--border-2); }
@media (max-width:680px){ .a-body{ grid-template-columns:1fr; } .a-count{ display:none; } }
.feat{ display:flex; gap:11px; padding:11px 0; align-items:flex-start; }
.f-check{ flex:0 0 auto; width:19px; height:19px; margin-top:3px; border-radius:50%;
  background:var(--green-soft); color:var(--green-ink); display:grid; place-items:center; }
.f-check svg{ width:11px; height:11px; stroke:currentColor; stroke-width:2.6; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
/* The one thing Core does NOT have. Same shape and weight as the tick so the
   list still scans as one column, red so the difference is the thing you see
   first rather than something to work out by comparing two cards. */
.f-cross{ flex:0 0 auto; width:19px; height:19px; margin-top:3px; border-radius:50%;
  background:rgba(220,38,38,.10); color:#dc2626; display:grid; place-items:center; }
.f-cross svg{ width:11px; height:11px; stroke:currentColor; stroke-width:2.6; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.tier-list .f-cross{ margin-top:2px; width:18px; height:18px; }
.tier-list li.is-out{ color:var(--muted); }
.feat > span:last-child{ flex:1; min-width:0; display:block; }
.feat > span:last-child > b{ display:block; font-size:.94rem; line-height:1.5; letter-spacing:-.01em; }
.feat > span:last-child > span{ display:block; color:var(--muted); font-size:.86rem; line-height:1.5; margin-top:2px; text-wrap:pretty; }
.manifest-note{ margin:18px auto 0; text-align:center; color:var(--muted); font-size:.9rem; }
.manifest-note b{ font-weight:650; }

/* ---- Themes ------------------------------------------------------------- */
.themes-sec{ padding-bottom:clamp(56px,8vw,96px); }
.themes-in{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(28px,4.5vw,60px); align-items:center; }
@media (max-width:860px){ .themes-in{ grid-template-columns:1fr; } }
.themes-copy h2{ margin:0; font-size:clamp(1.8rem,1.3rem + 2.2vw,2.6rem); line-height:1.1;
  letter-spacing:-.03em; font-weight:750; text-wrap:balance; }
.themes-copy > p{ margin:16px 0 0; color:var(--muted); font-size:1.04rem; max-width:52ch; text-wrap:pretty; }
.themes-points{ margin:22px 0 0; padding:0; list-style:none; display:grid; gap:10px; }
.themes-points li{ display:flex; gap:11px; align-items:flex-start; font-size:.97rem; color:var(--body); }
.themes-points .f-check{ margin-top:3px; }
.themes-cta{ display:flex; flex-wrap:wrap; gap:12px; margin-top:28px; }
.theme-cards{ display:grid; gap:14px; }
.tcard{ border-radius:var(--r-lg); border:1px solid var(--border); overflow:hidden;
  box-shadow:var(--shadow-md); background:var(--surface);
  transition:transform .25s var(--ease), box-shadow .25s ease; }
.tcard:hover{ transform:translateY(-4px); box-shadow:var(--shadow-lg); }
@media (prefers-reduced-motion: reduce){ .tcard:hover{ transform:none; } }
.t-meta{ display:flex; align-items:baseline; gap:10px; padding:13px 18px 15px;
  border-top:1px solid var(--border-2); background:var(--surface); }
.t-meta b{ font-size:.97rem; }
.t-meta span{ color:var(--muted); font-size:.86rem; }
.t-meta em{ font-style:normal; margin-left:auto; font-weight:700; color:var(--ink); font-size:.95rem; }

/* ---- Pricing ------------------------------------------------------------ */
.pricing{ padding-bottom:clamp(48px,7vw,80px); }
/* THE PRICING BAND IS WIDER THAN THE REST OF THE PAGE, on purpose. Four cards
   inside the site's 1180 leaves each one about 263px, where the feature lines
   break after two or three words and the cards read as cramped. 1360 gives them
   about 308px each and one clean row. It is wide enough to look deliberate
   rather than like a section that missed its container. */
.pricing.wrap{ max-width:min(1600px, 96vw); }
.tiers{ display:grid; grid-template-columns:repeat(4,1fr); gap:16px; align-items:stretch; }
/* Two up before the single column. The breakpoint is arithmetic, not taste:
   four cards want 300px each to keep a feature line above two words, and
   4x300 + 3x16 gap + 80 padding is 1328. Below that they drop to two. */
@media (max-width:1330px){ .tiers{ grid-template-columns:repeat(2,1fr); max-width:760px; margin:0 auto; } }
@media (max-width:640px){ .tiers{ grid-template-columns:1fr; max-width:460px; margin:0 auto; } }
.tier{ position:relative; display:flex; flex-direction:column; border:1px solid var(--border);
  border-radius:var(--r-lg); background:var(--surface); box-shadow:var(--shadow-sm);
  padding:30px 28px 28px; }
.tier-mid{ border-color:transparent; box-shadow:var(--shadow-lg); }
.tier-mid::before{ content:""; position:absolute; inset:0; border-radius:inherit; padding:2px;
  background:var(--gradient); -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude; pointer-events:none; }
.tier-flag{ position:absolute; top:-13px; left:50%; transform:translateX(-50%);
  background:var(--gradient); color:#fff; font-size:.75rem; font-weight:700; letter-spacing:.02em;
  padding:5px 14px; border-radius:999px; box-shadow:var(--shadow-blue); white-space:nowrap; }
.tier h3{ margin:0; font-size:1.12rem; letter-spacing:-.015em; font-weight:700; }
.tier-who{ margin:6px 0 0; color:var(--muted); font-size:.9rem; line-height:1.5; min-height:3em; }
.tier-price{ margin:10px 0 0; height:100px; padding-top:27px; display:flex; align-items:baseline; gap:9px; }
.tier-price .n{ font-weight:750; font-size:2.9rem; letter-spacing:-.035em; color:var(--ink);
  font-variant-numeric:tabular-nums; }
.tier-price .per{ color:var(--muted); font-size:.9rem; font-weight:550; }
.tier-list{ margin:20px 0 26px; padding:18px 0 0; list-style:none; border-top:1px solid var(--border-2);
  display:grid; gap:10px; }
.tier-list li{ display:flex; gap:10px; align-items:flex-start; font-size:.93rem; color:var(--body); }
.tier-list .f-check{ margin-top:2px; width:18px; height:18px; }
.tier .btn{ margin-top:auto; width:100%; }
.price-note{ max-width:none; margin:26px auto 0; text-align:center; color:var(--fog);
  font-size:.80rem; line-height:1.6; text-wrap:pretty; }

/* ---- Updates ------------------------------------------------------------ */
/* ---- UPDATES -------------------------------------------------------------
   Two blocks, the same shape, mirrored: Core with its reasons on the left and
   its price on the right, then Pro the other way round. They are separated by a
   rule and a tagged heading, because the first attempt ran them together and
   nothing said where one ended and the other began. */
.updates{ padding-bottom:clamp(56px,8vw,96px); }

.u-block + .u-block{ margin-top:clamp(48px,6vw,86px); padding-top:clamp(40px,5vw,68px);
  border-top:1px solid var(--border); }
.u-block-tag{ margin:clamp(30px,4vw,46px) 0 clamp(18px,2vw,26px); font-size:.78rem; font-weight:700;
  letter-spacing:.09em; text-transform:uppercase; color:var(--blue-text); }
.u-block + .u-block .u-block-tag{ margin-top:0; }

.updates-grid{ display:grid; grid-template-columns:1.2fr .8fr; gap:clamp(20px,3vw,40px); align-items:start; }
/* Mirrored: the price column leads, so the two blocks are read as a pair rather
   than as one long list. DOM order matches visual order, so keyboard and screen
   reader order do too. */
.u-block-rev .updates-grid{ grid-template-columns:.8fr 1.2fr; }
@media (max-width:860px){
  .updates-grid, .u-block-rev .updates-grid{ grid-template-columns:1fr; }
}

.u-reasons{ display:grid; gap:22px; }
.u-lede{ margin:0; color:var(--body); line-height:1.7; }
.u-row{ display:grid; grid-template-columns:auto 1fr; gap:14px; align-items:start; }
.u-row b{ display:block; margin-bottom:4px; color:var(--ink); font-size:1rem; letter-spacing:-.01em; }
.u-row p{ margin:0; font-size:.92rem; line-height:1.6; color:var(--muted); }
.u-ico{ display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px;
  border-radius:11px; background:var(--blue-soft); color:var(--blue-text); flex:0 0 auto; }
/* fill:none or the line icons render as solid black shapes. Lost when this
   block was rewritten, and it is the first thing the eye catches. */
.u-ico svg{ width:19px; height:19px; fill:none; stroke:currentColor; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round; }

.u-price{ border:1px solid var(--border); border-radius:var(--r-lg); background:var(--surface);
  padding:clamp(22px,2.4vw,30px); box-shadow:var(--shadow-sm); }
.u-flag{ display:inline-block; margin-bottom:12px; padding:4px 12px; border-radius:999px;
  background:var(--gradient); color:#fff; font-size:.74rem; font-weight:650; letter-spacing:.01em; }
.u-price h3{ margin:0; font-size:1.08rem; letter-spacing:-.015em; font-weight:700; }
.u-price .tier-price{ margin-top:14px; }
.u-price .tier-list{ margin-bottom:0; }
.u-small{ margin:18px 0 0; padding-top:16px; border-top:1px solid var(--border-2);
  font-size:.86rem; line-height:1.6; color:var(--muted); }
/* ---- Finale ------------------------------------------------------------- */
/* Glass panel over soft brand glows; the gradient lives on the button only. */
/* ---- Proof shots: real screens, not drawings ---------------------------- */
.shots{ padding-bottom:clamp(56px,8vw,96px); }
@media (max-width:700px){ .shot-quad{ grid-template-columns:1fr; } }

.finale{ padding-bottom:clamp(56px,8vw,96px); position:relative; }
.f-glow{ position:absolute; border-radius:50%; filter:blur(70px); pointer-events:none; }
.f-glow.g1{ width:min(520px,46vw); height:320px; left:8%; top:-4%;
  background:radial-gradient(closest-side, rgba(0,119,156,.35), transparent 70%); }
.f-glow.g2{ width:min(520px,46vw); height:320px; right:8%; bottom:-2%;
  background:radial-gradient(closest-side, rgba(0,119,156,.3), transparent 70%); }
.finale-in{ position:relative; overflow:hidden; border-radius:var(--r-xl);
  background:color-mix(in srgb, var(--surface) 65%, transparent);
  border:1px solid color-mix(in srgb, var(--surface) 92%, transparent); outline:1px solid var(--border-2);
  text-align:center; padding:clamp(48px,7vw,84px) clamp(24px,5vw,60px);
  box-shadow:var(--shadow-md); }
.finale h2{ margin:0 auto; max-width:16ch; font-size:clamp(2rem,1.4rem + 2.8vw,3.2rem);
  line-height:1.05; letter-spacing:-.032em; font-weight:750; text-wrap:balance; }
.finale p{ margin:16px auto 0; max-width:54ch; color:var(--body); font-size:1.05rem; text-wrap:pretty; }
.finale .hero-price{ margin-top:clamp(22px,3vw,30px); }
.finale .btn{ margin-top:26px; }

/* ---- Footer ------------------------------------------------------------- */
footer{ border-top:1px solid var(--border); background:var(--surface); }
.foot-in{ max-width:var(--maxw); margin:0 auto; padding:30px clamp(20px,4vw,40px);
  display:flex; flex-wrap:wrap; align-items:center; gap:14px 28px; }
.foot-in .logo{ font-size:1rem; }
.foot-links{ display:flex; flex-wrap:wrap; gap:4px 20px; margin-left:auto; }
.foot-links a{ color:var(--muted); font-size:.9rem; transition:color .15s ease; }
.foot-links a:hover{ color:var(--ink); }
.foot-note{ flex-basis:100%; color:var(--faint); font-size:.84rem; }
@media (max-width:640px){ .foot-links{ margin-left:0; } }

/* ---- Back to top -------------------------------------------------------- */
.to-top{ position:fixed; right:22px; bottom:22px; z-index:var(--z-top); width:46px; height:46px;
  border-radius:50%; border:1px solid var(--border); background:var(--surface); color:var(--ink);
  font-size:1.1rem; cursor:pointer; box-shadow:var(--shadow-md); opacity:0; visibility:hidden;
  transform:translateY(8px); transition:opacity .25s ease, transform .25s ease, visibility .25s; }
.to-top.show{ opacity:1; visibility:visible; transform:none; }
.to-top:hover{ border-color:color-mix(in srgb, var(--blue) 32%, var(--border)); }

/* ===========================================================================
   THE MIDNIGHT LAYER
   ---------------------------------------------------------------------------
   Everything below overrides the old white-surface treatment. It is appended
   rather than woven in, so the retheme is one block you can read, judge and
   remove in one piece.
   =========================================================================== */

/* ---- Ambient atmosphere: blueprint grid + spotlight halo ------------------
   Two fixed layers behind everything. The grid is what stops a near-black page
   reading as an empty void; the halo is what makes the top of the page feel
   lit rather than merely dark. Both are pointer-transparent and both fade at
   the edges so they never draw a hard line of their own. */
body{
  background:var(--canvas);
  font-family:var(--font);
  font-size:16px;
  line-height:1.5;
  letter-spacing:-.16px;
  color:var(--mist);
}
/* THE BLUEPRINT GRID IS GONE. DESIGN.md calls for one and it is right about
   what it is for - a near-black page with nothing on it reads as a void - but on
   a page this full it just tiles a checkerboard behind real content. Owner:
   "whatever this checkered thing in the background is, that is not supposed to
   be there." The soft dome below does the same job without drawing a pattern. */
body::after{
  content:""; position:fixed; left:0; right:0; top:0; height:60vh;
  z-index:0; pointer-events:none;
  background:radial-gradient(ellipse 90% 100% at 50% -20%,
    rgba(180,180,180,.14) 0%, rgba(0,119,156,.055) 42%, transparent 72%);
}
/* ONLY THINGS THAT ARE IN THE FLOW. This rule exists to lift page content
   above the ambient background layer, and it originally listed .nav and .to-top
   too - which overwrote position:sticky on one and position:fixed on the other,
   so the bar stopped sticking and the back-to-top button fell out of the corner
   into the bottom of the document. Both keep their own positioning and both
   already make their own stacking context. */
main, .foot, footer{ position:relative; z-index:1; }

/* ---- Type ---------------------------------------------------------------
   Display face for headings only, at weight 500. The authority comes from the
   size, not the weight: 600+ on the display face reads as shouting and breaks
   the calm the whole page depends on. */
h1,h2,h3{ font-family:var(--display); font-weight:500; letter-spacing:normal; color:var(--ice); }
h1{ font-size:clamp(44px,6vw,76px); line-height:1.08; }
h2{ font-size:clamp(32px,4vw,44px); line-height:1.16; }
h3{ font-size:20px; line-height:1.2; }
h4{ font-family:var(--font); font-weight:600; color:var(--frost); }
p{ color:var(--mist); }
b,strong{ color:var(--frost); font-weight:600; }
small{ color:var(--fog); }

/* NO GRADIENT ON TYPE. A colour wash poured across a headline is the single
   most recognisable tell of a generated page, and it costs legibility for
   nothing: the eye reads a letterform by its edge, and a gradient softens the
   edge. The headline is a flat fill. Emphasis inside it is carried by a
   DIFFERENT flat colour, which is a real hierarchy rather than a decoration. */
h1, .logo{ color:var(--ice); background:none; }
h1 em{ font-style:normal; color:var(--frost-em); }

:focus-visible{ outline:2px solid var(--frost); outline-offset:3px; border-radius:4px; }

/* ---- Buttons: every one a pill ------------------------------------------
   One radius family for anything you press. The primary is the only chromatic
   thing on the page and it is spent here. */
.btn{
  height:44px; padding:0 22px; border-radius:var(--r-pill);
  font-family:var(--font); font-size:14px; font-weight:500; letter-spacing:0;
}
.btn-primary{
  background:var(--violet); color:var(--violet-ink);
  box-shadow:inset 0 1px 1px rgba(255,255,255,.18), 0 8px 24px rgba(0,119,156,.35);
}
.btn-primary:hover{ background:var(--violet-hi); box-shadow:inset 0 1px 1px rgba(255,255,255,.22), 0 10px 30px rgba(0,119,156,.45); }
.btn-ghost{
  background:var(--frost-wash); color:#fff;
  box-shadow:inset 0 0 0 1px var(--hair);
  border:0;
}
.btn-ghost:hover{ background:rgba(232,232,232,.12); color:#fff; box-shadow:inset 0 0 0 1px var(--hair-strong); }

/* ---- Glass, everywhere a card used to be paper --------------------------
   A single treatment applied by selector rather than by hand on each block, so
   a section added later inherits the look instead of standing out. */
.bcard, .theme-card, .price-card, .feat-card, .proof-card,
.upd-card, .stage-in, .vendor, .fin-card, .cat, .plan, .card{
  background:var(--frost-tint) !important;
  border:0 !important;
  border-radius:var(--r-card) !important;
  box-shadow:var(--shadow-md) !important;
  /* No backdrop blur on a card: nothing moves behind it, so the blur is
     invisible, and it costs the text inside its subpixel rendering. */
}
.bcard:hover, .theme-card:hover, .price-card:hover, .feat-card:hover{
  box-shadow:inset 0 1px 1px rgba(235,235,235,.2),
             inset 0 24px 48px rgba(220,220,220,.06),
             0 24px 40px rgba(0,0,0,.45) !important;
}

/* ---- THE GLASS NAV, which is the one people actually feel ---------------
   Owner asked for it by name. It works here because the page scrolls under a
   translucent bar and the blur keeps the words readable while the colour
   underneath still moves. Without the blur it is just a see-through bar and
   the text fights the page. */
.nav{
  background:transparent !important;
  border-bottom:0 !important;
  box-shadow:inset 0 -1px 0 var(--hair);
}
/* The blur restated for this theme, still on the pseudo-element. See the note
   on .nav::before above: the filter must never land on an ancestor of text. */
.nav::before{
  background:rgba(7,7,7,.55);
  -webkit-backdrop-filter:blur(20px) saturate(140%);
          backdrop-filter:blur(20px) saturate(140%);
}
.nav-in{ max-width:var(--maxw); }
.logo{ font-family:var(--display); font-weight:500; letter-spacing:-.01em; }
.logo-mark{
  background:var(--frost-wash) !important;
  box-shadow:inset 0 0 0 1px var(--hair);
  border-radius:var(--r-pill) !important;
  color:var(--frost) !important;
}
.nav-links a{ color:var(--mist); font-size:14px; }
.nav-links a:hover{ color:var(--frost); }
.theme-btn{
  background:var(--frost-wash) !important; color:var(--frost) !important;
  border:0 !important; border-radius:var(--r-pill) !important;
  box-shadow:inset 0 0 0 1px var(--hair);
}
/* NO BLUR HERE, deliberately. At 92% opacity there is almost nothing showing
   through for a blur to act on, so it was paying the composited-layer cost -
   grayscale text on every link in the menu - for an effect nobody can see. */
.nav-menu{
  background:rgba(7,7,7,.92) !important;
  border:0 !important; box-shadow:inset 0 0 0 1px var(--hair), 0 24px 48px rgba(0,0,0,.6);
}

/* ---- The same glass on the footer --------------------------------------- */
/* The footer is glass in colour only. A backdrop blur here would blur nothing -
   the page ends above it - while softening every word in the footer. */
.foot, footer{
  background:rgba(7,7,7,.55) !important;
  border-top:0 !important;
  box-shadow:inset 0 1px 0 var(--hair);
}

/* ---- Eyebrow labels: the section markers this system opens every block with
   Tracked caps in the mono face, flanked by hairlines that fade out. They are
   what give the page its rhythm; without them the sections run together. */
.sec-head{ text-align:center; }

/* The eyebrow is drawn from data-eyebrow, so a section gets one by adding an
   attribute rather than by adding markup. The flanking lines are the same
   fading hairline used everywhere else, which is what ties the label to the
   rest of the system instead of making it a decoration. */
.sec-head[data-eyebrow]::before{
  content:attr(data-eyebrow);
  display:block; width:fit-content; margin:0 auto 22px;
  font-family:var(--mono); font-size:15px; font-weight:400;
  letter-spacing:.10em; text-transform:uppercase; color:var(--mist);
  padding:0 20px; position:relative;
}
.sec-head[data-eyebrow]::after{
  content:""; display:block; height:0;
}
.sec-head[data-eyebrow]{ position:relative; }
.sec-head[data-eyebrow]::before{
  background-image:
    linear-gradient(90deg, transparent, var(--hair)),
    linear-gradient(90deg, var(--hair), transparent);
  background-size:min(120px, 15vw) 1px, min(120px, 15vw) 1px;
  background-position:left 50%, right 50%;
  background-repeat:no-repeat;
  padding-inline:min(150px, 18vw);
}
.sec-head h2{ margin:0 auto; max-width:18ch; }
.sec-head p{ max-width:640px; margin-inline:auto; color:var(--mist); font-size:16px; }
/* ---- Badges and pills ---------------------------------------------------- */
.hero-badge, .badge, .tag, .pill{
  background:var(--lumen) !important; color:var(--frost) !important;
  border:0 !important; border-radius:var(--r-badge) !important;
  box-shadow:inset 0 0 0 1px var(--hair);
  font-size:12px; font-weight:500;
}
.hero-badge{ border-radius:var(--r-pill) !important; }
.beat{ background:var(--violet) !important; box-shadow:0 0 0 4px rgba(0,119,156,.22); }

/* ---- Inputs -------------------------------------------------------------- */
input, textarea, select{
  background:rgba(210,210,210,.06) !important; color:#fff !important;
  border:0 !important; border-radius:var(--r-input) !important;
  box-shadow:inset 0 0 0 1px var(--hair);
}
input::placeholder, textarea::placeholder{ color:rgba(210,210,210,.6); }
input:focus, textarea:focus, select:focus{ box-shadow:inset 0 0 0 1px var(--hair-strong); outline:none; }

/* ---- Section rhythm: cathedral, not dense SaaS --------------------------- */
/* SECTION RHYTHM. Written once, and for a long time it did nothing: the
   original selector `main > section` scores 0,0,2 and .wrap scores 0,1,0, so
   `.wrap{ margin:0 auto }` beat it on every section that carries the class -
   which is all of them. Sections ran straight into each other and the cause was
   invisible, because the rule was right there in the file. Naming .wrap in the
   selector settles it. */
main > section, main > section.wrap, main > .wrap > section{
  margin-block:clamp(72px,10vw,120px);
}

/* ---- Odds and ends the old light theme owned ---------------------------- */
.vendor{ color:var(--mist) !important; font-size:14px; }
/* THE STATS ROW IS ONE CARD, NOT FOUR. The glass rule above briefly included
   .stat, which made every cell its own plate inside the outer plate and killed
   the divider between them, so the four numbers ran together with no gap at all.
   Owner: "the counters do not work, they are clumped together." One glass
   container, hairline dividers, and the cells stay plain. */
.stats-in{
  background:var(--frost-tint) !important;
  border:0 !important;
  border-radius:var(--r-card) !important;
  box-shadow:var(--shadow-md) !important;
  overflow:hidden;
}
.stat{ padding:clamp(24px,3vw,32px) clamp(20px,2.6vw,30px); background:none; }
.stat + .stat{ border-left:1px solid var(--hair) !important; }
.stat .v{ font-family:var(--display); font-weight:500; color:var(--ice);
  font-size:clamp(2.2rem,3.4vw,2.9rem); letter-spacing:normal; line-height:1.1; }
.stat .v .u{ color:var(--fog); font-weight:400; }
.stat .k{ color:var(--fog); font-size:14px; line-height:1.45; margin-top:8px; }
@media (max-width:820px){
  .stat + .stat{ border-left:0 !important; }
  .stat:nth-child(n+2){ border-top:1px solid var(--hair) !important; }
  .stat:nth-child(2){ border-top:0 !important; }
  .stat:nth-child(even){ border-left:1px solid var(--hair) !important; }
}
hr, .rule, .sep{ border:0; height:1px; background:linear-gradient(90deg,transparent,var(--hair),transparent); }

/* ---- Screenshots: framed, not punched out --------------------------------
   The shop's own screenshots are mostly LIGHT, and a bright rectangle dropped
   straight onto the midnight canvas reads as a hole in the page rather than a
   picture on it. Owner: "your shop looks like on day one - that looks terrible
   in here."

   So each one gets a real frame: a glass plate with an inset hairline, a little
   inner padding so the image never touches the edge, and a slight knock-back
   that lifts on hover. The frame is what makes a light image sit ON the dark
   page instead of fighting it. */
@media (max-width:820px){ .shot-quad{ grid-template-columns:1fr; } }

/* ---- Two faults introduced by this retheme, both fixed here --------------

   1. BLURRY HEADINGS. The old stylesheet asks for weight 750 in places, and
      Space Grotesk ships 400 and 500. Asked for a weight it does not have, the
      browser SYNTHESISES one by smearing the glyphs, which is exactly what the
      owner saw: "the h's just look really blurry." Nothing was out of focus;
      the font was being faked. DESIGN.md forbids 600+ on the display face for
      this reason, so every display heading is pinned to a weight that exists.

   2. THE NAV STOPPED STICKING. Giving .nav position:relative to lift it above
      the ambient background layers overwrote its position:sticky. It needs a
      stacking context AND to stick, and sticky already provides one. */
h1, h2, h3, .logo, .stat .v, .hero-price .hp-num{
  font-family:var(--display);
  font-weight:500 !important;
  font-synthesis-weight:none;
}
.nav{
  position:sticky !important; top:0; z-index:var(--z-nav);
}

/* ===========================================================================
   THE LIGHT ROOM
   ---------------------------------------------------------------------------
   The same design, lit from the front instead of from behind. Owner asked for a
   light theme alongside the dark one, and the honest way to build it is NOT to
   invert the palette: inverting a glass system gives you grey mud, because
   frosted white on black and frosted black on white behave nothing alike.

   So the RULES are kept and the materials are restated:
     - surfaces are still glass, but now a warm white plate over a soft canvas
     - the hairline is still the border language, now a cool grey at low alpha
     - elevation is still inset light + a soft halo, now a shadow that falls
       rather than a glow that rises
     - the violet is still the only chromatic accent, and still only on the
       primary action

   Everything the dark theme sets with a token is re-pointed here, so no rule
   below the token block has to know which room it is in.
   =========================================================================== */
:root[data-theme="light"]{
  color-scheme:light;

  --canvas:#fafafa;
  --ice:#131313;            /* headings: near-black, not pure               */
  --frost:#242424;          /* default foreground                            */
  --mist:#525252;           /* body                                          */
  --fog:#646464;            /* helper                                        */

  --hair:rgba(19,19,19,.10);
  --hair-strong:rgba(19,19,19,.18);
  --frost-wash:rgba(19,19,19,.04);
  --frost-tint:#ffffff;
  --lumen:rgba(19,19,19,.06);

  /* Headline emphasis in a light room runs the other way: the violet, which
     is the only chromatic thing this design owns. */
  --frost-em:#00779C;

  --ink:var(--ice);
  --body:var(--mist);
  --muted:var(--mist);
  --faint:var(--fog);
  --bg:var(--canvas);
  --surface:#ffffff;
  --surface-alt:#f2f2f2;
  --blue-soft:rgba(0,119,156,.10);
  --border:var(--hair);
  --border-2:rgba(19,19,19,.06);
  --blue-text:#00779C;

  --green:#1a9b73; --green-ink:#12775a;
  --green-soft:rgba(26,155,115,.08); --green-line:rgba(26,155,115,.24);

  /* Elevation falls in a light room. Same restraint, opposite direction. */
  /* The 1px ring is INSET, like its two siblings below. It was outset, which
     meant anything carrying both a real border AND --shadow-sm drew two lines
     a pixel apart: the double border around the tables and code blocks on the
     theme pages. An inset ring lands exactly on the border instead of beside
     it, so an element that has a border shows one edge and an element that has
     none still gets its definition. */
  --shadow-sm:0 1px 2px rgba(19,19,19,.06), inset 0 0 0 1px rgba(19,19,19,.05);
  --shadow-md:0 1px 2px rgba(19,19,19,.05),
              0 12px 28px -10px rgba(19,19,19,.14),
              inset 0 0 0 1px rgba(19,19,19,.06);
  --shadow-lg:0 2px 4px rgba(19,19,19,.06),
              0 24px 48px -16px rgba(19,19,19,.20),
              inset 0 0 0 1px rgba(19,19,19,.06);
  --shadow-blue:0 8px 24px rgba(0,119,156,.28);
}

/* The dome warms and weakens: in a light room a glow is a tint, not a light
   source, and the same opacity that reads as atmosphere on black reads as a
   smudge on white. */
:root[data-theme="light"] body::after{
  background:radial-gradient(ellipse 90% 100% at 50% -20%,
    rgba(0,119,156,.07) 0%, rgba(180,180,180,.10) 42%, transparent 74%);
}

/* Glass is a real white plate here, not a tint of the page. */
:root[data-theme="light"] .bcard,
:root[data-theme="light"] .theme-card,
:root[data-theme="light"] .price-card,
:root[data-theme="light"] .feat-card,
:root[data-theme="light"] .stats-in,
:root[data-theme="light"] .shot,
:root[data-theme="light"] .vendor{
  background:#ffffff !important;
  -webkit-backdrop-filter:none; backdrop-filter:none;
}
:root[data-theme="light"] .shot img{ filter:none; }

/* The bar stays glass in both rooms: that is the effect the owner asked for and
   it is the one thing that should not change between them.

   THE TINT GOES ON ::before HERE TOO, and it has to. The bar itself must stay
   transparent so the blurred pseudo-element behind it is what shows - see the
   note on .nav::before. Putting the near-white back on .nav instead left the
   dark tint sitting behind a 72% white and the two mixed to grey, which is
   what the owner saw: *"the colour of the menu in the light theme at the top
   seems to be grey, not white"*. */
:root[data-theme="light"] .nav{
  background:transparent !important;
  box-shadow:inset 0 -1px 0 var(--hair);
}
:root[data-theme="light"] .nav::before{ background:rgba(250,250,250,.72); }
:root[data-theme="light"] .foot, :root[data-theme="light"] footer{
  background:rgba(250,250,250,.72) !important;
  box-shadow:inset 0 1px 0 var(--hair);
}
:root[data-theme="light"] .nav-menu{
  background:rgba(255,255,255,.96) !important;
  box-shadow:inset 0 0 0 1px var(--hair), 0 24px 48px rgba(19,19,19,.18);
}
:root[data-theme="light"] .btn-ghost{
  background:#ffffff; color:var(--ice);
  box-shadow:inset 0 0 0 1px var(--hair-strong), 0 1px 2px rgba(19,19,19,.05);
}
:root[data-theme="light"] .btn-ghost:hover{ background:#fbfbfb; color:var(--ice); }
:root[data-theme="light"] .btn-primary{ color:#fff; }
:root[data-theme="light"] input,
:root[data-theme="light"] textarea,
:root[data-theme="light"] select{
  background:#ffffff !important; color:var(--ice) !important;
  box-shadow:inset 0 0 0 1px var(--hair-strong);
}

/* A sticky bar eats the top of whatever you jump to, so every anchor target
   keeps a landing margin the height of the bar plus a little air. Without this
   every in-page link lands with its own heading half hidden. */
:where(section, header, [id]){ scroll-margin-top:96px; }

/* ---- NO BLOBS ------------------------------------------------------------
   Two blurred coloured circles floating behind the finale, and a third behind
   the old device stage. Owner: "no blobs either. Light blobs in the foot.
   That stuff's AI straight away." He is right, and it is worth being precise
   about why, because a glow is not automatically slop:

   A blurred blob is decoration that carries NO information. It is not lighting
   anything, it does not mark a boundary, it does not follow the content, and it
   would look identical on any page of any product. That is the tell. The dome
   at the top of the page survives because it does a job: it makes the top of a
   near-black page read as lit, and it is anchored to the horizon rather than
   floating in the middle of a section.

   So the blobs go, and the finale earns its separation from the page the same
   way every other block does: a glass plate and a hairline. */
.f-glow, .stage-glow{ display:none !important; }
.finale-in{
  background:var(--frost-tint) !important;
  border:0 !important; outline:0 !important;
  box-shadow:var(--shadow-md) !important;
}
:root[data-theme="light"] .finale-in{ background:#ffffff !important; }

/* The button restated in this theme: glass, pill, and it keeps its fixed corner. */
.to-top{
  position:fixed !important; right:22px; bottom:22px; z-index:var(--z-top);
  background:var(--frost-wash) !important; color:var(--frost) !important;
  border:0 !important; border-radius:var(--r-pill) !important;
  box-shadow:inset 0 0 0 1px var(--hair), 0 8px 24px rgba(0,0,0,.4);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
}
.to-top:hover{ background:rgba(232,232,232,.12) !important; box-shadow:inset 0 0 0 1px var(--hair-strong), 0 10px 28px rgba(0,0,0,.5); }
:root[data-theme="light"] .to-top{
  background:#ffffff !important; color:var(--ice) !important;
  box-shadow:inset 0 0 0 1px var(--hair-strong), 0 8px 24px rgba(19,19,19,.14);
}

/* ---- POSTAGE: the calculation, shown end to end -----------------------------
   Added 2026-09-01, after the shipping rebuild replaced size buckets with real
   measurements.

   WHY IT IS NOT A CARD GRID. The bento above it is nine cards and the ladder
   below it is a numbered sequence. A third grid here would read as more of the
   same and the argument would be skimmed rather than followed. So the
   centrepiece is the calculation itself - order, parcel, price - because the
   claim being made is that the number is WORKED OUT, and the only convincing
   way to say that is to show the working.

   Every figure in it is real: those are Royal Mail's own 2026 prices for that
   parcel at that weight, which is the same reason the ladder quotes real
   minutes. A made-up number here would undo the section it is decorating. */
.postage{ padding-bottom:clamp(56px,8vw,96px); }

/* THE FLOW. Three panes and two connectors on one row; one column with the
   connectors turned a quarter turn once there is no room. The connector is a
   grid item rather than a pseudo-element on the pane so that it can rotate
   without dragging the pane's own transform with it. */
.pflow{
  display:grid; align-items:stretch; gap:clamp(10px,1.4vw,16px);
  grid-template-columns:1fr auto 1fr auto 1fr;
}
.pjoin{ display:grid; place-items:center; color:var(--fog); }
.pjoin svg{ width:20px; height:20px; stroke:currentColor; stroke-width:1.6;
  fill:none; stroke-linecap:round; stroke-linejoin:round; }

.pstep{
  margin:0; padding:20px 20px 18px; border-radius:var(--r-lg);
  background:var(--surface); box-shadow:var(--shadow-sm);
  display:flex; flex-direction:column; gap:14px;
}
.pstep figcaption{
  font-family:var(--mono); font-size:12px; letter-spacing:.10em;
  text-transform:uppercase; color:var(--fog);
}

/* The rows inside a pane. One shape for all three panes: a name on the left, a
   measurement on the right, hairline between. Tabular numerals so the digits
   line up in a column instead of shuffling, which is the difference between a
   price list and a paragraph of numbers. */
.prow{ list-style:none; margin:0; padding:0; display:grid; gap:0; }
.prow li{
  display:grid; grid-template-columns:1fr auto; align-items:baseline;
  gap:6px 14px; padding:9px 0;
}
.prow li + li{ box-shadow:inset 0 1px 0 var(--hair); }
.prow b{ font-weight:600; font-size:.94rem; color:var(--ink); letter-spacing:-.012em; }
.prow .pmeta{
  grid-column:1 / -1; font-family:var(--mono); font-size:12px;
  color:var(--fog); letter-spacing:0; font-variant-numeric:tabular-nums;
}
.prow .pnum{
  font-family:var(--mono); font-size:.86rem; color:var(--mist);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}

/* THE PARCEL. The middle pane is the only one with a drawn object, because it
   is the only one that names a thing rather than a list. It is centred and
   given the room the lists spend on rows. */
.pparcel{ display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; gap:10px; flex:1; padding:6px 0 10px; }
.pparcel svg{ width:44px; height:44px; stroke:var(--mist); stroke-width:1.3;
  fill:none; stroke-linecap:round; stroke-linejoin:round; }
.pparcel b{ font-weight:650; font-size:1.02rem; color:var(--ink); letter-spacing:-.014em; }
.pparcel span{ font-family:var(--mono); font-size:12px; color:var(--fog);
  font-variant-numeric:tabular-nums; line-height:1.7; }

/* THE CHOSEN SERVICE. One row carries the accent and nothing else does: the
   section is about arriving at a number, so the number it arrives at is the
   only thing lit. */
.prow li.pwin b, .prow li.pwin .pnum{ color:var(--frost-em); }
.prow li.pwin .pnum{ font-weight:600; }
.ptick{ display:inline-block; margin-left:7px; font-family:var(--mono);
  font-size:10px; letter-spacing:.08em; text-transform:uppercase;
  color:var(--fog); }

/* COVERAGE. Columns divided by the same hairline, not boxes - five carriers
   sitting in five cards would be the card grid this section exists to avoid. */
.pmap{
  margin-top:clamp(30px,4vw,44px);
  display:grid; grid-template-columns:repeat(5,1fr);
}
.pmap div{ padding:4px 18px; }
.pmap div + div{ box-shadow:inset 1px 0 0 var(--hair); }
.pmap span{ display:block; font-family:var(--mono); font-size:11.5px;
  letter-spacing:.08em; text-transform:uppercase; color:var(--fog); }
.pmap b{ display:block; margin-top:5px; font-weight:600; font-size:1rem;
  color:var(--ink); letter-spacing:-.014em; }

/* THE METHODS. A single mono line, separated by hairlines: it is a list of
   names and nothing about it needs a container. */
/* A clear step down from the carrier row above. They are two different kinds
   of list - who carries it, then how it is charged - and at the old spacing
   they read as one block. Owner asked for the gap. */
.pkinds{
  margin:clamp(40px,4.6vw,54px) auto 0; padding:0; list-style:none;
  display:flex; flex-wrap:wrap; justify-content:center;
  gap:0 clamp(14px,2vw,22px); max-width:900px;
}
.pkinds li{ font-family:var(--mono); font-size:12.5px; letter-spacing:.05em;
  text-transform:uppercase; color:var(--mist); padding:5px 0; }
.pkinds li + li{ padding-left:clamp(14px,2vw,22px);
  box-shadow:inset 1px 0 0 var(--hair); }

.pnote{
  margin:clamp(22px,3vw,30px) auto 0; max-width:64ch; text-align:center;
  color:var(--muted); font-size:clamp(1rem,1.2vw,1.08rem); text-wrap:pretty;
}
.pnote strong{ color:var(--ink); font-weight:650; }

/* ---- Postage, narrow ------------------------------------------------------
   Two moves, in this order. First the coverage columns fold, because five
   carrier names are the first thing to run out of width. Then the flow itself
   turns vertical and the connectors turn with it, which is the point at which
   the arrows would otherwise be pointing across a gap that no longer exists. */
@media (max-width:980px){
  .pmap{ grid-template-columns:repeat(2,1fr); gap:2px 0; }
  .pmap div{ padding:12px 16px; }
  .pmap div + div{ box-shadow:inset 1px 0 0 var(--hair), inset 0 1px 0 var(--hair); }
  .pmap div:nth-child(odd){ box-shadow:inset 0 1px 0 var(--hair); }
  .pmap div:first-child{ box-shadow:none; }
  .pmap div:nth-child(2){ box-shadow:inset 1px 0 0 var(--hair); }
}
@media (max-width:860px){
  .pflow{ grid-template-columns:1fr; }
  .pjoin{ padding:2px 0; }
  .pjoin svg{ transform:rotate(90deg); }
  .pstep{ padding:18px 18px 16px; }
  .pparcel{ padding:2px 0 6px; }
}
@media (max-width:520px){
  .pmap{ grid-template-columns:1fr; }
  .pmap div, .pmap div + div, .pmap div:nth-child(odd), .pmap div:nth-child(2){
    padding:11px 0; box-shadow:inset 0 1px 0 var(--hair); }
  .pmap div:first-child{ box-shadow:none; padding-top:0; }
  .pkinds{ gap:0; }
  .pkinds li{ width:100%; text-align:center; padding:8px 0; }
  .pkinds li + li{ padding-left:0; box-shadow:inset 0 1px 0 var(--hair); }
}

/* ---- DAY ONE: the ladder ---------------------------------------------------
   Replaces the screenshot gallery. Five rungs, each a step, read top to bottom.

   Why this shape and not cards: a sequence has an ORDER, and a grid of cards
   destroys order - the eye picks a card at random and the argument collapses.
   A single column with a numbered gutter can only be read one way, which is the
   whole point of the section.

   The one line running down the numbers is the only piece of decoration, and it
   is doing a job: it is what makes five separate blocks read as one continuous
   process rather than five unrelated claims. It stops at the last number, so
   the ladder ends rather than trailing off. */
.ladder{
  list-style:none; margin:0 auto; padding:0;
  max-width:840px;
  position:relative;
}
.rung{
  position:relative;
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:baseline;
  gap:0 clamp(20px,3vw,34px);
  padding:clamp(26px,3.4vw,34px) 0;
}
/* The hairline between steps, not around them. A box around each step would be
   five borders doing what four hairlines do better. */
.rung + .rung{ box-shadow:inset 0 1px 0 var(--hair); }

/* The connecting rule. Drawn from the number's own column so it stays aligned
   at every width, and skipped on the last rung so the line terminates. */
.rung::before{
  content:""; position:absolute; top:0; bottom:0; left:calc(1em + 2px);
  width:1px; background:var(--hair);
}
.rung:first-child::before{ top:50%; }
.rung:last-child::before{ bottom:50%; }

.rung-n{
  position:relative; z-index:1;
  font-family:var(--mono); font-size:13px; font-weight:400;
  letter-spacing:.04em; color:var(--fog);
  background:var(--canvas);
  padding:6px 0; min-width:2.2em;
}
.rung-b h3{ margin:0 0 8px; }
.rung-b p{ margin:0; max-width:56ch; font-size:16px; line-height:1.6; }

/* The time column. Right-aligned and quiet: it is reassurance, not a headline,
   and the moment it competes with the step title the ladder reads as a table. */
.rung-t{
  font-family:var(--mono); font-size:12px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--fog); white-space:nowrap;
  text-align:right;
}
/* The last rung is the payoff, so its time cell is the one that carries colour.
   One accent, spent at the end, on the only line that says you are trading. */
.rung:last-child .rung-t{ color:var(--frost-em); }

.ladder-foot{
  max-width:840px; margin:28px auto 0;
  color:var(--fog); font-size:15px; line-height:1.6;
}

@media (max-width:720px){
  /* The time column drops under the step rather than squeezing the text. */
  .rung{ grid-template-columns:auto 1fr; gap:0 18px; }
  .rung-t{ grid-column:2; text-align:left; margin-top:10px; }
  .rung-b p{ font-size:15px; }
}

/* ===========================================================================
   AUDIT FIXES, 2026-08-31
   Every rule below answers a measured defect from the design and technical
   review, not a matter of taste. Each is annotated with what was measured.
   =========================================================================== */

/* ---- 1. Contrast: the helper colour in the light theme --------------------
   Measured 4.14-4.33:1 against the light canvas on .rung-n, .rung-t,
   .ladder-foot, .stat .k and the drag handles - all below the 4.5 floor, and
   .stat .k scraped through at 4.59 with no headroom. One token was carrying all
   of them, so one token fixes all of them. #5b6474 measures 5.9:1 on #f7f8fb
   and still reads as clearly secondary next to --mist. */
:root[data-theme="light"]{ --fog:#646464; }

/* ---- 2. White text on a gradient -----------------------------------------
   --gradient runs violet -> pale blue. White holds at the violet end (6.06) and
   collapses at the pale end (1.89), so "Most popular", "Highly recommended" and
   "Checkout securely" are unreadable across their right-hand third. A badge is
   two words on a chip: there is nothing for a gradient to do there except break
   it. Flat accent, which passes everywhere on the chip. */
.tier-flag, .u-flag, .viz-pay{
  background:var(--violet) !important;
  color:var(--violet-ink) !important;
}

/* ---- 3. Tap targets ------------------------------------------------------
   Measured: footer links 21.6px tall, nav links 39px, theme toggle 42px. The
   floor is 44px and it is not a stylistic number - it is roughly the pad of an
   adult thumb. Padding, not height, so the text stays where it sits. */
.foot-links{ gap:0 12px; }
.foot-links a{
  display:inline-flex; align-items:center; min-height:44px; padding:0 8px;
  font-size:.92rem;
}
.nav-links a{ min-height:44px; display:inline-flex; align-items:center; }
.theme-btn{ min-height:44px; }

/* ---- 4. Space Grotesk 600 silently renders at 500 -------------------------
   The face ships 400 and 500 only and loads as static instances, so a declared
   600 snaps DOWN to 500: ".hp-per" was authored bolder than everything around
   it and rendered lighter. Declaring the weight that exists makes the file say
   what the screen does. */
.hp-per{ font-weight:500; }

/* ---- 5. The second price is not a second headline ------------------------
   "From £199" was set at clamp(2.8rem..4rem), which lands within a few pixels
   of the H1 directly above it. Two objects at headline scale in one viewport
   read as two headlines and the eye cannot tell which one it is meant to start
   at. Brought down a step: still the biggest thing in its own block, no longer
   competing with the sentence that has to land first. */
.hp-num{ font-size:clamp(2rem, 1.5rem + 2.2vw, 2.9rem); }

/* ---- 6. The light page showing through the dark one ----------------------
   These rules were written for white paper and the retheme never reached them,
   so the three little product cards in the first bento tile were WHITE PLATES
   holding WHITE line-art on a near-black page: the brightest objects on the
   whole page, and the exact "bright rectangle punched into the page" fault the
   screenshots were rejected for.

   The artwork now takes its colours from variables rather than from hard-coded
   hexes, so it belongs to whichever room it is in instead of only ever
   belonging to the light one. */
:root{
  --art-fill:rgba(232,232,232,.07);
  --art-fill-2:rgba(232,232,232,.11);
  --art-line:rgba(210,210,210,.5);
  --art-line-2:rgba(210,210,210,.34);
}
:root[data-theme="light"]{
  --art-fill:#ffffff;
  --art-fill-2:#f5f5f5;
  --art-line:#c6c6c6;
  --art-line-2:#a8a8a8;
}
.s-card{
  background:var(--frost-tint); border:0;
  box-shadow:inset 0 0 0 1px var(--hair);
}
.s-thumb{ background:var(--frost-wash); }
.s-card b{ color:var(--frost); }
.s-card span{ color:var(--ice); font-weight:600; }
:root[data-theme="light"] .s-card{ background:#fff; }

/* ---- 7. One accent, and it is not four ----------------------------------
   The bar chart shipped a saturated #2563eb and a second purple #7c3aed, and
   the payment bar a three-stop gradient. That is four chromatic colours on a
   page whose entire design rests on having ONE. The bars now climb from the
   frost through to the accent, so height and colour say the same thing instead
   of two different things. */
.viz-chart i{ background:linear-gradient(180deg, rgba(210,210,210,.34), rgba(210,210,210,.6)) !important; }
.viz-chart i:nth-child(4){ background:linear-gradient(180deg, var(--violet-hi), var(--violet)) !important; }

/* ---- 8. The rounded icon tile above the heading --------------------------
   Six cards, each opening with a 40x40 rounded square holding a line icon, with
   the heading underneath. It is the most-generated component on the web and it
   costs a whole line of vertical space to say nothing the heading does not
   already say.

   The icon is not deleted - it is demoted to a mark beside the heading, where it
   works as a bullet rather than as a badge. No tile, no fill, no border: the
   heading gets its own line back and the card starts with a sentence. */
.bico{
  width:auto; height:auto; margin:0 10px 0 0; border:0; background:none;
  border-radius:0; color:var(--fog);
  display:inline-grid; place-items:center; vertical-align:-4px;
}
.bico .icon{ width:19px; height:19px; }
.bcard h3{
  display:flex; align-items:center; gap:0;
  font-family:var(--display); font-weight:500; font-size:1.2rem;
}
/* The mark and the heading are one line now, so the tile's old bottom margin
   would leave a gap where nothing sits. */
.bcard > .bico + h3{ margin-top:0; }

/* ---- 9. Cramped padding in the stats band -------------------------------
   Flagged on .stats-in and every .stat: children sitting flush against the
   container edge and against the dividing rules. The band is the one place on
   the page where four things share a single plate, so the gap between a number
   and the rule beside it is the only thing separating one fact from the next.
   Symmetrical breathing room, and more of it between columns than within one. */
.stats-in{ padding:6px; }
.stat{ padding:clamp(26px,3vw,34px) clamp(24px,2.8vw,34px) !important; }

/* ---- 10. The vendor pills -----------------------------------------------
   Text flush against the top and bottom of its own chip. A fixed 44px height
   with centred content is not the same as padding: the moment the label wraps
   or the font falls back, the text touches the edge. */
.vendor{ height:auto !important; min-height:44px; padding:10px 18px !important; }

/* ---- 11. No coloured glow under the primary button ----------------------
   A violet drop-shadow under a violet button is the single most recognisable
   detail of a generated page, and it is doing no work: the button is already
   the only saturated object on the screen. Elevation stays, colour comes out of
   it, and the shadow goes back to being a shadow. */
.btn-primary{ box-shadow:inset 0 1px 1px rgba(255,255,255,.16), 0 6px 18px rgba(0,0,0,.45) !important; }
.btn-primary:hover{ box-shadow:inset 0 1px 1px rgba(255,255,255,.20), 0 10px 26px rgba(0,0,0,.55) !important; }

/* ---- 12. The buy buttons -------------------------------------------------
   Pushed to the bottom of the card so all four line up whatever length the
   feature list runs to. Full width, because at the moment of deciding, the
   action should be the widest thing in the column. */
/* The gap above the button is the pause between reading and deciding, so it
   has to be bigger than the gap between two list items or the button reads as
   the last bullet. margin-top alone was not enough on the shortest card, where
   the flex `auto` on the list leaves no slack to push against. */
/* The gap above the buy button lives on the LIST as padding, not on the
   button as margin, for a measured reason: .tier .btn{ margin-top:auto }
   outranks any single-class rule and resolves to ZERO on the tallest card, so
   a margin here quietly vanished on exactly the cards that needed it. Padding
   cannot be beaten by specificity and cannot resolve to zero. The auto margin
   stays, because it is also what pins every button to the card's bottom edge
   when the lists are different lengths. */
.tier-buy{ width:100%; justify-content:center; }
.tier .tier-list{ margin-bottom:auto; padding-bottom:36px; }
.tier{ display:flex; flex-direction:column; }
.tier .tier-list{ margin-bottom:auto; }


/* ---- 13. The theme previews: show the theme, not a fake screenshot -------
   Three attempts went into drawing a little shop window here, and the light one
   was a white rectangle every time. It kept looking wrong because it WAS wrong:
   a screenshot at 90px tall shows nothing legible, and rendering the light theme
   as a white slab on a near-black page makes the quieter of the two products
   shout the loudest.

   A theme in this shop is a palette, a typeface and a corner radius - that is
   literally what the 43 variables set. So show those. The letters are set in
   the theme's own face at the theme's own weight, the chips are its actual
   colours in order from ground to ink, and the card corner is its radius. It is
   more informative than the wireframe was, it is honest, and neither card can
   become a white blob because no swatch is bigger than 22px. */
.t-preview{
  display:flex; align-items:center; gap:16px;
  padding:22px 20px;
  background:var(--frost-wash);
  box-shadow:inset 0 0 0 1px var(--hair);
}
.t-aa{
  font-size:2rem; line-height:1; letter-spacing:-.02em;
  color:var(--ice);
}
.t-swatches{ display:flex; gap:8px; margin-left:auto; }
.t-swatches i{
  width:22px; height:22px; border-radius:var(--r-pill);
  background:var(--c);
  box-shadow:inset 0 0 0 1px var(--hair-strong);
}

/* Each theme's letters are set in its own face, which is the one thing a
   swatch row cannot tell you. */
.t-nova-p .t-aa{ font-family:var(--display); font-weight:500; }
.t-white-p .t-aa{ font-family:var(--font); font-weight:600; }

/* ---- 14. The two nav pieces that had no styles at all --------------------
   .nav-div and .is-here were put into the markup and never given rules, so on
   the theme pages the current page's own label rendered as bare text: wrong
   weight, no padding, sitting off the line the other links share. A missing
   rule looks exactly like a broken layout, which is why it read as "everything
   all over the place".

   .is-here takes the SAME metrics as a link so the row stays level, and differs
   only in being quieter and unclickable - you are already here, so it is a
   label, not a control. */
.nav-links .is-here{
  display:inline-flex; align-items:center; min-height:44px;
  padding:9px 14px; border-radius:9px;
  color:var(--ink); font-size:.95rem; font-weight:550;
  background:var(--surface-alt);
  cursor:default;
}
/* The hairline that separates the in-page anchors from the two theme pages.
   Short, centred on the row, and it fades at both ends so it reads as a pause
   rather than as a rule drawn through the nav. */
.nav-div{
  width:1px; height:20px; margin:0 8px; align-self:center; flex:0 0 auto;
  background:linear-gradient(180deg,transparent,var(--hair-strong),transparent);
}
@media (max-width:1080px){
  /* Below this the nav collapses to the hamburger anyway, and a divider inside a
     row that is about to be hidden is just one more thing to reflow. */
  .nav-div{ display:none; }
}

/* ---- CART SPLIT: one order, sorted into its parcels ----------------------
   Redone 2026-08-31. Round one drew three separate floating cards and the
   owner was right that it did not look good: three near-identical plates read
   as a repeated component, not as a cart. One order is ONE object, so the redo
   draws one cart plate - bar at the top, the parcels as grouped rows inside,
   a real total at the bottom - the same shape as the checkout card in the
   bento, which is the page's strongest visual.

   Graphic LEFT, copy right: the themes section directly below runs copy left,
   graphic right, so the two alternate down the page. */
.split-in{
  display:grid; grid-template-columns:1.1fr 1fr;
  gap:clamp(28px,4.5vw,60px); align-items:center;
}
.split-points{ list-style:none; margin:0; padding:0; display:grid; gap:18px; }
.split-points li{ display:flex; gap:11px; align-items:flex-start; color:var(--body); }
.split-points b{ color:var(--ink); }
.split-note{ margin:26px 0 0; color:var(--fog); font-size:.95rem; line-height:1.6; }

.sv-cart{
  background:var(--frost-tint); border-radius:var(--r-card);
  box-shadow:var(--shadow-md);
  padding:6px 20px 0;
  max-width:480px;
}
.sv-bar{
  display:flex; align-items:center; gap:9px; padding:14px 0;
  box-shadow:inset 0 -1px 0 var(--hair);
}
.sv-bar svg{ width:17px; height:17px; stroke:var(--frost); stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; }
.sv-bar b{ color:var(--ice); font-size:.95rem; font-weight:600; }
.sv-bar span{ margin-left:auto; color:var(--fog); font-size:.8rem; }

/* Groups separate by SPACE and a quiet header, not by boxes: the plate is the
   box, and boxes inside boxes is how round one went wrong. */
.sv-group{ padding:14px 0 12px; }
.sv-group + .sv-group{ box-shadow:inset 0 1px 0 var(--hair); }
.sv-head{ display:flex; align-items:baseline; gap:8px; margin-bottom:2px; }
.sv-head b{
  font-family:var(--mono); font-size:.72rem; font-weight:400;
  letter-spacing:.08em; text-transform:uppercase; color:var(--fog);
}
.sv-head span{ margin-left:auto; color:var(--fog); font-size:.78rem; }

.sv-row{
  display:flex; align-items:center; gap:11px; padding:8px 0;
  color:var(--mist); font-size:.9rem;
}
.sv-row i{ width:30px; height:30px; border-radius:6px; background:var(--frost-wash);
  box-shadow:inset 0 0 0 1px var(--hair); flex:0 0 auto; }
.sv-row em{ font-style:normal; }
.sv-row span{ margin-left:auto; color:var(--frost); font-variant-numeric:tabular-nums; }

.sv-post{
  display:flex; align-items:center; gap:8px; padding:6px 0 2px;
  color:var(--fog); font-size:.82rem;
}
.sv-post svg{ width:14px; height:14px; stroke:currentColor; stroke-width:1.8; fill:none;
  stroke-linecap:round; stroke-linejoin:round; flex:0 0 auto; }
.sv-post span{ margin-left:auto; color:var(--frost); font-variant-numeric:tabular-nums; }
.sv-free{ color:var(--green-ink); }

/* The total: the one heavy line, closing the plate the way the checkout card
   closes with its button. Negative margins let its rule run edge to edge. */
.sv-total{
  display:flex; align-items:baseline; margin:0 -20px; padding:14px 20px 16px;
  box-shadow:inset 0 1px 0 var(--hair-strong);
}
.sv-total b{ color:var(--ice); font-size:.95rem; font-weight:600; }
.sv-total span{ margin-left:auto; color:var(--ice); font-weight:600; font-size:1.05rem;
  font-variant-numeric:tabular-nums; }

@media (max-width:860px){
  .split-in{ grid-template-columns:1fr; }
  /* copy first on a phone: the claim, then the evidence */
  .split-viz{ order:2; }
  .sv-cart{ max-width:none; }
}
