@import url("/assets/fonts.css");

/* ==========================================================================
   store-kit — storefront design system
   Implements research/03-art-direction.md §1–§5. Every value below is a token
   substituted by scaffold.js from theme.js (§6.2). There is no raw hex in this
   file: a colour that is not a token is a bug, not a style choice.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1 · Tokens. The full light palette is defined on bare :root so no colour has
   its only definition inside a media query (§3.4).
   -------------------------------------------------------------------------- */
:root{
  color-scheme: light dark;

  /* brand — derived from the one accent the merchant supplies */
  --brand-accent:   #0F5E4E;
  --brand-deep:     #004337;
  --brand-tint:     #D8F2EA;
  --accent-ink:     #FFFFFF;

  /* surfaces */
  --surface-page:    #F5F8F7;
  --surface-raised:  #FFFFFF;
  --surface-sunken:  #E8EFEC;
  --surface-inverse: #101614;

  /* ink */
  --ink-strong:  #101614;
  --ink:         #29322F;
  --ink-quiet:   #54605C;
  --ink-faint:   #7B8783;
  --ink-inverse: #F0F5F3;

  /* lines — hairline and line are decorative only; line-strong borders controls */
  --line-hairline: #D9E2DF;
  --line:          #C3CECA;
  --line-strong:   #6D7975;

  /* state */
  --state-good:       #1F7A4C;
  --state-good-quiet: #DFF5E6;
  --state-warn:       #8A5A00;
  --state-warn-quiet: #FBECD9;
  --state-bad:        #A32C1E;
  --state-bad-quiet:  #FFE9E5;

  /* commerce semantics */
  --price-ink:     #101614;
  --price-was-ink: #7B8783;
  --sale-flag-bg:  #8E2C17;
  --sale-flag-ink: #FFFFFF;
  --stock-low-ink: #8A5A00;
  --stock-out-ink: #54605C;
  --ship-free-ink: #0F5E4E;
  --pickup-ink:    #1F7A4C;

  /* spacing (§1.1) */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:24px; --sp-6:32px; --sp-7:48px; --sp-8:64px;
  --sp-9:96px; --sp-10:128px; --sp-11:176px;

  /* radius (§1.4) — product photography is always --r-0 */
  --r-0:0; --r-1:2px; --r-2:6px; --r-3:14px; --r-pill:999px;

  /* elevation — neutral, never tinted */
  --el-1:0 1px 2px rgba(16,22,20,.06);
  --el-2:0 6px 16px -6px rgba(16,22,20,.14);
  --el-3:0 24px 48px -18px rgba(16,22,20,.28);

  /* the one permitted gradient (§3.6) */
  --scrim:linear-gradient(to top, rgba(16,22,20,.72) 0%, rgba(16,22,20,.34) 38%, transparent 72%);

  /* type (§2.2) */
  --font-display:"Bricolage Grotesque", "Helvetica Neue", "Segoe UI", Roboto, Arial, sans-serif;
  --font-display-stretch:100%;
  --font-text:"Hanken Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-mono:"Spline Sans Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fs-micro:0.6875rem;
  --fs-fine:0.8125rem;
  --fs-base:1rem;
  --fs-lead:1.1875rem;
  --fs-4:1.4375rem;
  --fs-3:1.9375rem;
  --fs-2:2.5625rem;
  --fs-1:clamp(2.125rem, 1.55rem + 2.4vw, 3.4375rem);
  --fs-display-1:clamp(2.5rem, 1.60rem + 3.2vw, 4.5625rem);

  /* motion (§5.1) */
  --dur-state:120ms;
  --dur-elem:200ms;
  --dur-overlay:320ms;
  --ease-in:cubic-bezier(.2,.7,.2,1);
  --ease-out:cubic-bezier(.4,0,1,1);

  /* containers (§1.3) */
  --w-read:62ch;
  --w-page:1180px;
  --w-wide:1440px;
  --gutter:clamp(16px, 4vw, 40px);

  /* the shelf's tallest tile (§1.6) */
  --shelf-h:360px;
}

/* Dark is not an inversion (§3.4). Redefined twice so the system default and an
   explicit toggle both win, and never as the only definition of a colour. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --brand-accent:#2AC0A2;
    --brand-deep:#49D5B6;
    --brand-tint:#0C201B;
    --accent-ink:#05130E;
    --surface-page:#0C1210;
    --surface-raised:#141C19;
    --surface-sunken:#080D0B;
    --surface-inverse:#F0F5F3;
    --ink-strong:#F0F5F3;
    --ink:#DAE2DF;
    --ink-quiet:#A1AEAA;
    --ink-faint:#899692;
    --ink-inverse:#101614;
    --line-hairline:#1C2623;
    --line:#2A3632;
    --line-strong:#65726E;
    --state-good:#4FB37A;
    --state-good-quiet:#14251A;
    --state-warn:#D6A429;
    --state-warn-quiet:#271F0F;
    --state-bad:#F0705C;
    --state-bad-quiet:#2D1B18;
    --price-ink:#F0F5F3;
    --price-was-ink:#899692;
    --sale-flag-bg:#F36F52;
    --sale-flag-ink:#180805;
    --stock-low-ink:#D6A429;
    --stock-out-ink:#A1AEAA;
    --ship-free-ink:#2AC0A2;
    --pickup-ink:#4FB37A;
  }
}
:root[data-theme="dark"]{
  --brand-accent:#2AC0A2;
  --brand-deep:#49D5B6;
  --brand-tint:#0C201B;
  --accent-ink:#05130E;
  --surface-page:#0C1210;
  --surface-raised:#141C19;
  --surface-sunken:#080D0B;
  --surface-inverse:#F0F5F3;
  --ink-strong:#F0F5F3;
  --ink:#DAE2DF;
  --ink-quiet:#A1AEAA;
  --ink-faint:#899692;
  --ink-inverse:#101614;
  --line-hairline:#1C2623;
  --line:#2A3632;
  --line-strong:#65726E;
  --state-good:#4FB37A;
  --state-good-quiet:#14251A;
  --state-warn:#D6A429;
  --state-warn-quiet:#271F0F;
  --state-bad:#F0705C;
  --state-bad-quiet:#2D1B18;
  --price-ink:#F0F5F3;
  --price-was-ink:#899692;
  --sale-flag-bg:#F36F52;
  --sale-flag-ink:#180805;
  --stock-low-ink:#D6A429;
  --stock-out-ink:#A1AEAA;
  --ship-free-ink:#2AC0A2;
  --pickup-ink:#4FB37A;
}

/* --------------------------------------------------------------------------
   1b · Collection worlds. A store may carry two brands that share a checkout but
   not a look. Each world below is a complete palette derived from its own accent
   and gated on the same WCAG table as the store palette (theme.js §3.7); the
   blocks are generated, so there is no hand-written hex here either. Put
   data-world="<collection slug>" on <body> for a whole page, or on a section.
   -------------------------------------------------------------------------- */
/* No collection worlds declared (theme.worlds is empty). */

/* --------------------------------------------------------------------------
   2 · Reset and base
   -------------------------------------------------------------------------- */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scrollbar-gutter:stable; }
