
:root{
  /* Blue anchors the brand; red and yellow are accents, not co-leads. */
  --blue:#1B4FD8;
  --blue-deep:#123AA8;
  --red:#D6402F;
  --yellow:#E8AE1A;
  --ink:#12141B;
  --paper:#FFFFFF;
  --shell:#F7F8FA;
  /* band colour: a light neutral grey, set deep enough to read as a distinct
     surface against paper rather than a barely-there tint */
  --sand:#F1F2F5;
  --sky:#EEF3FF;
  --wash:#F4F7FE;
  --yellow-lt:#FDF3D8;
  --blue-lt:#7BA4FF;
  --copper:#C86A32;
  /* hairlines and soft elevation replace the inked-outline system */
  --line:#E3E6EC;
  --line-2:#D3D8E2;
  --mute:#5B6270;
  --sh-1:0 1px 2px rgba(18,20,27,.05), 0 1px 3px rgba(18,20,27,.04);
  --sh-2:0 2px 4px rgba(18,20,27,.05), 0 8px 20px rgba(18,20,27,.06);
  --sh-3:0 4px 10px rgba(18,20,27,.07), 0 18px 38px rgba(18,20,27,.08);

  --display:'Bricolage Grotesque',system-ui,sans-serif;
  --body:'DM Sans',system-ui,sans-serif;
  --mono:'Space Mono',ui-monospace,monospace;

  --edge:1px;
  --s1:8px; --s2:14px; --s3:22px; --s4:30px; --s5:44px; --s6:64px;
  /* no overshoot — the bounce was most of the toy feel */
  --pop:cubic-bezier(.22,.61,.36,1);
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
[id]{scroll-margin-top:96px}
/* overflow-x:hidden on html OR body turns that element into a scroll container,
   which breaks position:sticky in every descendant. overflow-x:clip crops the
   same way without creating one, so the sticky nav keeps working. */
body{overflow-x:clip}
body{
  background:var(--paper);
  color:var(--ink);
  font-family:var(--body);
  font-size:17px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

/* full-bleed tonal bands: each one steps the page a shade to give it depth */
.tint{position:relative}
.tint::before{
  content:'';position:absolute;top:0;bottom:0;left:50%;transform:translateX(-50%);
  width:100vw;z-index:-1;background-color:var(--paper);
}
.tint-shell::before{background-color:var(--shell)}
.tint-sky::before{background-color:var(--wash)}
.tint-ink::before{background-color:var(--shell)}
/* a step below --ink so the footer reads as the page's floor rather than
   another dark panel */
.tint-ink-solid::before{background-color:#0B0D12}
.tint-shell-band::before{background-color:var(--shell)}
.tint-sand-band::before{background-color:var(--sand)}
/* halftone stipple, the comic print texture */
/* the dot field is masked so it's densest behind the product and dissolves
   toward the edges — the dots fade, not the background behind them */
/* an explicitly sized ellipse, not a circle: a circle sized to the farthest
   corner runs past the top and bottom of a tall hero, so the field gets cut
   at the section edge instead of fading out */
@media(max-width:900px){
}
.tint-edge::after{
  content:'';position:absolute;left:50%;transform:translateX(-50%);bottom:0;
  width:100vw;border-bottom:var(--edge) solid var(--line);
}
.wrap{max-width:1180px;margin:0 auto;padding:0 20px;position:relative}

h1,h2,h3{font-family:var(--display);font-weight:800;line-height:.94;letter-spacing:-.02em}
h1{font-size:clamp(2.5rem,6.4vw,4.7rem)}
.hero h1{font-size:clamp(2.7rem,5.4vw,5.1rem);letter-spacing:-.035em;line-height:.94}
h2{font-size:clamp(2rem,5vw,3.4rem)}
h3{font-size:1.22rem;line-height:1.15}
a{color:inherit}

.mono{font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase}

/* ─── panels: everything sits in an inked comic frame ─── */
.panel{
  border:var(--edge) solid var(--line);
  border-radius:16px;
  box-shadow:var(--sh-2);
  background:var(--paper);
}

/* ─── announcement banner ─── */
/* flat brand blue */
.banner{
  position:relative;z-index:5;padding:11px 20px;
  background:var(--blue);color:#FFFFFF;
}
.banner-in{
  display:flex;align-items:center;justify-content:center;gap:6px;flex-wrap:wrap;
}
.banner-truck{width:42px;height:20px;flex:none;color:#FFFFFF;opacity:.92;margin-right:-4px}
@media(max-width:640px){
  .banner-in{gap:4px}
  .banner-truck{width:35px;height:17px;margin-right:-3px}
}
.banner p{
  font-family:var(--display);font-weight:800;font-size:.82rem;
  letter-spacing:.02em;text-transform:uppercase;
}
.banner b{font-weight:800}

/* ─── nav ─── */
/* follows the page down at every width; translucent so content reads through
   it, with a shadow that only appears once it has left the top */
nav{position:sticky;top:0;z-index:40;
  background:rgba(255,255,255,.88);
  backdrop-filter:saturate(180%) blur(12px);
  -webkit-backdrop-filter:saturate(180%) blur(12px);
  border-bottom:var(--edge) solid var(--line);transition:box-shadow .2s ease}
nav.stuck{box-shadow:0 1px 3px rgba(18,20,27,.06),0 8px 24px rgba(18,20,27,.06)}
.nav-in{display:flex;align-items:center;gap:1.6rem;padding:14px 20px;max-width:1180px;margin:0 auto}
.brand{font-family:var(--display);font-weight:800;font-size:1.4rem;letter-spacing:-.035em;display:flex;align-items:center;gap:.5rem;text-decoration:none;white-space:nowrap}
/* three bars flush against each other, forming one solid square —
   no outlines, so the colour boundaries do the dividing */
.brand-mark{
  display:flex;width:26px;height:26px;flex:none;
  border-radius:7px;overflow:hidden;
}
.brand-mark i{flex:1;transition:flex-grow .22s var(--pop)}
.brand-mark i:nth-child(1){background:var(--red)}
.brand-mark i:nth-child(2){background:var(--yellow)}
.brand-mark i:nth-child(3){background:var(--blue)}
/* the mark stays perfectly still on hover — no reweighting, no shift */
.brand-mark i{transition:none}
.nav-links{display:flex;gap:1.3rem;margin-left:auto;list-style:none;white-space:nowrap}
.nav-links a{font-size:.9rem;font-weight:500;text-decoration:none;padding:3px 0;border-bottom:2px solid transparent}
.nav-links a:hover,.nav-links a:focus-visible{border-bottom-color:var(--blue)}

/* inked frame with a hard offset shadow: the button presses into it on click */
.btn{
  display:inline-block;font-family:var(--display);font-weight:700;font-size:.96rem;
  padding:13px 24px;border:2px solid var(--ink);border-radius:12px;
  background:var(--blue);color:var(--paper);box-shadow:4px 4px 0 var(--ink);
  text-decoration:none;cursor:pointer;
  transition:transform .12s var(--pop),box-shadow .12s var(--pop);
}
.btn:hover,.btn:focus-visible{transform:translate(-2px,-2px);box-shadow:6px 6px 0 var(--ink)}
.btn:active{transform:translate(4px,4px);box-shadow:0 0 0 var(--ink)}
.btn-alt{background:var(--paper);color:var(--ink)}
.btn-yellow{background:var(--yellow);color:var(--ink);border-color:var(--ink)}
.btn-sm{font-size:.85rem;padding:9px 16px;box-shadow:3px 3px 0 var(--ink)}

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

/* ─── hero ─── */
/* two columns on desktop: copy left, product right. Below 900 it stacks and
   re-centres, which is also where the brick field switches to the burst. */
.hero{
  padding:88px 0 var(--s6);
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
  gap:var(--s5);align-items:center;text-align:left;
}
.hero-copy{min-width:0;position:relative;z-index:2}
.hero-product{min-width:0;display:grid;place-items:center;position:relative;z-index:1}
.hero .hero-cta{justify-content:flex-start}
/* each sentence starts its own line on desktop, so 'We' and 'Fast' never
   trail at the end of a line. Off on narrow, where the column is too
   short for forced breaks to help. */
.brk{display:none}
@media(min-width:901px){
  .brk{display:inline}
  .hero .lede{max-width:67ch}   /* wide enough that only the breaks wrap it */
}
.hero .lede{margin-left:0;margin-right:0;font-size:1.06rem;max-width:46ch}
/* the eyebrow gets a live indicator: small, but it says the verification is
   ongoing rather than a one-off claim */
.hero-eyebrow{display:inline-flex;align-items:center;gap:7px;margin-bottom:14px;line-height:1}
/* uppercase text sits slightly above the middle of its line box, because the
   box reserves room for descenders that capitals never use. Centring the icon
   on the box leaves it looking low, so it lifts a fraction to sit level with
   the cap height instead. */
.eb-shield{width:14px;height:14px;flex:none;color:var(--blue);
  transform:translateY(-1px)}
.hero h1{margin-inline:0}
@media(max-width:900px){
  /* the desktop curve is driven by 5.4vw, which collapses to its minimum on a
     phone — the stacked layout has the full width, so it can run much larger */
  .hero h1{font-size:clamp(2.9rem,12.5vw,4.2rem);line-height:.92}
  .hero{grid-template-columns:1fr;gap:var(--s4);text-align:center;padding-top:64px}
  .hero-product{order:2}
  .hero .hero-cta{justify-content:center}
  .hero .lede{margin-inline:auto}
  .hero h1{margin-inline:auto}
}
.hero .lede{margin:var(--s3) auto var(--s4);max-width:min(52ch,var(--hero-w))}
.hero h1{max-width:var(--hero-w);margin-inline:auto}
.hero-cta{justify-content:center}
.hero-stats{
  display:flex;flex-wrap:wrap;max-width:900px;margin:0 auto;text-align:center;
  border:var(--edge) solid var(--line);border-radius:16px;
  box-shadow:var(--sh-2);background:var(--paper);overflow:hidden;
}
.hs{flex:1 1 150px;padding:18px 12px;border-right:1px solid var(--line)}
.hs:last-child{border-right:0}
.hs b{display:block;font-family:var(--display);font-weight:800;font-size:1.75rem;line-height:1;color:var(--blue)}
.hs span{font-family:var(--mono);font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;opacity:.7}
/* quiet compliance line closing out the hero */
/* the accent word is a colour change, never an italic */
h1 em,h2 em{font-style:normal;color:var(--blue)}
.lede{font-size:1.06rem}
.hero-cta{display:flex;gap:14px;flex-wrap:wrap}

/* ─── hero brick field ─── */
/* the copy column narrows with the viewport so the bricks can move inward
   instead of being pushed flat against the edges */
.hero{position:relative;--hero-w:clamp(280px,46vw + 120px,720px)}
.hero>*{position:relative;z-index:1}
.hero>.hero-copy{z-index:2}
.hero>.hero-product{z-index:1}
.hero>.bricks{
  position:absolute;z-index:0;top:0;left:50%;transform:translateX(-50%);
  width:100vw;height:100%;pointer-events:none;
}
.bricks canvas{position:absolute;left:0;top:0;width:100%;height:100%;display:block}
#brickFar{filter:blur(2.5px)}
#brickNear{filter:none}   /* near plane stays sharp */
/* the headline sits on a paper cushion so type never fights the render */
/* pieces now sit at the margins, so the type only needs a light cushion */
.hero h1,.hero .lede{
  text-shadow:0 0 20px var(--paper),0 0 9px var(--paper);
}
/* let the field bleed past the hero edges so it reads as a space, not a panel */

/* ─── mobile burst ─── */
.burst-stage{
  position:relative;width:100%;aspect-ratio:1/1;max-width:560px;margin:0 auto;
  display:grid;place-items:center;
}
@media(max-width:900px){.burst-stage{max-width:420px}}
/* full-bleed so the only thing that can clip a brick is the screen edge,
   not the 440px stage the vial is centred in */
/* the canvas runs well past the stage on all four sides: a brick that leaves
   the stage should carry on into the hero above and the stats below, cropped
   only by the screen edge */
/* Desktop: bounded, because the stage sits in the right column and a
   viewport-wide canvas would run across the copy.
   Narrow: full-bleed exactly as before, so pieces still reach the screen. */
.burst-bricks{
  position:absolute;top:-170px;left:50%;transform:translateX(-50%);
  width:calc(100% + 340px);height:calc(100% + 340px);
  z-index:1;pointer-events:none;
}
@media(max-width:900px){
  .burst-bricks{top:-190px;width:100vw;height:calc(100% + 380px)}
}
/* the field is sized by a `.hero > .bricks` rule; once it moves in here that
   selector stops matching, so it needs its own dimensions or it collapses to
   zero height and the renderer bails out */
.burst-bricks>.bricks{
  position:absolute;left:0;top:0;transform:none;
  width:100%;height:100%;pointer-events:none;
}
/* a little vertical headroom so the top and bottom pieces aren't trimmed */
.burst-stage{overflow:visible}
.burst-bricks canvas{position:absolute;left:0;top:0;width:100%;height:100%;display:block}
/* tilted and drifting like the bricks around it, so the vial reads as
   floating in the same weightless space rather than standing on a shelf */
.burst-vial{
  position:relative;z-index:2;width:44%;display:block;
  transform:rotate(-13deg);
  filter:drop-shadow(-10px 18px 28px rgba(18,20,27,.20));
  animation:vialFloat 15s ease-in-out infinite;
  will-change:transform;
}
.burst-vial svg{width:100%;height:auto;display:block}
/* the hero vial is floating and tilted, so a contact shadow would contradict it */
.burst-vial .vgs{display:none}
@keyframes vialFloat{
  0%   {transform:rotate(-13deg) translate(0,0)}
  50%  {transform:rotate(-9.5deg) translate(4px,-9px)}
  100% {transform:rotate(-13deg) translate(0,0)}
}
@media(prefers-reduced-motion:reduce){
  .burst-vial{animation:none}
}
#creds,#catalog{position:relative;z-index:1}

/* ─── section furniture ─── */
/* One rhythm instead of nine ad-hoc overrides. Banded sections get more
   padding than plain ones, because a tint has visible edges and content
   sitting close to them reads as cramped in a way it doesn't on white. */
section{padding:var(--s6) 0}
section.tint{padding:calc(var(--s6) + 10px) 0}
section#creds{padding:var(--s5) 0 var(--s6)}      /* stats sit up under the hero */
@media(max-width:900px){
  /* A band edge needs more clearance than open white does, and on a phone the
     content is full-bleed to the gutters, so a tight boundary reads as the
     sections colliding. Both sides of the boundary get more room. */
  section{padding:calc(var(--s5) + 10px) 0}
  section.tint{padding:calc(var(--s5) + 24px) 0}
  section#creds{padding:var(--s4) 0 var(--s5)}
}
.sec-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1.5rem;margin-bottom:calc(var(--s3) + 14px);flex-wrap:wrap}
.sec-head-mid{justify-content:center;text-align:center}
.eyebrow{
  font-family:var(--mono);font-size:.7rem;font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;display:inline-block;margin-bottom:14px;color:var(--blue);
}

/* ─── the block set ─── */
/* copy on the left, the twenty tiles on the right; stacks below 900 */
.set{
  color:var(--ink);display:grid;gap:var(--s5);align-items:center;
  grid-template-columns:minmax(0,1fr) minmax(0,.92fr);
}
.set-copy{min-width:0}
.set-blocks{min-width:0}
@media(max-width:900px){
  .set{grid-template-columns:1fr;gap:var(--s4)}
}
.set-copy{min-width:0}
.set-lede{max-width:52ch;margin-top:16px;opacity:.85}
.set h2{color:var(--ink)}

.set 
.aa-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:9px;margin-top:0}
@media(max-width:900px){.aa-grid{margin-top:var(--s3)}}
@media(max-width:520px){.aa-grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}}
.aa{
  aspect-ratio:1;border:var(--edge) solid var(--line);border-radius:11px;
  color:var(--ink);   /* was inheriting paper from .set — unreadable on yellow */
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  font-family:var(--display);font-weight:800;font-size:.9rem;
  box-shadow:var(--sh-1);
  transition:transform .14s var(--pop);
}
.aa:hover{transform:translateY(-3px);box-shadow:var(--sh-2)}
.aa i{font-family:var(--mono);font-style:normal;font-size:.53rem;letter-spacing:.05em;opacity:.72;margin-top:3px}
.aa.np{background:var(--yellow)}
.aa.po{background:var(--blue);color:var(--paper)}
.aa.ch{background:var(--red)}
.legend{display:flex;gap:1.4rem;flex-wrap:wrap;margin-top:24px;font-family:var(--mono);font-size:.68rem;letter-spacing:.08em;text-transform:uppercase}
.legend span{display:flex;align-items:center;gap:.5rem}
.swatch{width:15px;height:15px;border:1px solid var(--line-2);border-radius:4px;flex:none}

/* ─── catalog ─── */
/* six best sellers: fixed 3 across on desktop and 2 across on phones, so it's
   always two full rows rather than whatever auto-fill happens to produce */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3)}