body{
  margin:0;
  background:var(--surface-page);
  color:var(--ink);
  font-family:var(--font-text);
  font-size:var(--fs-base);
  font-weight:400;
  line-height:1.55;
  font-synthesis-weight:none;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg,video{ display:block; max-width:100%; }
img{ height:auto; }
button,input,select,textarea{ font:inherit; color:inherit; }
ul,ol{ margin:0; padding:0; list-style:none; }
p{ margin:0 0 var(--sp-4); max-width:68ch; }
p:last-child{ margin-bottom:0; }
a{ color:var(--brand-accent); text-underline-offset:.18em; text-decoration-thickness:from-font; }
a:hover{ color:var(--brand-deep); }
hr{ border:0; border-top:1px solid var(--line-hairline); margin:var(--sp-6) 0; }

/* Focus is a contract, not a decoration (§5.4). outline:none without a
   replacement is a review-blocking error. */
:focus-visible{
  outline:2px solid var(--brand-accent);
  outline-offset:2px;
  border-radius:inherit;
  box-shadow:0 0 0 4px var(--surface-page);
}
:focus:not(:focus-visible){ outline:none; }

.sr-only{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0;
}
.skip{
  position:absolute; left:var(--sp-4); top:var(--sp-2); z-index:80;
  transform:translateY(-160%);
  background:var(--surface-raised); color:var(--ink-strong);
  border:1px solid var(--line-strong); border-radius:var(--r-2);
  padding:var(--sp-3) var(--sp-4); font-weight:600; text-decoration:none;
  transition:transform var(--dur-state) var(--ease-in);
}
.skip:focus{ transform:none; }
.sprite{ position:absolute; width:0; height:0; overflow:hidden; }
[hidden]{ display:none !important; }

/* --------------------------------------------------------------------------
   3 · Type (§2.2)
   -------------------------------------------------------------------------- */
h1,h2,h3,h4{
  font-family:var(--font-display);
  font-weight:500;
  font-stretch:var(--font-display-stretch);
  color:var(--ink-strong);
  margin:0;
  text-wrap:balance;
}
h1{ font-size:var(--fs-1); line-height:1.08; letter-spacing:-.015em; }
h2{ font-size:var(--fs-2); line-height:1.14; letter-spacing:-.012em; }
h3{ font-size:var(--fs-3); line-height:1.22; letter-spacing:0; }
h4{ font-size:var(--fs-4); line-height:1.3; letter-spacing:0; }
.display-1{ font-size:var(--fs-display-1); line-height:1.02; letter-spacing:-.018em; }
.lead{ font-size:var(--fs-lead); line-height:1.5; color:var(--ink); }
.fine{ font-size:var(--fs-fine); color:var(--ink-quiet); }
.quiet{ color:var(--ink-quiet); }

.mono{
  font-family:var(--font-mono);
  font-weight:500;
  letter-spacing:.02em;
  font-variant-numeric:tabular-nums lining-nums;
}
.micro{
  font-family:var(--font-mono);
  font-size:var(--fs-micro);
  font-weight:500;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--ink-quiet);
}

/* Every money figure in the storefront. Tabular so a right-aligned column
   never jitters when a quantity changes (§2.3). */
.price{
  font-family:var(--font-mono);
  font-variant-numeric:tabular-nums lining-nums;
  font-weight:500;
  color:var(--price-ink);
}
.price s{ color:var(--price-was-ink); text-decoration-thickness:1px; margin-right:var(--sp-2); }
.price--lg{ font-size:var(--fs-4); }
/* A product with no price yet. Reads as a label, not as a number that failed to load:
   normal weight, quiet ink, and the tabular-figure treatment removed. */
.price--quoted{
  font-family:var(--font-text);
  font-variant-numeric:normal;
  font-weight:500;
  color:var(--ink-quiet);
  letter-spacing:0;
}
.sale-flag{
  display:inline-block;
  background:var(--sale-flag-bg); color:var(--sale-flag-ink);
  font-family:var(--font-mono); font-size:var(--fs-micro); font-weight:500;
  letter-spacing:.06em; text-transform:uppercase;
  padding:2px var(--sp-2); border-radius:var(--r-1);
  font-variant-numeric:tabular-nums lining-nums;
}
.stock-low{ color:var(--stock-low-ink); font-size:var(--fs-fine); }
.stock-out{ color:var(--stock-out-ink); font-size:var(--fs-fine); }
.ship-free{ color:var(--ship-free-ink); }
.pickup{ color:var(--pickup-ink); }

/* --------------------------------------------------------------------------
   4 · The shell (§1.3) — a named 12-column grid whose content column sits right
   of a persistent rail. Not centred below --w-wide; the consistent left edge
   that is not the text edge is what stops a page reading as generated.
   -------------------------------------------------------------------------- */
.shell{
  display:grid;
  grid-template-columns:
    [bleed-start] var(--gutter)
    [rail-start main-start] repeat(10, minmax(0,1fr))
    [main-end] var(--gutter) [bleed-end];
  column-gap:var(--sp-5);
  max-width:var(--w-wide);
  margin-inline:0 auto;
}
.shell > :where(*){ grid-column:main-start / main-end; min-width:0; }
/* :where() keeps the default at zero specificity so the bleed and rail helpers
   below win on source order rather than on an escalating selector. */
@media (min-width:1024px){
  .shell{
    grid-template-columns:
      [bleed-start] var(--gutter)
      [rail-start] minmax(0,1fr)
      [main-start] repeat(10, minmax(0,1fr))
      [main-end] var(--gutter) [bleed-end];
  }
}

/* Opt-in bleeds. .bleed-r runs from the content column past the page gutter;
   its scroller then clips at the viewport edge, which is the cut-off effect. */
.bleed-r{ grid-column:main-start / bleed-end; }
.bleed-full{ grid-column:bleed-start / bleed-end; }
.read{ max-width:var(--w-read); }

/* Section rhythm is variable on purpose — a page uses at least two densities. */
.sec{ padding-block:var(--sp-9); }
.sec--tight{ padding-block:var(--sp-7); }
.sec--normal{ padding-block:var(--sp-9); }
.sec--air{ padding-block:var(--sp-11); }
@media (max-width:719px){
  .sec--air{ padding-block:var(--sp-9); }
  .sec--normal{ padding-block:var(--sp-7); }
  .sec--tight{ padding-block:var(--sp-6); }
}

/* The left rail marker: a hairline and a mono index, sticky through the section.
   Below lg it collapses to a hairline above the heading. */
.sec__mark{
  grid-column:main-start / main-end;
  display:flex; align-items:center; gap:var(--sp-3);
  font-family:var(--font-mono); font-size:var(--fs-micro); font-weight:500;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-quiet);
  margin-bottom:var(--sp-4);
}
.sec__mark::before{
  content:""; flex:0 0 var(--sp-7); height:1px; background:var(--line);
}
@media (min-width:1024px){
  .sec__mark{
    grid-column:rail-start / main-start;
    align-self:start;
    position:sticky; top:calc(var(--sp-9) + var(--sp-4));
    margin-bottom:0; padding-right:var(--sp-4);
    flex-direction:column; align-items:flex-start; gap:var(--sp-2);
  }
  .sec__mark::before{ flex:none; width:var(--sp-6); }
}
.sec__head{ margin-bottom:var(--sp-6); }
.sec__head p{ color:var(--ink-quiet); margin-top:var(--sp-3); }

/* --------------------------------------------------------------------------
   5 · Nav (§1.5 block 1) — never glass on the storefront.
   -------------------------------------------------------------------------- */
.nav{
  position:sticky; top:0; z-index:60;
  background:var(--surface-page);
  border-bottom:1px solid transparent;
  transition:border-color var(--dur-state) var(--ease-in);
}
.nav[data-scrolled="true"]{ border-bottom-color:var(--line-hairline); }
.nav__in{
  display:grid;
  grid-template-columns:auto 1fr auto;
  align-items:center;
  gap:var(--sp-5);
  padding-block:var(--sp-3);
}
.nav__mark{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  font-family:var(--font-display); font-weight:500; font-stretch:var(--font-display-stretch);
  font-size:var(--fs-lead); letter-spacing:-.01em;
  color:var(--ink-strong); text-decoration:none;
}
.nav__mark img{ height:26px; width:auto; }
.nav__links{ display:none; gap:var(--sp-5); }
@media (min-width:720px){ .nav__links{ display:flex; } }
.nav__links a{
  color:var(--ink); text-decoration:none; font-size:var(--fs-base);
  padding-block:var(--sp-2);
  border-bottom:2px solid transparent;
  transition:border-color var(--dur-state) var(--ease-in), color var(--dur-state) var(--ease-in);
}
.nav__links a:hover,
.nav__links a[aria-current="page"]{ color:var(--ink-strong); border-bottom-color:var(--brand-accent); }
.nav__tools{ display:flex; align-items:center; gap:var(--sp-1); }
.iconbtn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-width:44px; min-height:44px; padding:0 var(--sp-2);
  background:none; border:1px solid transparent; border-radius:var(--r-2);
  color:var(--ink-strong); cursor:pointer; text-decoration:none;
  transition:background-color var(--dur-state) var(--ease-in);
}
.iconbtn:hover{ background:var(--surface-sunken); }
.iconbtn svg{ width:22px; height:22px; }
.cart-count{
  font-family:var(--font-mono); font-size:var(--fs-fine); font-weight:500;
  font-variant-numeric:tabular-nums lining-nums;
  min-width:1.5em; text-align:center;
  transition:transform var(--dur-state) var(--ease-in);
}
.cart-count[data-bump="true"]{ transform:scale(1.12); }

/* Search sits in the nav as a real form so it works with JavaScript off. */
.nav__search{ display:none; }
@media (min-width:1024px){
  .nav__search{ display:flex; align-items:center; }
  .nav__search input{ width:16ch; }
  .nav__search input:focus{ width:24ch; }
}

/* --------------------------------------------------------------------------
   6 · counter (§1.5 block 2) — full-bleed context photograph, type in the left
   third, bottom-aligned. No eyebrow, no subhead paragraph.
   -------------------------------------------------------------------------- */
.counter{ position:relative; isolation:isolate; }
.counter__frame{
  position:relative;
  aspect-ratio:4/5;
  background:var(--surface-sunken);
  overflow:hidden;
  border-radius:var(--r-0);
}
@media (min-width:720px){ .counter__frame{ aspect-ratio:16/9; } }
.counter__frame img{ width:100%; height:100%; object-fit:cover; }
.counter__frame::after{
  content:""; position:absolute; inset:0; background:var(--scrim); pointer-events:none;
}
.counter__copy{
  position:absolute; z-index:1;
  left:var(--gutter); right:var(--gutter); bottom:var(--sp-6);
  color:var(--ink-inverse);
}
@media (min-width:720px){
  .counter__copy{ left:var(--sp-8); right:auto; bottom:var(--sp-8); width:min(46ch,42%); }
}
.counter__copy h1{ color:var(--ink-inverse); margin-bottom:var(--sp-5); }

/* --------------------------------------------------------------------------
   7 · shelf (§1.6) — the signature block. Products rest on one hairline
   baseline, scaled by real package height against the tallest SKU in the row,
   inside a strip that scrolls horizontally past the right edge. Tiles are not
   uniform, and one tile breaks the baseline while another breaks the rhythm.
   -------------------------------------------------------------------------- */