@media(max-width:900px){.cards{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* same dot field as the hero, masked so it's densest behind the vial and
   dissolves before the card edges */
.vialbox{
  position:relative;overflow:hidden;
  margin:-22px -22px 16px;padding:22px 12px 14px;
  /* a studio sweep: bright behind the vial, settling to a grounded grey at the
     base, which is what makes the contact shadow read as a surface */
  background:
    radial-gradient(ellipse 74% 58% at 50% 34%,
      #FFFFFF 0%, rgba(255,255,255,0) 72%),
    linear-gradient(#F4F5F8 0%, #ECEEF3 62%, #E4E7ED 100%);
  border-bottom:var(--edge) solid var(--line);
  border-radius:13px 13px 0 0;display:grid;place-items:center;
}
.vialbox .vial{position:relative;z-index:1}
.vial{width:130px;height:auto;display:block;transition:transform .18s var(--pop)}
.card:hover .vial{transform:translateY(-4px) rotate(-2.5deg)}
.card{
  padding:22px;overflow:hidden;display:flex;flex-direction:column;
  transition:transform .16s var(--pop),box-shadow .16s var(--pop);
}
.card:hover{transform:translateY(-3px);box-shadow:var(--sh-3);border-color:var(--line-2)}
.tag{align-self:flex-start;font-family:var(--mono);font-size:.6rem;letter-spacing:.12em;text-transform:uppercase;border:1px solid var(--line-2);border-radius:100px;padding:3px 10px;margin-bottom:16px}
.stack{display:flex;gap:3px;flex-wrap:wrap;margin:14px 0 16px;min-height:19px}
.unit{width:15px;height:15px;border:1px solid var(--line-2);border-radius:4px;background:var(--blue)}
.unit.y{background:var(--yellow)}
.unit.r{background:var(--red)}
.count{font-family:var(--mono);font-size:.6rem;font-weight:400;letter-spacing:.1em;text-transform:uppercase;opacity:.6;margin-left:6px;align-self:center}
.nochain{font-family:var(--mono);font-size:.62rem;letter-spacing:.09em;text-transform:uppercase;opacity:.62;border:2px dashed var(--ink);border-radius:6px;padding:2px 9px}
.card p{font-size:.86rem;opacity:.8;margin-bottom:16px}
.spec-2{border-top:0;padding-top:6px;margin-top:0}
.spec{font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;display:flex;justify-content:space-between;border-top:1px dashed var(--line-2);padding-top:11px;margin-top:11px;opacity:.85}
.price{font-family:var(--display);font-weight:800;font-size:1.7rem;color:var(--blue);margin-top:auto;padding-top:14px;display:flex;align-items:baseline;gap:.5rem}
.was{font-family:var(--mono);font-size:.75rem;font-weight:400;text-decoration:line-through;opacity:.65}
/* primary action on each card; RUO now lives once in the footer rather than
   repeated on every product */
.addcart{
  margin-top:14px;width:100%;cursor:pointer;
  font-family:var(--display);font-weight:800;font-size:.88rem;
  color:var(--paper);background:var(--blue);
  border:2px solid var(--ink);border-radius:10px;padding:10px 12px;
  box-shadow:3px 3px 0 var(--ink);
  transition:background .14s ease,transform .12s var(--pop),box-shadow .12s var(--pop);
}
.addcart:hover{background:var(--blue-deep)}
.addcart:active{transform:translate(3px,3px);box-shadow:0 0 0 var(--ink)}
.addcart:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* ─── process ─── */
/* process rendered as a timeline: numbered nodes joined by a rule, rather
   than four separate cards. The connector is built from two half-width
   pseudo-elements per step so the ends stop at the first and last node. */
.steps{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s3);margin-top:var(--s5)}
/* one unbroken rule drawn on the container, inset to the first and last node
   centres (12.5% = half of a quarter column). Per-step segments left gaps at
   every column edge, which is what made it look stitched together. */
.steps::before{
  content:"";position:absolute;top:21px;left:12.5%;right:12.5%;
  height:1px;background:var(--line-2);z-index:0;
}
.step{position:relative;text-align:center;padding:0 10px;background:none;border:0;box-shadow:none}
.step-n{
  position:relative;z-index:1;width:42px;height:42px;margin:0 auto 18px;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--mono);font-size:.76rem;letter-spacing:.06em;
  background:var(--paper);border:1px solid var(--line-2);border-radius:50%;
  box-shadow:var(--sh-1);
}
.step h3{font-size:1.12rem;letter-spacing:-.02em}
.step p{font-size:.89rem;margin-top:9px;opacity:.78;max-width:30ch;margin-inline:auto}
/* one accent across all four nodes — a sequence, not four categories */
.step .step-n{color:var(--blue);border-color:var(--blue)}

/* ─── coa ─── */
.coa{background:var(--blue);color:var(--paper);border-radius:18px;padding:var(--s5) var(--s4);box-shadow:var(--sh-2);text-align:center}
.coa .hero-cta{justify-content:center}
.coa h2{color:var(--paper)}
.coa .eyebrow{color:var(--paper);opacity:.65}
.coa p{max-width:52ch;margin:18px auto 28px;opacity:.94}
.coa 
.coa .stat b{color:var(--blue)}
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:18px;margin-top:38px}
.stat{background:var(--paper);color:var(--ink);border:var(--edge) solid var(--line);border-radius:14px;padding:18px 12px}
.stat b{display:block;font-family:var(--display);font-weight:800;font-size:2.1rem;line-height:1}
.stat span{font-family:var(--mono);font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;opacity:.7}

/* ─── footer ─── */
footer{margin-top:0;padding:var(--s6) 0 var(--s5);position:relative}
footer::before{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:100vw;border-top:1px solid rgba(255,255,255,.10)}
.fcols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:34px}
.fcols h4{font-family:var(--mono);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;margin-bottom:14px}
.fcols ul{list-style:none;display:grid;gap:8px}
.fcols a{font-size:.87rem;text-decoration:none;opacity:.72;color:var(--paper)}
footer{color:var(--paper)}
footer h4{color:var(--paper);opacity:.5}
footer .brand{color:var(--paper)}
/* the mark's palette is tuned for white; on the dark footer the blue drops to
   2.8:1 and reads as a gap, so all three lift to brighter variants */