.shelf{
  display:flex;
  align-items:flex-end;
  gap:0;                       /* stages touch so the baseline hairline is continuous */
  overflow-x:auto;
  overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  padding-bottom:var(--sp-2);
  -webkit-overflow-scrolling:touch;
}
@media (max-width:719px){ .shelf{ --shelf-h:min(360px, 240px); } }
.shelf-item{
  flex:0 0 auto;
  width:clamp(150px, 42vw, 210px);
  scroll-snap-align:start;
}
.shelf-item__stage{
  display:flex; align-items:flex-end; justify-content:center;
  height:var(--tile-h, var(--shelf-h));
  padding:0 var(--sp-3);
  background:var(--surface-sunken);
  border-bottom:1px solid var(--line);
  border-radius:var(--r-0);
}
.shelf-item__stage img{
  width:100%; height:100%;
  object-fit:contain;             /* the shelf's whole point is true relative height */
  object-position:bottom center;
  border-radius:var(--r-0);
}
.shelf-item__meta{
  padding:var(--sp-3) var(--sp-3) 0;
  display:flex; flex-direction:column; gap:var(--sp-1);
  min-height:5.2em;
}
.shelf-item__name{
  font-size:var(--fs-fine); color:var(--ink-strong); text-decoration:none;
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.shelf-item__name:hover{ text-decoration:underline; }
.shelf-item__meta .price{ font-size:var(--fs-fine); }

/* The feature tile: double width, pulled up off the baseline, copy set in the
   negative space beside the packshot rather than below it. */
.shelf-item--feature{ width:clamp(280px, 76vw, 440px); margin-bottom:var(--sp-6); }
.shelf-item--feature .shelf-item__stage{
  display:grid;
  grid-template-columns:minmax(0,7fr) minmax(0,8fr);
  align-items:end;
  gap:var(--sp-4);
  border-bottom:0;              /* it breaks the baseline — that is the point */
  padding:var(--sp-4) var(--sp-4) 0;
}
.shelf-item--feature .shelf-item__copy{
  padding-bottom:var(--sp-5);
  display:flex; flex-direction:column; gap:var(--sp-2); align-items:flex-start;
}
.shelf-item--feature .shelf-item__copy h3{ font-size:var(--fs-4); }
.shelf-item--feature .shelf-item__copy p{ font-size:var(--fs-fine); color:var(--ink-quiet); }
.shelf-item--feature .shelf-item__meta{ display:none; }

/* --------------------------------------------------------------------------
   8 · Product grid and tile (§1.7, §4.3). The tile is a container component so
   it drops into the grid, the rail and the drawer unchanged.
   -------------------------------------------------------------------------- */
.grid{
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:var(--sp-5);
}
@media (min-width:1024px){ .grid{ grid-template-columns:repeat(3, minmax(0,1fr)); } }
@media (min-width:1280px){ .grid{ grid-template-columns:repeat(4, minmax(0,1fr)); } }

.tile{ position:relative; container-type:inline-size; }
.tile__frame{
  position:relative;
  aspect-ratio:4/5;
  background:var(--surface-sunken);
  border-radius:var(--r-0);
  overflow:hidden;
}
.tile__frame img{
  width:100%; height:100%; object-fit:cover; border-radius:var(--r-0);
}
/* Hover crossfade to the scale shot, pointer devices only, never on touch. */
.tile__alt{ position:absolute; inset:0; opacity:0; transition:opacity var(--dur-elem) var(--ease-in); }
@media (pointer:fine){ .tile:hover .tile__alt{ opacity:1; } }
.tile__body{
  display:flex; flex-direction:column; gap:var(--sp-1);
  padding-top:var(--sp-3);
}
.tile__name{
  font-size:var(--fs-lead); font-weight:500; line-height:1.3;
  color:var(--ink-strong); margin:0;
}
.tile__name a{ color:inherit; text-decoration:none; }
.tile__name a:hover{ text-decoration:underline; }
/* Exactly one anchor per tile; the overlay is for pointer users only, so a
   screen reader announces the product name and not a 200-character link. */
.tile__name a::after{ content:""; position:absolute; inset:0; }
.tile__pricerow{
  display:flex; align-items:baseline; gap:var(--sp-2); flex-wrap:wrap;
  padding-top:var(--sp-2); border-top:1px solid var(--line-hairline);
  font-size:var(--fs-base);
}
.tile__sub{ font-size:var(--fs-fine); color:var(--ink-quiet); }

/* Every seventh tile spans two columns and uses the lifestyle frame, so the
   card wall breaks once per screenful without a bento layout. */
.grid > .tile:nth-child(7n){ grid-column:span 2; }
.grid > .tile:nth-child(7n) .tile__frame{ aspect-ratio:3/2; }
.grid > .tile:nth-child(7n) .tile__body{
  position:absolute; left:0; right:0; bottom:0; z-index:1;
  padding:var(--sp-5); color:var(--ink-inverse);
}
.grid > .tile:nth-child(7n) .tile__frame::after{
  content:""; position:absolute; inset:0; background:var(--scrim); pointer-events:none;
}
.grid > .tile:nth-child(7n) .tile__name{ color:var(--ink-inverse); }
.grid > .tile:nth-child(7n) .tile__pricerow{ border-top-color:transparent; }
.grid > .tile:nth-child(7n) .price{ color:var(--ink-inverse); }

/* Sold out keeps full colour: strikethrough plus the words, never dimming alone. */
.tile--out .tile__pricerow .price{ color:var(--stock-out-ink); }

/* --------------------------------------------------------------------------
   9 · spread (§1.5 block 5) — 5-column editorial split, image bleeding off the
   left edge, text offset down so the two do not baseline-align.
   -------------------------------------------------------------------------- */
.spread{
  grid-column:bleed-start / main-end;
  display:grid;
  grid-template-columns:minmax(0,1fr);
  gap:var(--sp-6);
  align-items:start;
}
@media (min-width:900px){
  .spread{ grid-template-columns:repeat(5, minmax(0,1fr)); column-gap:var(--sp-7); }
  .spread__media{ grid-column:1 / 4; }
  .spread__body{ grid-column:4 / 6; max-width:var(--w-read); margin-top:var(--sp-8); }
}
.spread__media img{
  width:100%; aspect-ratio:3/2; object-fit:cover; border-radius:var(--r-0);
  background:var(--surface-sunken);
}
.spread--mirror{ grid-column:main-start / bleed-end; }
@media (min-width:900px){
  .spread--mirror .spread__media{ grid-column:3 / 6; }
  .spread--mirror .spread__body{ grid-column:1 / 3; margin-top:var(--sp-8); }
}
.spread__body h2{ margin-bottom:var(--sp-4); }

/* --------------------------------------------------------------------------
   10 · spec (§1.5 block 6) — a real table. This is what replaces the three-up
   icon feature cards. Hairline rows, mono values, no icons, no cards.
   -------------------------------------------------------------------------- */
.tablewrap{ overflow-x:auto; }
.spec{
  width:100%; border-collapse:collapse; text-align:left;
  max-width:760px;
}
.spec caption{
  text-align:left; padding-bottom:var(--sp-4);
  font-family:var(--font-display); font-weight:500; font-size:var(--fs-3);
  color:var(--ink-strong); letter-spacing:0;
}
.spec th,.spec td{
  padding:var(--sp-3) var(--sp-4) var(--sp-3) 0;
  border-bottom:1px solid var(--line-hairline);
  vertical-align:top;
}
.spec th{ font-weight:500; color:var(--ink-quiet); width:38%; }
.spec td{
  font-family:var(--font-mono); font-variant-numeric:tabular-nums lining-nums;
  color:var(--ink-strong); letter-spacing:.02em;
}
.spec tr:last-child th,.spec tr:last-child td{ border-bottom:0; }

/* --------------------------------------------------------------------------
   11 · voice (§1.5 block 8) — one named review as a pull-quote. No cards, no
   avatars, no stars-out-of-five row. One per page maximum.
   -------------------------------------------------------------------------- */
.voice{ grid-column:main-start / main-end; }
.voice blockquote{
  margin:0;
  font-family:var(--font-display); font-weight:400; font-stretch:var(--font-display-stretch);
  font-size:var(--fs-4); line-height:1.4;
  color:var(--ink-strong);
  max-width:52ch;
  border-left:2px solid var(--brand-accent);
  padding-left:var(--sp-5);
}
.voice figcaption{
  margin-top:var(--sp-4); padding-left:var(--sp-5);
  font-size:var(--fs-fine); color:var(--ink-quiet);
}
.voice figcaption .mono{ color:var(--ink); }

/* --------------------------------------------------------------------------
   12 · rail (§1.5 block 9) — horizontal snap row of related SKUs, no arrows.
   -------------------------------------------------------------------------- */
.rail{
  display:flex; gap:var(--sp-5);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  padding-bottom:var(--sp-3);
}
.rail > .tile{ flex:0 0 clamp(180px, 46vw, 260px); scroll-snap-align:start; }

/* --------------------------------------------------------------------------
   13 · Controls, buttons, forms (§5.4). Every target is at least 44 x 44px
   with at least 24px between adjacent targets.
   -------------------------------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--sp-2);
  min-height:44px; padding:var(--sp-2) var(--sp-5);
  font-family:var(--font-text); font-size:var(--fs-base); font-weight:600; line-height:1.2;
  text-decoration:none; text-align:center;
  border:1px solid transparent; border-radius:var(--r-2);
  background:none; color:var(--ink-strong); cursor:pointer;
  transition:background-color var(--dur-state) var(--ease-in),
             border-color var(--dur-state) var(--ease-in),
             color var(--dur-state) var(--ease-in);
}
.btn--solid{ background:var(--brand-accent); color:var(--accent-ink); }
.btn--solid:hover{ background:var(--brand-deep); color:var(--accent-ink); }
.btn--line{ border-color:var(--line-strong); }
.btn--line:hover{ background:var(--surface-sunken); color:var(--ink-strong); }
.btn--wide{ width:100%; }
.btn--quiet{ min-height:36px; padding:var(--sp-1) var(--sp-3); font-weight:500; font-size:var(--fs-fine); }
.btn[disabled],.btn[aria-disabled="true"]{
  background:var(--surface-sunken); color:var(--ink-quiet);
  border-color:var(--line); cursor:not-allowed;
}
.btn svg{ width:20px; height:20px; }
.btn__check{ display:none; }
.btn[data-added="true"] .btn__check{ display:block; }
.btn[data-added="true"] .btn__label{ display:none; }

.field{ display:flex; flex-direction:column; gap:var(--sp-2); margin-bottom:var(--sp-4); }
.field label{ font-size:var(--fs-fine); font-weight:500; color:var(--ink-strong); }
input[type=text],input[type=email],input[type=search],input[type=number],input[type=tel],select,textarea{
  min-height:44px;
  padding:var(--sp-2) var(--sp-3);
  font-size:var(--fs-base);            /* 16px keeps iOS from zooming on focus */
  background:var(--surface-raised);
  color:var(--ink-strong);
  border:1px solid var(--line-strong);
  border-radius:var(--r-1);
}
textarea{ min-height:96px; resize:vertical; }
input[aria-invalid="true"],select[aria-invalid="true"],textarea[aria-invalid="true"]{
  border-color:var(--state-bad);
}
.err{ color:var(--state-bad); font-size:var(--fs-fine); }
.ok{ color:var(--state-good); font-size:var(--fs-fine); }

/* Variant chips — a real fieldset of radios, so arrow keys work natively.
   The selected chip carries a border AND a check, never a fill alone. */
.opt{ border:0; padding:0; margin:0 0 var(--sp-5); }
.opt legend{
  padding:0; margin-bottom:var(--sp-3);
  font-size:var(--fs-fine); font-weight:500; color:var(--ink-strong);
}
.opt legend .mono{ color:var(--ink-quiet); font-weight:400; }
.opt__chips{ display:flex; flex-wrap:wrap; gap:var(--sp-3); }
.chip{ position:relative; }
.chip input{
  position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer;
}
.chip span{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  min-height:44px; padding:var(--sp-2) var(--sp-4);
  border:1px solid var(--line-strong); border-radius:var(--r-1);
  background:var(--surface-raised); color:var(--ink-strong);
  font-size:var(--fs-base);
  transition:border-color var(--dur-state) var(--ease-in), background-color var(--dur-state) var(--ease-in);
}
.chip input:hover + span{ background:var(--surface-sunken); }
.chip input:checked + span{
  border-color:var(--brand-accent); border-width:2px;
  padding:calc(var(--sp-2) - 1px) calc(var(--sp-4) - 1px);
  background:var(--brand-tint);
}
.chip input:focus-visible + span{
  outline:2px solid var(--brand-accent); outline-offset:2px;
  box-shadow:0 0 0 4px var(--surface-page);
}
.chip__check{ display:none; width:16px; height:16px; color:var(--brand-accent); }
.chip input:checked + span .chip__check{ display:block; }
/* Unavailable combinations are disabled and keep their label — never removed. */
.chip input[aria-disabled="true"] + span,
.chip input:disabled + span{
  color:var(--ink-quiet); border-color:var(--line);
  border-style:dashed; background:var(--surface-page); cursor:not-allowed;
}
.chip__note{ font-size:var(--fs-micro); font-family:var(--font-mono); letter-spacing:.06em; text-transform:uppercase; }

/* Quantity stepper — two real buttons plus an <output>. --r-pill is used here
   and nowhere else. */
.qty{
  display:inline-flex; align-items:center;
  border:1px solid var(--line-strong); border-radius:var(--r-pill);
  background:var(--surface-raised);
}
.qty button{
  width:44px; height:44px;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:0; border-radius:var(--r-pill);
  color:var(--ink-strong); cursor:pointer;
}
.qty button:hover{ background:var(--surface-sunken); }
.qty button[disabled]{ color:var(--ink-faint); cursor:not-allowed; }
.qty button svg{ width:18px; height:18px; }
.qty output{
  min-width:3ch; text-align:center;
  font-family:var(--font-mono); font-weight:500;
  font-variant-numeric:tabular-nums lining-nums;
}

/* --------------------------------------------------------------------------
   14 · PDP (§4.4) — 7/5 split, frames stacked and scrolled on desktop, a snap
   strip with a mono counter on mobile, sticky buy panel.
   -------------------------------------------------------------------------- */
.pdp{ display:grid; gap:var(--sp-6); }
@media (min-width:720px){
  .pdp{ grid-template-columns:minmax(0,7fr) minmax(0,5fr); column-gap:var(--sp-7); align-items:start; }
}
.pdp__frames{
  display:flex; gap:var(--sp-4);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;
  margin-inline:calc(-1 * var(--gutter));
  padding-inline:var(--gutter);
}
.pdp__frame{ flex:0 0 86%; scroll-snap-align:center; }
.pdp__frame img{
  width:100%; aspect-ratio:4/5; object-fit:cover;
  background:var(--surface-sunken); border-radius:var(--r-0);
}
.pdp__frame--wide img{ aspect-ratio:3/2; }
.pdp__frame--square img{ aspect-ratio:1/1; }
.pdp__counter{
  margin-top:var(--sp-3);
  font-family:var(--font-mono); font-size:var(--fs-fine); font-weight:500;
  font-variant-numeric:tabular-nums lining-nums; color:var(--ink-quiet);
}
@media (min-width:720px){
  .pdp__frames{
    display:grid; grid-template-columns:minmax(0,1fr); gap:var(--sp-2);
    overflow:visible; margin-inline:0; padding-inline:0;
  }
  .pdp__frame{ flex:none; }
  .pdp__counter{ display:none; }
}
.pdp__panel{ display:flex; flex-direction:column; gap:var(--sp-4); }
@media (min-width:720px){
  .pdp__panel{ position:sticky; top:var(--sp-6); }
}
.pdp__panel h1{ font-size:var(--fs-2); line-height:1.14; letter-spacing:-.012em; }
.pdp__price{ font-size:var(--fs-4); }
.pdp__desc{ color:var(--ink); }
.pdp__buyrow{ display:flex; align-items:center; gap:var(--sp-5); flex-wrap:wrap; }
.pdp__buyrow .btn{ flex:1 1 220px; }
.pdp__terms{ font-size:var(--fs-fine); color:var(--ink-quiet); display:flex; flex-direction:column; gap:var(--sp-2); }
.pdp__terms span{ display:inline-flex; align-items:center; gap:var(--sp-2); }
.pdp__terms svg{ width:16px; height:16px; flex:none; }

/* Mobile sticky buy bar, shown once the inline button scrolls out of view. */
.buybar{
  position:fixed; left:0; right:0; bottom:0; z-index:55;
  display:flex; align-items:center; gap:var(--sp-4);
  padding:var(--sp-3) var(--gutter);
  padding-bottom:calc(var(--sp-3) + env(safe-area-inset-bottom));
  background:var(--surface-raised);
  border-top:1px solid var(--line-hairline);
  box-shadow:var(--el-2);
  transform:translateY(110%);
  transition:transform var(--dur-elem) var(--ease-in);
}
.buybar[data-show="true"]{ transform:none; }
.buybar .btn{ margin-left:auto; }
@media (min-width:720px){ .buybar{ display:none; } }

/* --------------------------------------------------------------------------
   15 · Collection filters — the sticky left rail is what makes the grid
   asymmetric rather than a centred card wall.
   -------------------------------------------------------------------------- */
.catrail{
  display:flex; gap:var(--sp-4); overflow-x:auto; padding-bottom:var(--sp-2);
  margin-bottom:var(--sp-5);
}
.catrail a{
  flex:none; text-decoration:none; color:var(--ink-quiet);
  font-family:var(--font-mono); font-size:var(--fs-micro); font-weight:500;
  letter-spacing:.06em; text-transform:uppercase;
  padding:var(--sp-2) 0; border-bottom:2px solid transparent;
}
.catrail a[aria-current="page"]{ color:var(--ink-strong); border-bottom-color:var(--brand-accent); }

.browse{ display:grid; gap:var(--sp-6); }
@media (min-width:1024px){
  .browse{ grid-template-columns:minmax(180px,1fr) minmax(0,4fr); column-gap:var(--sp-7); align-items:start; }
  .filters{ position:sticky; top:calc(var(--sp-8)); }
}
.filters h2{ font-size:var(--fs-4); margin-bottom:var(--sp-4); }
.filters fieldset{ border:0; padding:0; margin:0 0 var(--sp-5); }
.filters legend{ padding:0; margin-bottom:var(--sp-3); font-size:var(--fs-fine); font-weight:500; color:var(--ink-strong); }
.check{ display:flex; align-items:center; gap:var(--sp-3); min-height:32px; font-size:var(--fs-fine); }
.check input{ width:18px; height:18px; accent-color:var(--brand-accent); }
.check .mono{ margin-left:auto; color:var(--ink-quiet); font-size:var(--fs-micro); }
.browse__bar{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  flex-wrap:wrap; margin-bottom:var(--sp-5);
}
.browse__count{ font-family:var(--font-mono); font-size:var(--fs-fine); color:var(--ink-quiet); font-variant-numeric:tabular-nums lining-nums; }
.empty{ padding:var(--sp-8) 0; color:var(--ink-quiet); }

/* --------------------------------------------------------------------------
   16 · drawer (§1.5 block 10, §5.2) — cart. Slides from the right at 420px,
   --r-3 on the left corners only. Glass is permitted here and nowhere else.
   -------------------------------------------------------------------------- */