footer .brand-mark i:nth-child(1){background:#F2543F}
footer .brand-mark i:nth-child(2){background:#F7C22B}
footer .brand-mark i:nth-child(3){background:#5B86FF}
footer .fnote{font-size:.87rem;opacity:.6;max-width:32ch}
.fcols a:hover{opacity:1;text-decoration:underline}
/* RUO callout: an inked panel with the brand's three-brick spine down the
   left edge, so the legal block reads as ours rather than as a generic box.
   Text is measure-capped so it never runs the full 1140px band. */
.ruo-note{
  display:grid;grid-template-columns:19px minmax(0,1fr);gap:0 14px;
  align-items:center;margin-top:var(--s5);
  padding:22px 26px;border:1px solid rgba(255,255,255,.14);border-radius:16px;
  background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.015));
}
.ruo-note svg{width:19px;height:19px;flex:none;color:var(--blue-lt);align-self:center}
.ruo-note p{font-size:.82rem;line-height:1.7;opacity:.72;max-width:none}
.ruo-note b{color:var(--paper);opacity:1;font-weight:700}
.ruo-note a{color:var(--paper);opacity:.9;text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:rgba(255,255,255,.35)}
.ruo-note a:hover{text-decoration-color:var(--paper)}
.fbase{margin-top:22px;padding-top:16px;border-top:1px solid rgba(255,255,255,.08);
  font-family:var(--mono);font-size:.64rem;
  letter-spacing:.1em;text-transform:uppercase;opacity:.4}
@media(max-width:640px){
  .ruo-note{padding:18px;gap:0 12px;grid-template-columns:17px minmax(0,1fr)}
}


/* ─── reveal ─── */
/* Copy stays visible when JS is off or before it runs — crawlers must read it. */
.js .rise{opacity:0;transform:translateY(26px);transition:opacity .5s ease,transform .5s var(--pop)}
.js .rise.in{opacity:1;transform:none}

@media(max-width:860px){
  .hero{grid-template-columns:1fr;gap:36px;padding-top:76px}
  .fcols{grid-template-columns:1fr 1fr}
  .nav-links::-webkit-scrollbar{display:none}
  .nav-links a{white-space:nowrap;font-size:.84rem}
}
/* ─── mobile ───────────────────────────────────────────────────────
   The offset shadows, panel padding and spacing scale were all tuned
   for a wide canvas; at phone width they eat the screen. Everything
   here steps those down proportionally rather than switching layout. */
@media(max-width:640px){
  /* sec-head is a space-between row; on a phone the right-hand link lands
     miles from the heading, so it stacks and tightens instead */
  .sec-head{flex-direction:column;align-items:flex-start;gap:10px;margin-bottom:calc(var(--s3) + 10px)}
  /* vertical timeline on a phone: node column on the left, rule runs down it */
  .steps{grid-template-columns:1fr;gap:0;margin-top:var(--s4)}
  .step{display:grid;grid-template-columns:42px 1fr;gap:4px 16px;
        grid-template-rows:auto auto;align-content:start;
        text-align:left;padding:0 0 26px}
  .steps::before{display:none}
  .step::after{content:"";position:absolute;top:42px;bottom:0;left:20.5px;
        width:1px;background:var(--line-2);z-index:0}
  .step:last-child::after{display:none}
  .step-n{margin:0;grid-row:1 / span 2}
  .step h3{align-self:start;margin-top:8px;font-size:1.05rem;line-height:1.2}
  .step p{grid-column:2;margin-top:0;max-width:none;margin-inline:0}

  .stats{grid-template-columns:1fr 1fr;gap:12px;margin-top:26px}
  .banner{padding:8px 14px}
  .banner p{font-size:.66rem}
    :root{--s3:18px;--s4:24px;--s5:32px;--s6:44px}
  body{font-size:16px;-webkit-text-size-adjust:100%}
  .wrap{padding:0 24px}
  h1{font-size:clamp(2.1rem,9vw,2.9rem)}
  h2{font-size:clamp(1.7rem,7.4vw,2.3rem)}
  .brand{font-size:1.05rem;gap:.4rem}
  .brand-mark{width:23px;height:23px;border-radius:6px}
  .lede{font-size:1rem}
  .hero .lede{font-size:.86rem;line-height:1.55;font-weight:300;max-width:321px;margin-inline:auto}

  .hero{padding:56px 0 var(--s6)}
  .btn{padding:12px 20px;font-size:.95rem;box-shadow:3px 3px 0 var(--ink)}
  .sec-head{gap:6px}
  .cats{margin:0 0 12px}
  .viewall{margin-bottom:14px;font-size:.68rem}
  /* stats go 2x2, so the dividers have to move from columns to a grid */
  .hero-stats{box-shadow:var(--sh-1)}
  .hs{flex:1 1 46%;padding:14px 8px;border-bottom:1px solid var(--line)}
  .hs:nth-child(even){border-right:0}
  .hs:nth-last-child(-n+2){border-bottom:0}

  .aa-grid{grid-template-columns:repeat(auto-fit,minmax(58px,1fr));gap:8px}
  .aa{border-width:1px;box-shadow:var(--sh-1)}

  /* two per row on a phone; padding drops so the cards aren't mostly gutter,
     and the vial bleed has to track the new padding exactly */
  .cards{grid-template-columns:1fr 1fr;gap:12px}
  .panel{box-shadow:var(--sh-1)}
  .card{padding:13px}
  .vialbox{margin:-13px -13px 11px;padding:11px 6px 8px}
  .vial{width:104px}
  /* vertical rhythm is retuned for the narrow card: the desktop margins were
     set against 22px padding, and hiding the blurb took its margin with it */
  .card .tag{font-size:.55rem;padding:2px 8px}
  .card h3{font-size:.98rem;letter-spacing:-.01em;margin-top:7px;line-height:1.2}
  /* two cards per row leaves ~147px of content, so 15px blocks fit only 8 to a
     line and a 43-residue chain runs six rows. Smaller blocks hold the longest
     chain to three rows without hiding any of it. */
  .card .stack{margin:9px 0 0;gap:1.5px;min-height:10px}
  .card .unit{width:8px;height:8px;border-radius:2px}
  .card .count{font-size:.53rem;margin-left:4px}
  .card .nochain{font-size:.54rem;padding:2px 6px}
  .card p{display:none}          /* blurb doesn't survive a half-width card */
  .card .price{font-size:1.15rem;padding-top:10px;gap:.35rem}
  .card .was{font-size:.66rem}
  /* pushes the spec + RUO block to the bottom so every card's footer lines up
     even when a product name wraps to two lines */
  .card .spec{font-size:.57rem;letter-spacing:.02em;padding-top:9px}
  .spec-2{display:none}          /* second spec row is detail, not decision */
  .card .addcart{font-size:.78rem;padding:9px 8px;margin-top:10px;border-radius:9px}
  .card:hover{transform:none;box-shadow:var(--sh-1)}

  .coa{padding:var(--s4) 20px;box-shadow:var(--sh-2)}

  .fcols{grid-template-columns:1fr;gap:26px}
  .fcols ul{gap:2px}
  .fcols a{display:inline-block;padding:7px 0}   /* real tap targets */
  .nav-links a{padding:8px 0}
}
/* ─── mobile drawer ────────────────────────────────────────────────
   Below 860px the inline links become a slide-in panel. The trigger and
   the panel borrow the same inked-frame language as the rest of the page. */
.burger{
  display:none;flex-direction:column;align-items:center;justify-content:center;gap:5px;
  width:46px;height:46px;flex:none;padding:0;cursor:pointer;
  background:var(--paper);border:2px solid var(--ink);border-radius:12px;
  box-shadow:3px 3px 0 var(--ink);
  transition:transform .12s var(--pop),box-shadow .12s var(--pop);
}
.burger:active{background:var(--shell);transform:translate(3px,3px);box-shadow:0 0 0 var(--ink)}
.burger span{
  display:block;width:20px;height:3px;background:var(--ink);border-radius:2px;
  transition:transform .2s var(--pop),opacity .12s linear;
}
.burger[aria-expanded="true"] span:nth-child(1){transform:translateY(8px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}

.scrim{
  display:none;position:fixed;inset:0;z-index:50;background:rgba(16,18,26,.55);
  opacity:0;visibility:hidden;transition:opacity .2s ease,visibility 0s linear .2s;
}
.scrim.open{opacity:1;visibility:visible;transition:opacity .2s ease}
.drawer{
  display:none;flex-direction:column;position:fixed;top:0;right:0;bottom:0;z-index:60;
  width:min(330px,86vw);padding:18px;overflow-y:auto;
  background:var(--paper);border-left:var(--edge) solid var(--line);
  transform:translateX(100%);visibility:hidden;
  transition:transform .24s var(--pop),visibility 0s linear .24s;
}
.drawer.open{transform:none;visibility:visible;transition:transform .24s var(--pop)}
.drawer-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px}
.drawer-close{
  width:38px;height:38px;flex:none;padding:0;cursor:pointer;line-height:1;
  font-family:var(--display);font-weight:800;font-size:1.25rem;color:var(--ink);
  background:var(--paper);border:2px solid var(--ink);border-radius:11px;
  box-shadow:3px 3px 0 var(--ink);
}
.drawer-close:active{background:var(--shell);transform:translate(3px,3px);box-shadow:0 0 0 var(--ink)}
.drawer ul{list-style:none;display:grid;gap:2px}
.drawer ul a{
  display:block;text-decoration:none;padding:13px 4px;
  font-family:var(--display);font-weight:800;font-size:1.3rem;letter-spacing:-.02em;
  border-bottom:2px solid rgba(16,18,26,.12);
}
.drawer ul a:hover,.drawer ul a:focus-visible{color:var(--blue)}
.drawer .btn{margin-top:22px;text-align:center}
.drawer .drawer-note{margin-top:auto;padding-top:22px;opacity:.6}

@media(max-width:860px){
  .burger{display:flex}
  .nav-links{display:none}
  /* the auto margin that pushed the bar right lived on .nav-links, which is
     hidden here — so it moves to the cart, keeping cart+burger flush right */
  .nav-in>.btn-sm{margin-left:auto}
  .nav-in{flex-wrap:nowrap;gap:.7rem;padding-left:24px;padding-right:24px}
  .drawer,.scrim{display:flex}
}

/* ─── floating cart (mobile) ───────────────────────────────────────
   Below 860px the cart leaves the bar and becomes a thumb-reach FAB,
   which also frees the top bar to be just brand + menu. */
.cart-fab{
  display:none;position:fixed;right:16px;z-index:45;
  bottom:calc(16px + env(safe-area-inset-bottom));
  align-items:center;gap:9px;padding:14px 18px;text-decoration:none;
  font-family:var(--display);font-weight:800;font-size:.95rem;color:var(--ink);
  background:var(--paper);border:2px solid var(--ink);border-radius:15px;
  box-shadow:4px 4px 0 var(--ink);
  transition:transform .12s var(--pop),box-shadow .12s var(--pop),opacity .2s ease;
}
.cart-fab:active{transform:translate(4px,4px);box-shadow:0 0 0 var(--ink)}
.cart-fab .cart-ico{width:17px;height:17px;flex:none;display:block}
  .cart-fab .cart-n{
  min-width:21px;height:21px;padding:0 5px;border-radius:11px;
  background:var(--blue);color:var(--paper);font-size:.72rem;
  display:inline-flex;align-items:center;justify-content:center;
}
/* it sits above the RUO strip, so it steps aside at the very bottom */
.cart-fab.tucked{opacity:0;pointer-events:none;transform:translateY(12px)}

/* the floating cart is used at every size now */
.cart-fab{display:inline-flex}
.nav-in>.btn-sm{display:none}
@media(max-width:860px){
  .nav-in>.burger{margin-left:auto}
}

/* ─── categories ─── */
/* one scrolling row instead of wrapping to two — the chips are a filter bar,
   not content, so they shouldn't claim vertical space.
   No mask here: it renders inconsistently on a scroll container, and a chip
   row that fails to paint is a far worse trade than a hard right edge. */
.cats{
  display:flex;flex-wrap:nowrap;gap:9px;margin:2px 0 16px;
  overflow-x:auto;overscroll-behavior-x:contain;
  scrollbar-width:none;-ms-overflow-style:none;
  scroll-snap-type:x proximity;
  padding-bottom:2px;
}
.cats::-webkit-scrollbar{display:none}
/* sits between the filter row and the grid, so it stays a quiet text action */
.viewall{
  display:inline-block;margin:0 0 var(--s3);
  font-family:var(--mono);font-size:.72rem;letter-spacing:.06em;
  color:var(--blue);text-decoration:none;
  border-bottom:1px solid rgba(27,79,216,.3);padding-bottom:2px;
}
.viewall:hover{border-bottom-color:var(--blue)}
/* no chip row above it here, so it keeps a normal gap under the heading */
.viewall-top{margin-top:0}
.cat{
  flex:none;scroll-snap-align:start;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.06em;text-decoration:none;
  padding:9px 15px;border:var(--edge) solid var(--line);border-radius:100px;
  background:var(--paper);box-shadow:var(--sh-1);
  transition:transform .12s var(--pop),box-shadow .12s var(--pop);
}
.cat:hover{border-color:var(--blue);color:var(--blue)}

/* ─── manifesto ─── */
.why-lede{max-width:62ch;margin:-6px auto 0;opacity:.85;text-align:center}
.versus{display:grid;grid-template-columns:1fr 1fr;gap:var(--s3);margin-top:var(--s4);align-items:stretch}
.vs{padding:26px 24px;border:var(--edge) solid var(--line);border-radius:16px}
.vs-them{background:var(--paper);box-shadow:none;color:var(--mute);opacity:.92}
.vs-them h3{color:var(--ink);opacity:.75}
.vs-us{background:var(--paper);border-color:var(--blue);border-width:2px;box-shadow:var(--sh-3)}
.vs .tag{display:inline-block;font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;opacity:.65}
.vs-us .tag{color:var(--blue);opacity:1}
.vs h3{margin:10px 0 16px;font-size:1.3rem;letter-spacing:-.02em}
.vs ul{list-style:none;display:grid;gap:10px;font-size:.92rem}
.vs li{display:flex;gap:10px;align-items:flex-start}
.vs li::before{content:"×";font-weight:800;opacity:.45;line-height:1.35;flex:none}
.vs-us li::before{content:"✓";opacity:1;color:var(--blue);font-weight:800}

/* ─── why grid ─── */
.why{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3)}
@media(max-width:900px){.why{grid-template-columns:repeat(2,minmax(0,1fr))}}
.why .panel{position:relative;padding:24px 22px}
/* icon in a bordered tile, the way the reference does it — reads faster than
   a corner numeral, which was only ever counting */
.why .ico{
  display:flex;align-items:center;justify-content:center;
  width:44px;height:44px;margin-bottom:16px;
  border:1px solid var(--line);border-radius:12px;background:var(--paper);
}
.why .ico svg{width:21px;height:21px;color:var(--blue)}
.why h3{font-size:1.06rem;margin-bottom:8px;letter-spacing:-.01em}
.why p{font-size:.9rem;opacity:.82}

/* ─── bundles ─── */
.stacks{display:grid;grid-template-columns:repeat(auto-fit,minmax(262px,1fr));gap:var(--s3)}
/* NB: .bundle, not .stack — .stack is the block row inside product cards */
.bundle{padding:24px 22px;display:flex;flex-direction:column}
/* two vials side by side, on the same grey dot field as the product cards */
.pairbox{
  position:relative;overflow:hidden;
  margin:-24px -22px 16px;padding:20px 10px 12px;
  background:
    radial-gradient(ellipse 78% 58% at 50% 34%,
      #FFFFFF 0%, rgba(255,255,255,0) 72%),
    linear-gradient(#F4F5F8 0%, #ECEEF3 62%, #E4E7ED 100%);
  border-bottom:var(--edge) solid var(--line);
  border-radius:13px 13px 0 0;
  display:flex;align-items:center;justify-content:center;gap:0;
}
/* the pair overlaps slightly and the back vial sits lower, so they read as two
   objects standing together rather than two flat cut-outs */
/* same size as the vials on the product cards, and level with each other:
   scaling or dropping the back one made the pair look mismatched rather than
   like two identical vials standing together */
.pairbox .vial{position:relative;z-index:1;width:130px;height:auto;display:block}
.pairbox .vial:first-child{z-index:2;margin-right:-18px}
@media(max-width:640px){
  .pairbox{margin:-16px -14px 12px;padding:12px 6px 9px}
  .pairbox .vial{width:104px}
  .pairbox .vial:first-child{margin-right:-14px}
}
.bundle .tag{font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;
  text-transform:uppercase;opacity:.65}
.bundle h3{margin:9px 0 14px;font-size:1.18rem;letter-spacing:-.02em}
.bundle ul{list-style:none;display:grid;gap:7px;font-size:.87rem;margin-bottom:16px}
.bundle li{display:flex;justify-content:space-between;gap:12px;
  padding-bottom:7px;border-bottom:2px solid rgba(16,18,26,.1)}
.bundle li i{font-style:normal;font-family:var(--mono);font-size:.76rem;opacity:.6}
.bundle .price{font-family:var(--display);font-weight:800;font-size:1.2rem;
  color:var(--blue);margin-top:auto;display:flex;align-items:baseline;gap:.5rem}
/* button sits flush at the bottom so every bundle card lines up */
.bundle .addcart{margin-top:14px}

/* ─── faq ─── */
.faq{display:grid;gap:12px;max-width:800px;margin:0 auto}
.faq details{background:var(--paper);border:var(--edge) solid var(--line);
  border-radius:14px;box-shadow:var(--sh-1);overflow:hidden}
.faq summary{
  cursor:pointer;list-style:none;padding:17px 20px;font-family:var(--display);
  font-weight:800;font-size:1rem;letter-spacing:-.01em;
  display:flex;justify-content:space-between;gap:16px;align-items:center;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-size:1.3rem;line-height:1;flex:none;opacity:.6}
.faq details[open] summary::after{content:"–"}
.faq p{padding:0 20px 19px;font-size:.92rem;opacity:.85;max-width:62ch}

@media(max-width:640px){
  .versus{grid-template-columns:1fr;gap:16px;margin-top:var(--s3)}
  .vs{padding:20px 18px}
  .why,.stacks{grid-template-columns:1fr}
}

@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  
  .rise{opacity:1;transform:none}
  html{scroll-behavior:auto}
}

/* ─── hero + credentials: paper-to-grey ombre ────────────────────────
   One wash across the hero and the stats below it: paper at the top edge,
   under the header, deepening to grey at the bottom. It ends hard just
   below the credibility numbers, which is what draws the separator
   between this opening block and the catalog. Same z-index:-1 trick the
   tonal bands use, so it paints above the page background but under the
   bricks, the copy and the stats card. */
.hero-band{position:relative}
.hero-band::before{
  content:'';position:absolute;z-index:-1;
  top:0;bottom:-1px;   /* -1px kills the hairline rounding leaves under it */
  left:50%;transform:translateX(-50%);width:100vw;
  /* a straight two-stop ramp bands through the middle; the extra stops
     back-load the falloff so the top reads as clean paper and the grey
     only arrives near the stats */
  background:linear-gradient(180deg,
    var(--paper) 0%,
    var(--paper) 8%,
    #F4F6F9 34%,
    #EBEEF3 60%,
    #E1E5EC 82%,
    #D9DEE7 100%);
}

/* the type sat on an opaque paper cushion to lift it off the flying bricks.
   Against a solid white background that was invisible; on the grey it reads
   as a white blob behind the headline, so it drops to a translucent one —
   still enough separation from a brick, no visible patch. */
.hero h1,.hero .lede{
  text-shadow:0 0 16px rgba(255,255,255,.6),0 0 6px rgba(255,255,255,.5);
}

/* the eyebrow declares display:inline-flex, but the generic `.eyebrow` rule
   further down the sheet sets display:inline-block at the same specificity
   and wins on source order — so the gap and align-items were never applied
   and the shield sat flush against the T, riding the text baseline.
   Restoring flex puts the icon and the line back on one level. */
.hero-eyebrow{display:inline-flex;align-items:center;gap:7px}

/* the badge fills solid: the shield body takes the blue, and the tick inside
   flips to paper so it still reads at 14px. The SVG carries fill="none" as a
   presentation attribute, which CSS outranks, so this needs no markup change. */
.eb-shield path:first-of-type{fill:currentColor}
.eb-shield path:last-of-type{stroke:var(--paper)}

/* ─── stack cards, matched to the product cards ──────────────────────
   The bundles carry the .card class now, so they inherit its padding,
   hover lift and vial nudge for free. What's left is undoing the three
   places .bundle deliberately diverged, plus the savings badge. */

/* the tag was plain low-contrast mono here; on a product card it's an
   outlined pill, so it goes back to being one */
.bundle .tag{
  font-family:var(--mono);font-size:.6rem;letter-spacing:.12em;
  text-transform:uppercase;opacity:1;
  align-self:flex-start;border:1px solid var(--line-2);
  border-radius:100px;padding:3px 10px;margin-bottom:16px;
}
.bundle h3{margin:0 0 14px;font-size:1.22rem}

/* the contents list becomes the same dashed hairline rows the product
   cards use for purity and batch — same job, same treatment */
.bundle ul{
  font-family:var(--mono);font-size:.66rem;letter-spacing:.06em;
  gap:0;margin-bottom:0;opacity:.85;
}
.bundle li{
  border-bottom:0;border-top:1px dashed var(--line-2);
  padding:11px 0 0;margin-top:11px;
}
.bundle li i{font-size:1em;opacity:1}

/* the price was two-thirds the size of a product card's, which is what
   made these read as a lesser card rather than a sibling */
.bundle .price{font-size:1.7rem;padding-top:14px}

/* the saving used to be the tail of a low-contrast mono tag. It's the
   whole reason to buy a stack, so it gets the page's inked-chip
   treatment in yellow and sits opposite the price, where the struck-out
   figure it's explaining already is. */
.bundle .pairbox{position:relative}
.bundle .save{
  position:absolute;top:12px;right:12px;z-index:2;
  display:inline-flex;align-items:center;white-space:nowrap;flex:none;
  font-family:var(--display);font-weight:800;font-size:.74rem;
  letter-spacing:.01em;text-transform:uppercase;line-height:1.4;
  background:var(--yellow);color:var(--ink);
  border:2px solid var(--ink);border-radius:100px;padding:3px 11px;
}

@media(max-width:640px){
  /* .bundle keeps its own 24/22 padding here, so the pair image has to
     track that rather than the narrower product-card figure */
  .pairbox{margin:-24px -22px 12px}
  .bundle .save{font-size:.68rem;padding:3px 9px;top:10px;right:10px}
}

/* ─── lab-results panel, on white ────────────────────────────────────
   The panel was a solid blue block with white type. On white it needs a
   frame to read as a panel at all, so it picks up the same hairline the
   cards use; the shadow it already had does the rest. */
.coa{
  background:var(--paper);color:var(--ink);
  border:var(--edge) solid var(--line);
}
.coa h2{color:var(--ink)}
.coa .eyebrow{color:var(--blue);opacity:1}
.coa p{opacity:.78}

/* the numbers were always meant to be blue — the existing rule was written
   as `.coa` on one line and `.coa .stat b` on the next, which CSS reads as
   one descendant selector hunting for a .coa inside a .coa. It never
   matched, so the figures stayed ink. */
.coa .stat b{color:var(--blue)}

/* and the stat tiles take the frame the product and stack cards use */
.stat{border-radius:16px;box-shadow:var(--sh-2);padding:20px 12px}

/* ─── heading breaks on a phone ───────────────────────────────────────
   Three headings carry a hard <br> tuned for a wide column. Below 640 the
   first half no longer fits on one line, so the break lands mid-phrase and
   strands a single word — 'supplier', 'order.', 'problem.' — on its own
   line. Dropping the break there lets the heading wrap on its own terms.
   The markup carries a real space in front of each, so nothing collides
   when the break switches off. */
@media(max-width:640px){
  .h2brk{display:none}
  /* dropping the break isn't enough on its own — natural wrapping strands
     'order.' in exactly the same spot. Balancing evens the line lengths
     across the whole heading, so no line is left with one word. */
  h1,h2,h3{text-wrap:balance}
}

/* ─── centred section headings on a phone ─────────────────────────────
   .sec-head-mid centres with justify-content, which works while the row
   is a row. Below 640 .sec-head flips to flex-direction:column, so
   justify-content starts governing the vertical axis and align-items
   governs the horizontal — and align-items is set to flex-start there.
   The heading block shrank to its content and hugged the left edge while
   its text stayed centred inside it, which put 'Four steps.' 58px left of
   centre. align-items is what has to be set once the axis flips. */
@media(max-width:640px){
  .sec-head-mid{align-items:center}
}

/* ─── footer menus: two columns on a phone ────────────────────────────
   Below 640 the footer collapsed to a single column, which stacked the
   brand block plus 19 links into one very long run before the research-use
   notice. Two columns halves that. The brand block spans both so it keeps
   its full measure, then the three menus flow Shop / Company across the
   first row and Legal into the second. */
@media(max-width:640px){
  .fcols{grid-template-columns:1fr 1fr;gap:26px 18px}
  .fcols>div:first-child{grid-column:1 / -1}   /* brand keeps its full measure */
  /* Shop has 8 links against Company's 7 and Legal's 4. Left to auto-place,
     Legal drops to a new row and leaves a hole beside it. Running Shop down
     the left and stacking Company over Legal on the right fills both
     columns and comes out shorter. */
  .fcols>div:nth-child(2){grid-column:2;grid-row:2 / span 2}  /* Shop right */
  .fcols>div:nth-child(3){grid-column:1;grid-row:2}           /* Company left */
  .fcols>div:nth-child(4){grid-column:1;grid-row:3}           /* Legal left */
  .fcols a{font-size:.82rem}
}

/* ─── footer link rhythm on a phone ───────────────────────────────────
   Each row was running 36px: a 20px line plus 7px of tap padding top and
   bottom, then a 2px gap. Most of that height was invisible padding, so
   the list read as loosely spaced rather than as generous targets. This
   tightens the leading and trims the padding to land on a 28px row —
   the same pitch the desktop footer uses — while keeping the whole row
   tappable rather than just the text. */
@media(max-width:640px){
  .fcols ul{gap:0}
  .fcols a{padding:5px 0;line-height:1.4}
}

/* ─── brand mark: three separated bars ────────────────────────────────
   The three colour bars sat flush inside one clipped rounded square, so
   the only thing dividing them was the colour change — which read as a
   single striped block rather than three marks. Splitting them apart and
   giving each its own corners makes them read as three separate blocks,
   which is also closer to what the page is about. */
.brand-mark{
  gap:3px;overflow:visible;border-radius:0;
}
.brand-mark i{border-radius:2px}
/* the footer brand is an <a> inside .fcols, so the .72 link opacity was
   dimming it — including the mark colours that were lifted specifically to
   hold up against the dark band */
.fcols .brand{opacity:1}
@media(max-width:640px){
  .brand-mark{gap:2.5px}
  /* the footer lockup keeps its desktop scale on small screens */
  footer .brand{display:flex;font-size:.87rem;gap:.5rem;letter-spacing:-.035em;flex-wrap:nowrap}
  footer .brand-mark{width:26px;height:26px;gap:3px}
}

/* ─── age / research-use gate ─────────────────────────────────────────
   Sits above everything and blocks the page until both declarations are
   ticked. The lock is a class on <html> set in the markup rather than by
   script, so the page can't be scrolled during the moment before the
   script runs. */
html.gated{overflow:hidden}
.gate{
  position:fixed;inset:0;z-index:200;
  display:flex;align-items:center;justify-content:center;
  padding:24px 20px;overflow-y:auto;
  background:rgba(9,12,24,.55);
  -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
}
.gate-panel{
  /* margin:auto rather than place-items:center — a centred grid item that
     outgrows its container gets clipped at the top and can't be scrolled to */
  margin:auto;width:100%;max-width:452px;text-align:center;
  background:var(--paper);border:var(--edge) solid var(--line);
  border-radius:18px;box-shadow:var(--sh-3);padding:32px 30px;
}
/* the lockup sits where the eyebrow did — same slot, but it identifies the
   site instead of repeating the headline back at it */
.gate-brand{justify-content:center;font-size:1.2rem;margin-bottom:16px}
.gate h2{font-size:1.95rem;letter-spacing:-.025em;line-height:1.02}
.gate-lede{font-size:.9rem;line-height:1.6;opacity:.78;margin:14px auto 22px;max-width:38ch}

/* each declaration is its own framed row, so ticking one is a visible act
   rather than a checkbox lost in a paragraph */
.gate-check{
  display:flex;gap:12px;align-items:flex-start;text-align:left;
  border:var(--edge) solid var(--line);border-radius:12px;
  padding:14px 15px;margin-top:11px;cursor:pointer;
  font-size:.87rem;line-height:1.5;
  transition:border-color .14s ease,background-color .14s ease;
}
.gate-check:hover{border-color:var(--line-2)}
.gate-check:has(input:checked){border-color:var(--blue-lt);background-color:var(--wash)}
.gate-check b{font-weight:700}
.gate-check input{
  appearance:none;-webkit-appearance:none;flex:none;
  width:21px;height:21px;margin:1px 0 0;position:relative;cursor:pointer;
  background:var(--paper);border:2px solid var(--line-2);border-radius:6px;
  transition:background-color .12s ease,border-color .12s ease;
}
.gate-check input:checked{background:var(--blue);border-color:var(--blue)}
.gate-check input:checked::after{
  content:'';position:absolute;left:6px;top:2px;width:4px;height:9px;
  border:solid var(--paper);border-width:0 2.5px 2.5px 0;transform:rotate(43deg);
}

.gate-enter{width:100%;margin-top:20px;text-align:center}
.gate-enter[disabled]{
  background:var(--shell);color:var(--mute);
  border-color:var(--line-2);box-shadow:3px 3px 0 var(--line);
  cursor:not-allowed;
}
/* :hover still fires on a disabled button, so the press animation has to be
   switched off explicitly or the button appears interactive */
.gate-enter[disabled]:hover,.gate-enter[disabled]:active{
  transform:none;box-shadow:3px 3px 0 var(--line);
}
.gate-note{
  margin-top:10px;font-family:var(--mono);font-size:.6rem;
  letter-spacing:.1em;text-transform:uppercase;opacity:.5;
}
.gate-enter:not([disabled]) + .gate-note{visibility:hidden}
.gate-links{
  margin-top:18px;display:flex;gap:9px;justify-content:center;align-items:center;
  flex-wrap:wrap;font-family:var(--mono);font-size:.63rem;letter-spacing:.05em;
}
.gate-links a{color:var(--mute);text-decoration:underline;text-underline-offset:3px}
.gate-links a:hover{color:var(--ink)}
.gate-links span{opacity:.35}
@media(max-width:640px){
  .gate{padding:18px 14px}
  .gate-panel{padding:26px 20px;border-radius:16px}
  .gate h2{font-size:1.65rem}
  .gate-check{font-size:.83rem;padding:13px 13px}
}

/* ─── blue-tinted surfaces ────────────────────────────────────────────
   The banded sections and the footer were neutral greys sitting under a
   blue brand. Both shift onto the blue axis: the bands to a pale tint at
   the same lightness the grey had, so text contrast is unchanged, and
   the footer from near-black to a deep navy. */
:root{
  --sand:#EDF2FC;          /* was #F1F2F5 — same value, blue hue */
  /* near-black, holding just enough blue that it still belongs to the palette
     rather than reading as a neutral grey-black */
  --floor:#05070F;
}
.tint-ink-solid::before{background-color:var(--floor)}

/* the hero wash was the same neutral ramp, so it follows the bands over
   rather than being left as the one grey surface on the page */
.hero-band::before{
  background:linear-gradient(180deg,
    var(--paper) 0%,
    #F7FAFE 20%,
    #EDF3FC 48%,
    #E1EAF8 72%,
    #D9E4F6 88%,   /* deepest point sits behind the credentials strip */
    #E2EBF8 100%);
}

/* ─── section rhythm ──────────────────────────────────────────────────
   More air between sections so the page reads as a sequence of distinct
   stops rather than a continuous run. Banded sections keep a little more
   than plain ones: a tint has visible edges, and content sitting close to
   them looks cramped in a way it doesn't on open white. */
section{padding:96px 0}
section.tint{padding:112px 0}
section#creds{padding:var(--s5) 0 88px}   /* also sets where the hero wash ends */
footer{padding:88px 0 var(--s5)}
@media(max-width:900px){
  section{padding:76px 0}
  section.tint{padding:88px 0}
}
@media(max-width:640px){
  /* a phone screen is short, so the same ratio would push a heading and its
     content onto separate screens — this scales back rather than tracking
     the desktop values */
  section{padding:60px 0}
  section.tint{padding:72px 0}
  section#creds{padding:var(--s4) 0 62px}
  footer{padding:64px 0 var(--s5)}
}

/* catalog, stacks and the fun-fact band sit on one continuous paper
   background, so the full section rhythm reads as dead space between them */
section#catalog{padding-bottom:64px}
section#stacks{padding:64px 0}
section#set{padding:64px 0 112px}
@media(max-width:900px){
  section#catalog{padding-bottom:52px}
  section#stacks{padding:52px 0}
  section#set{padding:52px 0 92px}
}
@media(max-width:640px){
  section#catalog{padding-bottom:40px}
  section#stacks{padding:40px 0}
  section#set{padding:40px 0 76px}
}

/* ─── hero description: three lines ───────────────────────────────────
   The three sentences are separated by hard <br>s that were switched on
   from 901px up. But between 901 and roughly 1180 the copy column isn't
   wide enough to hold a 65-character sentence, so each forced line wrapped
   again and the paragraph ran to five lines. The breaks now wait until the
   column can actually hold them; below that the text wraps on its own at a
   measure tuned to land on three lines. */
.brk{display:none}
.hero .lede{max-width:min(58ch,100%)}
@media(min-width:1180px){
  .brk{display:none}
  .hero .lede{max-width:68ch}   /* wide enough that only the breaks wrap it */
}
/* at narrow desktop the product column was taking enough width to squeeze
   the copy to four lines; the vial gives a little back */
@media(min-width:901px) and (max-width:1120px){
  .hero{grid-template-columns:minmax(0,1fr) minmax(0,.78fr)}
}
@media(max-width:640px){
  /* line the copy up with the two CTA buttons below it */
  .hero .lede{max-width:321px;margin-inline:auto}
}

/* hero band and the manifesto read as one continuous ombre: light at the top
   where it meets the hero, deepening into ink at the bottom so the section
   ends on a hard cut line against the catalog below */
#why.tint::before{
  background:linear-gradient(180deg,
    #E2EBF8 0%,
    #E9F0FB 35%,
    #F2F6FD 65%,
    #FAFCFE 88%,
    var(--paper) 100%);
}
#why{padding-top:48px}
#why .sec-head h2{color:var(--ink)}
#why .eyebrow{display:inline-block;margin-bottom:14px}
#why .why-lede{margin-top:18px}
#why .versus{margin-top:calc(var(--s4) + 20px)}
@media(max-width:900px){#why{padding-top:36px}}
@media(max-width:640px){#why .why-lede{max-width:30ch;margin-left:auto;margin-right:auto}}





/* tablet: same light, narrow measure as the phone hero copy */
@media(min-width:641px) and (max-width:900px){
  .hero .lede{font-size:.95rem;line-height:1.6;font-weight:300;max-width:44ch}
}
/* desktop: the copy shares the same left edge and measure as the headline
   and the CTA row */
@media(min-width:901px){
  .hero .lede{margin-left:0;margin-right:0;max-width:100%;margin-bottom:var(--s4)}
}
/* keep the copy at exactly three lines on narrow desktop: force the breaks on
   and scale the type down just enough that the longest line still fits */
@media(min-width:901px) and (max-width:1179px){
  .brk{display:none}
  .hero .lede{font-size:1.06rem;line-height:1.6;white-space:normal;max-width:52ch}
}

@media(min-width:1180px){
  .brk{display:none}
  .hero .lede{max-width:56ch;white-space:normal;font-size:1.06rem;line-height:1.6}
}

/* ─── ship-to country + currency picker ─── */
.cur-pick{position:relative;margin-left:auto;margin-right:10px}
.nav-in .cur-pick + .btn-sm{margin-left:0}
.cur-btn{display:inline-flex;align-items:center;gap:7px;background:#fff;border:1px solid rgba(18,20,27,.14);
  border-radius:999px;padding:7px 11px;font:inherit;font-size:.8rem;font-weight:500;color:#12141B;cursor:pointer;
  line-height:1;transition:border-color .18s ease,box-shadow .18s ease}
.cur-btn:hover{border-color:rgba(18,20,27,.3);box-shadow:0 2px 10px rgba(18,20,27,.07)}
.cur-btn .cur-flag{font-size:1rem;line-height:1}
.cur-btn .cur-code{font-size:.66rem;opacity:.55;letter-spacing:.04em}
.cur-btn svg{width:13px;height:13px;opacity:.5}
.cur-ship{display:none}
.cur-menu{position:absolute;top:calc(100% + 8px);right:0;z-index:120;width:250px;max-height:320px;overflow:auto;
  background:#fff;border:1px solid rgba(18,20,27,.12);border-radius:14px;box-shadow:0 18px 44px rgba(18,20,27,.16);padding:6px}
.cur-menu button{display:flex;width:100%;align-items:center;gap:9px;background:none;border:0;border-radius:9px;
  padding:8px 10px;font:inherit;font-size:.84rem;color:#12141B;cursor:pointer;text-align:left}
.cur-menu button span:first-child{font-size:1.05rem;line-height:1}
.cur-menu button i{margin-left:auto;font-style:normal;font-size:.66rem;opacity:.5}
.cur-menu button:hover{background:rgba(18,20,27,.05)}
.cur-menu button.on{background:rgba(27,79,216,.08);font-weight:600}
@media (max-width:860px){
  .nav-in .cur-pick{display:none}
  .drawer .cur-pick{position:static;margin:18px 0 0}
  .drawer .cur-btn{width:100%;justify-content:flex-start}
  .drawer .cur-menu{position:static;width:100%;margin-top:8px;max-height:240px;box-shadow:none}
  .drawer .cur-ship{display:block;margin-top:8px;font-size:.66rem;opacity:.55}
}
.cur-img{width:20px;height:15px;border-radius:2px;object-fit:cover;display:block;box-shadow:0 0 0 1px rgba(18,20,27,.08)}
.cur-btn .cur-flag{display:flex}
.cur-menu button span:first-child{display:flex;align-items:center}