.drawer__backdrop{
  position:fixed; inset:0; z-index:70;
  background:var(--surface-inverse);
  opacity:0; visibility:hidden;
  backdrop-filter:blur(3px);
  transition:opacity var(--dur-overlay) var(--ease-in), visibility 0s linear var(--dur-overlay);
}
.drawer__backdrop[data-open="true"]{ opacity:.55; visibility:visible; transition-delay:0s; }
.drawer{
  position:fixed; top:0; right:0; bottom:0; z-index:71;
  width:min(420px, 100%);
  display:flex; flex-direction:column;
  background:var(--surface-raised);
  border-radius:var(--r-3) 0 0 var(--r-3);
  box-shadow:var(--el-3);
  transform:translateX(100%);
  visibility:hidden;
  transition:transform var(--dur-overlay) var(--ease-in), visibility 0s linear var(--dur-overlay);
}
.drawer[data-open="true"]{ transform:none; visibility:visible; transition-delay:0s; }
.drawer__head{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  padding:var(--sp-5); border-bottom:1px solid var(--line-hairline);
}
.drawer__head h2{ font-size:var(--fs-4); }
.drawer__body{ flex:1 1 auto; overflow-y:auto; padding:var(--sp-5); }
.drawer__foot{
  border-top:1px solid var(--line-hairline);
  padding:var(--sp-5);
  padding-bottom:calc(var(--sp-5) + env(safe-area-inset-bottom));
  display:flex; flex-direction:column; gap:var(--sp-4);
  background:var(--surface-raised);
}
.drawer__totals{ display:flex; flex-direction:column; gap:var(--sp-2); }
.drawer__row{ display:flex; align-items:baseline; justify-content:space-between; gap:var(--sp-4); font-size:var(--fs-fine); }
.drawer__row--total{ font-size:var(--fs-base); color:var(--ink-strong); font-weight:500; }
.drawer__row .price{ text-align:right; }

.line{
  display:grid; grid-template-columns:64px minmax(0,1fr) auto;
  gap:var(--sp-4); align-items:start;
  padding-bottom:var(--sp-5); margin-bottom:var(--sp-5);
  border-bottom:1px solid var(--line-hairline);
}
.line:last-child{ border-bottom:0; margin-bottom:0; padding-bottom:0; }
.line__frame{ aspect-ratio:4/5; background:var(--surface-sunken); border-radius:var(--r-0); overflow:hidden; }
.line__frame img{ width:100%; height:100%; object-fit:cover; }
.line__title{ font-size:var(--fs-fine); font-weight:500; color:var(--ink-strong); }
.line__title a{ color:inherit; text-decoration:none; }
.line__variant{ font-family:var(--font-mono); font-size:var(--fs-micro); letter-spacing:.02em; color:var(--ink-quiet); }
.line__controls{ display:flex; align-items:center; gap:var(--sp-3); margin-top:var(--sp-3); flex-wrap:wrap; }
.line__price{ text-align:right; font-size:var(--fs-fine); }
.line__props{ font-size:var(--fs-micro); color:var(--ink-quiet); }

/* Free-shipping progress: a real number, not a percentage bar alone. */
.freeship{ font-size:var(--fs-fine); color:var(--ship-free-ink); }
.freeship__track{ height:3px; background:var(--surface-sunken); border-radius:var(--r-1); margin-top:var(--sp-2); overflow:hidden; }
.freeship__fill{ height:100%; background:var(--brand-accent); }

/* The FLIP clone flown from the product image into the new cart line (§5.2).
   It is a decoration on top of UI that is already correct underneath. */
.flip-clone{
  position:fixed; z-index:75; pointer-events:none;
  object-fit:cover; border-radius:var(--r-0);
  will-change:transform, opacity;
}

/* --------------------------------------------------------------------------
   17 · foot (§1.5 block 14) — four columns at md, asymmetric widths. Column 1
   is the real postal address and phone.
   -------------------------------------------------------------------------- */
.foot{
  background:var(--surface-inverse);
  color:var(--ink-inverse);
  margin-top:var(--sp-9);
}
.foot a{ color:var(--ink-inverse); text-decoration:none; }
.foot a:hover{ color:var(--ink-inverse); text-decoration:underline; }
.foot__in{ padding-block:var(--sp-8) var(--sp-6); display:grid; gap:var(--sp-6); }
@media (min-width:720px){
  .foot__in{ grid-template-columns:3fr 2fr 2fr 3fr; column-gap:var(--sp-6); }
}
.foot h2{ color:var(--ink-inverse); font-size:var(--fs-lead); margin-bottom:var(--sp-4); }
.foot ul{ display:flex; flex-direction:column; gap:var(--sp-2); font-size:var(--fs-fine); }
.foot address{ font-style:normal; font-size:var(--fs-fine); line-height:1.7; }
.foot__legal{
  border-top:1px solid var(--line-strong);
  padding-block:var(--sp-4) var(--sp-7);
  display:flex; flex-wrap:wrap; gap:var(--sp-3) var(--sp-5);
  align-items:center; justify-content:space-between;
  font-size:var(--fs-fine);
}
.foot__legal ul{ flex-direction:row; flex-wrap:wrap; gap:var(--sp-5); }
.foot__sub{ display:flex; gap:var(--sp-3); flex-wrap:wrap; align-items:flex-end; }
.foot__sub .field{ margin-bottom:0; flex:1 1 180px; }
.foot__sub input{ background:var(--surface-inverse); color:var(--ink-inverse); border-color:var(--line-strong); width:100%; }
.foot__sub label{ color:var(--ink-inverse); }
.foot .btn--line{ border-color:var(--line-strong); color:var(--ink-inverse); }
.foot .btn--line:hover{ background:var(--surface-inverse); color:var(--ink-inverse); border-color:var(--ink-inverse); }
.foot :focus-visible{ box-shadow:0 0 0 4px var(--surface-inverse); }

/* --------------------------------------------------------------------------
   18 · Flat placeholders while data is in flight. A block of --surface-sunken,
   never a shimmer.
   -------------------------------------------------------------------------- */
.skel{ background:var(--surface-sunken); border-radius:var(--r-0); }
.skel--tile{ aspect-ratio:4/5; }

/* --------------------------------------------------------------------------
   18b · Photography pending. Not a skeleton (nothing is loading) and not a stock
   photo of somebody else's jar. A stated absence: the frame keeps its aspect
   ratio so the grid does not reflow when the real photograph arrives, and it says
   why it is empty. Two hairline rules cross the frame so it reads as a reserved
   plate rather than a broken image.
   -------------------------------------------------------------------------- */
.pending{
  position:relative;
  display:grid; place-items:center;
  aspect-ratio:4/5;
  background:var(--surface-sunken);
  border:1px solid var(--line-hairline);
  border-radius:var(--r-0);
  overflow:hidden;
  padding:var(--sp-5);
}
.pending::before,
.pending::after{
  content:""; position:absolute; background:var(--line-hairline);
}
.pending::before{ left:0; right:0; top:50%; height:1px; }
.pending::after{ top:0; bottom:0; left:50%; width:1px; }
.pending__label{
  position:relative;
  font-family:var(--font-mono);
  font-size:var(--fs-micro);
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--ink-quiet);
  background:var(--surface-sunken);
  padding:var(--sp-2) var(--sp-3);
  text-align:center;
  max-width:22ch;
  line-height:1.5;
}
.pending--wide{ aspect-ratio:3/2; }

/* --------------------------------------------------------------------------
   19 · Reduced motion (§5.3). JavaScript honours this too: no FLIP flight, no
   slide, no smooth scroll.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}

@media print{
  .nav,.drawer,.drawer__backdrop,.buybar,.foot__sub,.skip{ display:none !important; }
  .shell{ max-width:none; }
}

/* --------------------------------------------------------------------------
   20 · The money pages (§4.5–§4.7): cart, checkout, receipt, order status,
   account. They share one layout idea and it is deliberately NOT the storefront's.

   A shop page invites you to wander; a checkout page has one job and every pixel
   that is not that job is a distraction with a measured cost. So: no bleeds, no
   editorial offsets, no hover crossfades, a narrower column, denser rhythm, and
   the summary pinned where the eye already is. The one place a flourish survives
   is the receipt, because that page is a thank-you and has nothing left to do.

   Mobile-first throughout. Every grid below is a single column until it has
   room, and the summary becomes a <details> at the top of the page rather than a
   thing you scroll past the form to find.
   -------------------------------------------------------------------------- */

.money{ padding-block:var(--sp-7) var(--sp-9); }
.money__head{ margin-bottom:var(--sp-6); }
.money__head h1{ font-size:var(--fs-2); line-height:1.14; letter-spacing:-.012em; }
.money__head p{ color:var(--ink-quiet); margin-top:var(--sp-2); }

/* 7/5 on desktop. The form is the wider column because it is the one being
   filled in; the summary is a reference, not a destination. */
.money__split{ display:grid; gap:var(--sp-6); align-items:start; }
@media (min-width:900px){
  .money__split{ grid-template-columns:minmax(0,7fr) minmax(0,5fr); column-gap:var(--sp-8); }
  .money__split > .summary{ position:sticky; top:var(--sp-6); }
}

/* --- the summary panel ---------------------------------------------------- */
.summary{
  background:var(--surface-sunken);
  border:1px solid var(--line-hairline);
  border-radius:var(--r-2);
  padding:var(--sp-5);
}
.summary > h2{ font-size:var(--fs-4); margin-bottom:var(--sp-4); }
.summary__lines{ margin-bottom:var(--sp-4); }
.summary__rows{ display:flex; flex-direction:column; gap:var(--sp-2); }
.summary__row{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:var(--sp-4); font-size:var(--fs-fine); color:var(--ink);
}
.summary__row dt{ color:var(--ink-quiet); }
.summary__row dd{ margin:0; text-align:right; }
.summary__row--total{
  font-size:var(--fs-base); font-weight:500; color:var(--ink-strong);
  border-top:1px solid var(--line); padding-top:var(--sp-3); margin-top:var(--sp-2);
}
.summary__note{ font-size:var(--fs-micro); color:var(--ink-quiet); margin-top:var(--sp-3); }

/* On a phone the summary collapses. The total stays in the closed state, because
   "Order summary" with the number hidden is the pattern every checkout study
   flags: people open it only to check the figure they were not shown. */
.summary--fold{ padding:0; margin-bottom:var(--sp-6); }
.summary--fold > summary{
  display:flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  padding:var(--sp-4) var(--sp-5); min-height:52px; cursor:pointer;
  font-weight:500; color:var(--ink-strong); list-style:none;
}
.summary--fold > summary::-webkit-details-marker{ display:none; }
.summary--fold > summary .price{ margin-left:auto; }
.summary--fold > summary svg{
  width:18px; height:18px; flex:none; color:var(--ink-quiet);
  transform:rotate(90deg); transition:transform var(--dur-state) var(--ease-in);
}
.summary--fold[open] > summary svg{ transform:rotate(-90deg); }
.summary--fold__body{ padding:0 var(--sp-5) var(--sp-5); border-top:1px solid var(--line-hairline); padding-top:var(--sp-4); }
@media (min-width:900px){ .summary--fold{ display:none; } }
.summary--rail{ display:none; }
@media (min-width:900px){ .summary--rail{ display:block; } }

/* --- the cart table ------------------------------------------------------- */
/* A real <table> on desktop, because a cart IS tabular: item, unit, quantity,
   line total. It becomes stacked blocks under 720px rather than a table that
   scrolls sideways, since a horizontally scrolling cart is how people fail to
   notice the remove button. */
.cartlist{ width:100%; border-collapse:collapse; }
.cartlist th{
  text-align:left; font-size:var(--fs-micro); font-weight:500;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-quiet);
  padding-bottom:var(--sp-3); border-bottom:1px solid var(--line);
}
.cartlist th:last-child,.cartlist td:last-child{ text-align:right; }
.cartlist td{ padding:var(--sp-5) 0; border-bottom:1px solid var(--line-hairline); vertical-align:top; }
.cartline{ display:grid; grid-template-columns:72px minmax(0,1fr); gap:var(--sp-4); }
.cartline__frame{
  width:72px; aspect-ratio:4/5; background:var(--surface-sunken);
  border-radius:var(--r-0); overflow:hidden;
}
.cartline__frame img{ width:100%; height:100%; object-fit:cover; }
.cartline__name{ font-weight:500; color:var(--ink-strong); }
.cartline__name a{ color:inherit; text-decoration:none; }
.cartline__name a:hover{ text-decoration:underline; }
.cartline__variant{
  font-family:var(--font-mono); font-size:var(--fs-micro);
  letter-spacing:.02em; color:var(--ink-quiet); margin-top:var(--sp-1);
}
.cartline__props{ font-size:var(--fs-micro); color:var(--ink-quiet); margin-top:var(--sp-2); }
.cartline__actions{ display:flex; align-items:center; gap:var(--sp-4); margin-top:var(--sp-3); flex-wrap:wrap; }
.cartline__remove{
  background:none; border:0; padding:0; cursor:pointer;
  font-size:var(--fs-fine); color:var(--ink-quiet); text-decoration:underline;
  text-underline-offset:.18em; min-height:44px;
}
.cartline__remove:hover{ color:var(--state-bad); }
.cartline__stock{ font-size:var(--fs-fine); }

@media (max-width:719px){
  .cartlist,.cartlist tbody,.cartlist tr,.cartlist td{ display:block; width:100%; }
  .cartlist thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }
  .cartlist td{ padding:var(--sp-5) 0 0; border:0; }
  .cartlist tr{ border-bottom:1px solid var(--line-hairline); padding-bottom:var(--sp-5); }
  .cartlist td[data-col="qty"],.cartlist td[data-col="total"]{ padding-top:var(--sp-3); }
  .cartlist td[data-col="total"]{ text-align:left; }
  .cartlist td[data-col="total"]::before{
    content:attr(data-label) " "; color:var(--ink-quiet); font-size:var(--fs-fine);
  }
}

/* --- the promo row -------------------------------------------------------- */
.promo{ display:flex; gap:var(--sp-3); align-items:flex-end; flex-wrap:wrap; margin-top:var(--sp-5); }
.promo .field{ margin-bottom:0; flex:1 1 200px; }
.promo input{ width:100%; text-transform:uppercase; }
.promo__applied{
  display:inline-flex; align-items:center; gap:var(--sp-2);
  font-size:var(--fs-fine); color:var(--ship-free-ink);
}
.promo__applied button{
  background:none; border:0; padding:0; cursor:pointer; color:var(--ink-quiet);
  text-decoration:underline; text-underline-offset:.18em;
}

/* --- checkout steps ------------------------------------------------------- */
/* Numbered because the number is real information here (which of four am I on),
   which is the one case the eyebrow rule allows. */
.steps{ display:flex; flex-direction:column; gap:var(--sp-6); }
.step{
  border:1px solid var(--line-hairline); border-radius:var(--r-2);
  background:var(--surface-raised); padding:var(--sp-5);
}
.step[data-state="done"]{ background:var(--surface-page); }
.step[data-state="locked"]{ opacity:.55; }
.step__head{ display:flex; align-items:baseline; gap:var(--sp-3); margin-bottom:var(--sp-4); }
.step__n{
  font-family:var(--font-mono); font-size:var(--fs-fine); font-weight:500;
  font-variant-numeric:tabular-nums lining-nums; color:var(--ink-quiet); flex:none;
}
.step__head h2{ font-size:var(--fs-lead); font-weight:500; color:var(--ink-strong); flex:1 1 auto; }
.step__edit{
  background:none; border:0; padding:0; cursor:pointer; min-height:44px;
  font-size:var(--fs-fine); color:var(--brand-accent);
  text-decoration:underline; text-underline-offset:.18em;
}
.step__done{ font-size:var(--fs-fine); color:var(--ink-quiet); }
.step__done strong{ color:var(--ink-strong); font-weight:500; }
.step__body > :last-child{ margin-bottom:0; }
.grid2{ display:grid; gap:0 var(--sp-4); }
@media (min-width:560px){ .grid2{ grid-template-columns:1fr 1fr; } .grid2 .span2{ grid-column:1 / -1; } }

/* Delivery-method and shipping-rate choices are radios that look like rows, not
   like chips: they carry a price on the right, and a price needs a column. */
.choice{ display:flex; flex-direction:column; gap:var(--sp-3); margin:0 0 var(--sp-4); border:0; padding:0; }
.choice legend{ padding:0; margin-bottom:var(--sp-3); font-size:var(--fs-fine); font-weight:500; color:var(--ink-strong); }
.choice__row{ position:relative; display:block; }
.choice__row input{ position:absolute; opacity:0; width:100%; height:100%; margin:0; cursor:pointer; }
.choice__row > span{
  display:grid; grid-template-columns:20px minmax(0,1fr) auto; align-items:center;
  gap:var(--sp-3); min-height:56px; padding:var(--sp-3) var(--sp-4);
  border:1px solid var(--line-strong); border-radius:var(--r-1);
  background:var(--surface-raised); color:var(--ink-strong);
}
.choice__row input:checked + span{
  border-color:var(--brand-accent); border-width:2px;
  padding:calc(var(--sp-3) - 1px) calc(var(--sp-4) - 1px);
  background:var(--brand-tint);
}
.choice__row input:focus-visible + span{
  outline:2px solid var(--brand-accent); outline-offset:2px;
  box-shadow:0 0 0 4px var(--surface-page);
}
.choice__row input:disabled + span{ color:var(--ink-quiet); border-style:dashed; cursor:not-allowed; }
.choice__dot{
  width:18px; height:18px; border-radius:50%;
  border:1px solid var(--line-strong); background:var(--surface-page);
}
.choice__row input:checked + span .choice__dot{
  border:5px solid var(--brand-accent); background:var(--surface-page);
}
.choice__label{ min-width:0; }
.choice__label b{ font-weight:500; display:block; }
.choice__label small{ display:block; font-size:var(--fs-fine); color:var(--ink-quiet); }
.choice__price{ font-family:var(--font-mono); font-variant-numeric:tabular-nums lining-nums; white-space:nowrap; }

/* The Stripe Payment Element mounts into this. It is an iframe from Stripe and
   that is the point: the card number never touches this origin, which is what
   keeps the merchant inside PCI SAQ-A. */
.paybox{ min-height:220px; }
.paybox--busy{ opacity:.6; pointer-events:none; }

.paynow{ margin-top:var(--sp-5); }
.paynow .btn{ width:100%; }
.trustrow{
  display:flex; align-items:center; gap:var(--sp-2);
  margin-top:var(--sp-4); font-size:var(--fs-fine); color:var(--ink-quiet);
}
.trustrow svg{ width:16px; height:16px; flex:none; }

/* An error that costs money gets a box, not a line of red text under a field. */
.notice{
  display:flex; gap:var(--sp-3); align-items:flex-start;
  padding:var(--sp-4); border-radius:var(--r-1);
  border:1px solid var(--state-bad); background:var(--state-bad-quiet);
  color:var(--ink-strong); margin-bottom:var(--sp-5);
}
.notice--warn{ border-color:var(--state-warn); background:var(--state-warn-quiet); }
.notice--good{ border-color:var(--state-good); background:var(--state-good-quiet); }
.notice p{ margin:0; }
.notice__id{
  display:block; margin-top:var(--sp-2);
  font-family:var(--font-mono); font-size:var(--fs-micro); color:var(--ink-quiet);
}

/* --- the receipt and the order-status document ---------------------------- */
/* The one place the money pages relax. A document, set like a document: a wide
   left column of facts, a narrow right column of what to do next, and a printed
   version that is genuinely usable on paper. */
.doc{ display:grid; gap:var(--sp-6); }
@media (min-width:900px){ .doc{ grid-template-columns:minmax(0,7fr) minmax(0,4fr); column-gap:var(--sp-8); align-items:start; } }
.doc__num{
  font-family:var(--font-mono); font-size:var(--fs-fine); font-weight:500;
  letter-spacing:.06em; color:var(--ink-quiet);
}
.doc h1{ font-size:var(--fs-2); line-height:1.12; letter-spacing:-.012em; margin-top:var(--sp-2); }
.doc__lede{ font-size:var(--fs-lead); color:var(--ink); margin-top:var(--sp-3); max-width:52ch; }
.doc__block{ margin-top:var(--sp-7); }
.doc__block h2{ font-size:var(--fs-4); margin-bottom:var(--sp-4); }
.doc__facts{ display:grid; gap:var(--sp-5); }
@media (min-width:560px){ .doc__facts{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.doc__fact dt{ font-size:var(--fs-micro); letter-spacing:.06em; text-transform:uppercase; color:var(--ink-quiet); }
.doc__fact dd{ margin:var(--sp-2) 0 0; color:var(--ink-strong); }

/* The timeline is a real ordered list with a rule down the left. Not a stepper
   with icons: the events are whatever actually happened, in whatever order. */
.tl{ position:relative; padding-left:var(--sp-5); }
.tl::before{ content:""; position:absolute; left:4px; top:6px; bottom:6px; width:1px; background:var(--line); }
.tl li{ position:relative; padding-bottom:var(--sp-4); }
.tl li:last-child{ padding-bottom:0; }
.tl li::before{
  content:""; position:absolute; left:calc(-1 * var(--sp-5) + 1px); top:7px;
  width:7px; height:7px; border-radius:50%; background:var(--line-strong);
}
.tl li[data-now="true"]::before{ background:var(--brand-accent); }
.tl__when{ font-family:var(--font-mono); font-size:var(--fs-micro); color:var(--ink-quiet); display:block; }
.tl__what{ color:var(--ink-strong); }

/* --- the account shell ---------------------------------------------------- */
.acct{ display:grid; gap:var(--sp-6); }
@media (min-width:900px){ .acct{ grid-template-columns:200px minmax(0,1fr); column-gap:var(--sp-8); align-items:start; } }
.acct__nav{ display:flex; gap:var(--sp-2); overflow-x:auto; padding-bottom:var(--sp-2); }
@media (min-width:900px){
  .acct__nav{ flex-direction:column; overflow:visible; position:sticky; top:var(--sp-6); }
}
.acct__nav button{
  flex:none; min-height:44px; padding:var(--sp-2) var(--sp-4);
  background:none; border:1px solid transparent; border-radius:var(--r-1);
  color:var(--ink); cursor:pointer; text-align:left; white-space:nowrap;
}
.acct__nav button:hover{ background:var(--surface-sunken); color:var(--ink-strong); }
.acct__nav button[aria-current="page"]{
  background:var(--surface-sunken); border-color:var(--line-strong); color:var(--ink-strong); font-weight:500;
}
.acct__panel h2{ font-size:var(--fs-4); margin-bottom:var(--sp-4); }

/* An order row in the account list. Compact, tabular figures, one tap target. */
.orderrow{
  display:grid; gap:var(--sp-2) var(--sp-4); align-items:baseline;
  grid-template-columns:minmax(0,1fr) auto;
  padding:var(--sp-4) 0; border-bottom:1px solid var(--line-hairline);
}
.orderrow__num{ font-family:var(--font-mono); font-weight:500; color:var(--ink-strong); }
.orderrow__num a{ color:inherit; text-decoration:none; }
.orderrow__num a:hover{ text-decoration:underline; }
.orderrow__meta{ font-size:var(--fs-fine); color:var(--ink-quiet); grid-column:1; }
.orderrow__price{ grid-row:1; grid-column:2; text-align:right; }
.orderrow__state{ grid-row:2; grid-column:2; text-align:right; font-size:var(--fs-fine); color:var(--ink-quiet); }

/* --- an empty state that says what to do next ----------------------------- */
.blank{ padding:var(--sp-8) 0; max-width:46ch; }
.blank h2{ font-size:var(--fs-4); margin-bottom:var(--sp-3); }
.blank p{ color:var(--ink-quiet); }

@media print{
  .money__split > .summary,.acct__nav,.promo,.paynow,.trustrow,.summary--fold{ display:none !important; }
  .doc{ grid-template-columns:1fr; }
  .doc__block{ break-inside:avoid; }
}
