/* ==========================================================================
   DINKOMART - Components
   Header, footer, section heads, carousels, product cards, category cards,
   seals, cart drawer, toasts.
   ========================================================================== */

/* ==================================================================== announcement */
.strip {
  background: var(--raw-night);
  color: #C6D6C9;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  overflow: hidden;
}
.strip-in { display: flex; align-items: center; gap: var(--s-6); min-height: 38px; white-space: nowrap; }
.strip b { color: #F0973F; font-weight: 600; }
.strip .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--raw-sprout); flex: none; }
@media (max-width: 760px) {
  .strip-in { overflow-x: auto; scrollbar-width: none; }
  .strip-in::-webkit-scrollbar { display: none; }
}

/* ==================================================================== header */
.site-nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(1.5) blur(16px);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.site-nav.is-stuck { border-bottom-color: var(--border); box-shadow: var(--shadow-sm); }

.nav-in { display: flex; align-items: center; gap: var(--s-4); min-height: 74px; }

.brand { display: inline-flex; align-items: center; gap: var(--s-3); text-decoration: none; color: var(--fg); min-width: 0; }
.brand-text { min-width: 0; overflow: hidden; }
/* The mark is req/img/dinkomart.png — a 2.15:1 horizontal lockup drawn on a
   SQUARE 1254px canvas, so roughly 30% of its height above and below the
   artwork is transparent. `cover` on a 2.2:1 box scales it to the box width
   and crops that dead space away; `contain` would fit the whole square and
   render the mark at less than half the height it should be.
   No border-radius: the old mark was a rounded badge, this one is not, and a
   radius here would bite into the D and the M.

   `flex: none` and `max-width: none` are both load-bearing. .brand is a flex
   row inside another flex row and carries `min-width: 0` so the wordmark can
   truncate — which also lets the whole brand be squeezed. base.css sets
   `img { max-width: 100% }` globally, so the mark then clamps to whatever
   width the squeezed .brand ended up with (76px was the first symptom) and
   `cover` crops the D off the left and the M off the right. The mark holds its
   size; the wordmark beside it is what gives way. */
.brand img { width: 88px; height: 40px; object-fit: cover; flex: none; max-width: none; }
.brand-text { display: grid; line-height: 1; }
.brand-name { font-family: var(--font-display); font-size: 22px; font-weight: 800; letter-spacing: -.03em; }
.brand-tag { font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: .14em; text-transform: uppercase; color: var(--fg-subtle); margin-top: 4px; }
@media (max-width: 420px) { .brand-tag { display: none; } }

.nav-links { display: none; align-items: center; gap: 2px; }
@media (min-width: 1080px) { .nav-links { display: flex; } }

.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--s-4);
  border-radius: var(--r-ctl);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--fg-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease-out), background-color var(--dur-1) var(--ease-out);
}
.nav-link:hover { color: var(--fg); background: var(--surface-2); }
.nav-link[aria-current='page'] { color: var(--brand); background: var(--brand-soft); }

/* search sits in the header on desktop: this is a marketplace, search is the CTA */
.nav-search { display: none; position: relative; flex: 1 1 auto; max-width: 380px; margin-inline: var(--s-3); }
@media (min-width: 1080px) { .nav-search { display: block; } }
.nav-search .input { min-height: 44px; padding-left: 42px; border-radius: var(--r-pill); background: var(--surface-2); border-color: transparent; }
.nav-search .input:hover { background: var(--surface); border-color: var(--border-strong); }
.nav-search .input:focus { background: var(--surface); }
.nav-search .ico { position: absolute; left: 14px; top: 22px; transform: translateY(-50%); color: var(--fg-subtle); pointer-events: none; }

.nav-tools { display: flex; align-items: center; gap: var(--s-1); margin-left: auto; flex: none; }

.cart-btn { position: relative; }
.cart-count {
  position: absolute;
  top: 2px; right: 1px;
  min-width: 19px; height: 19px;
  padding: 0 5px;
  display: none;
  place-items: center;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--accent-fg);
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  font-weight: 600;
  line-height: 19px;
  box-shadow: 0 0 0 2px var(--bg);
}
.cart-count.is-on { display: grid; }

.nav-toggle { display: inline-flex; }
@media (min-width: 1080px) { .nav-toggle { display: none; } }
.nav-search-btn { display: inline-flex; }
@media (min-width: 1080px) { .nav-search-btn { display: none; } }

.nav-drawer .offcanvas-body { padding: var(--s-6); }
.nav-drawer .nav-link {
  height: 56px; width: 100%;
  font-size: var(--t-lg);
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--fg);
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding-inline: 0;
  background: transparent;
}
.nav-drawer .nav-link:hover { background: transparent; color: var(--brand); }

/* ==================================================================== section head */
.sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-5);
  margin-bottom: var(--s-8);
}
.sec-head-copy { max-width: 62ch; }
.sec-head h2 { margin-bottom: var(--s-2); }
/* the eyebrow keeps its own mono treatment, it is not body copy */
.sec-head p:not(.eyebrow) { margin: 0; color: var(--fg-muted); font-size: var(--t-md); }
.on-band .sec-head p:not(.eyebrow) { color: var(--band-fg-muted); }

.see-all {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: 0 var(--s-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  font-size: var(--t-sm);
  font-weight: 600;
  color: var(--fg);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.see-all:hover { background: var(--brand); border-color: var(--brand); color: var(--brand-fg); }
.see-all .ico { transition: transform var(--dur-1) var(--ease-out); }
.see-all:hover .ico { transform: translateX(3px); }
.on-band .see-all { color: var(--band-fg); border-color: var(--band-border); }
.on-band .see-all:hover { background: var(--band-fg); color: var(--raw-night); border-color: var(--band-fg); }

/* ==================================================================== carousel rail */
.rail { position: relative; }

.rail-nav { display: none; gap: var(--s-2); }
@media (min-width: 900px) { .rail-nav { display: flex; } }

.rail-btn {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: var(--fg);
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out), opacity var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out);
}
.rail-btn:hover { background: var(--brand); border-color: var(--brand); color: var(--brand-fg); }
.rail-btn:active { transform: scale(.94); }
.rail-btn[disabled] { opacity: .32; cursor: not-allowed; pointer-events: none; }
.on-band .rail-btn { background: transparent; border-color: var(--band-border); color: var(--band-fg); }
.on-band .rail-btn:hover { background: var(--band-fg); color: var(--raw-night); }

.rail-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(238px, 1fr);
  gap: var(--s-4);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  padding-bottom: var(--s-2);
  /* let card shadows breathe without being clipped by the scroll box */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);

  /* AND THE TOP NEEDS IT MORE THAN ANY OTHER SIDE, BECAUSE THE CARD MOVES UP.

     `overflow-x: auto` cannot be paired with `overflow-y: visible` — the used
     value of the other axis becomes `auto` too, which is why this rule already
     compensates on three sides. The top was the one side left at zero, and it
     is the only side the card actually travels toward: `.pcard:hover` is
     `translateY(-4px)` (refine.css §3).

     Measured on /index: the rail's content top and the card's resting top were
     the SAME pixel — 2126.81 — so the clearance was 0 and the whole 4px of
     lift, the card's top border with it, was clipped off by the scroll box.
     That is why this only ever showed on the home page. The shop and the four
     category pages put the same card in `.prod-grid`, which is not a scroll
     box and does not clip, so every check run against a grid card came back
     clean while the rails stayed broken.

     Reported three times. The first two fixes were aimed at the card; the card
     was never the problem, its container was.

     `padding-top` opens the clearance and the negative `margin-top` takes the
     layout back, so nothing below moves — the same idiom as the inline axis
     two lines up. 12px covers the 4px lift with room for the hover shadow. */
  padding-top: var(--s-3);
  margin-top: calc(var(--s-3) * -1);
}
.rail-track::-webkit-scrollbar { display: none; }
.rail-track > * { scroll-snap-align: start; }
@media (prefers-reduced-motion: reduce) { .rail-track { scroll-behavior: auto; } }

@media (min-width: 640px)  { .rail-track { grid-auto-columns: minmax(262px, 1fr); } }
@media (min-width: 1180px) { .rail-track { grid-auto-columns: minmax(280px, 1fr); } }

/* ==================================================================== product card */
.pcard {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.pcard:hover { border-color: transparent; box-shadow: var(--shadow-lg); transform: translateY(-4px); }
.pcard:focus-within { border-color: var(--brand); }
@media (prefers-reduced-motion: reduce) { .pcard:hover { transform: none; } }

.pcard-media {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
  overflow: hidden;
}
.pcard-media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 620ms var(--ease-out);
}
.pcard:hover .pcard-media img { transform: scale(1.055); }
@media (prefers-reduced-motion: reduce) { .pcard:hover .pcard-media img { transform: none; } }

/* machinery photography is a flyer, not a studio shot: contain it on a
   neutral tile so it reads as a product rather than a poster */
.pcard-media.is-contain { background: var(--raw-white); }
.pcard-media.is-contain img { object-fit: contain; padding: var(--s-5); }
[data-theme='dark'] .pcard-media.is-contain { background: #F2F0EA; }

.pcard-flags { position: absolute; top: var(--s-3); left: var(--s-3); display: grid; gap: 5px; justify-items: start; z-index: 2; }


.pcard-body { display: flex; flex-direction: column; gap: var(--s-2); padding: var(--s-5); flex: 1; }
.pcard-cat { font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: var(--tr-mono); text-transform: uppercase; color: var(--fg-subtle); }
.pcard-name { font-family: var(--font-display); font-size: var(--t-md); font-weight: 700; letter-spacing: -.018em; line-height: 1.24; margin: 0; }
.pcard-name a { text-decoration: none; color: inherit; }
.pcard-name a::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.pcard-short { font-size: var(--t-sm); color: var(--fg-muted); margin: 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

.pcard-foot { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-3); margin-top: auto; padding-top: var(--s-4); }

.price { display: grid; gap: 1px; }
.price-now { font-family: var(--font-display); font-size: var(--t-lg); font-weight: 800; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.price-was { font-family: var(--font-mono); font-size: var(--t-xs); color: var(--fg-subtle); text-decoration: line-through; }
.price-unit { font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-subtle); }

.pcard-act { position: relative; z-index: 2; }
.add-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 42px;
  padding: 0 var(--s-4);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-fg);
  font-family: var(--font-body);
  font-size: var(--t-sm);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur-1) var(--ease-out), transform var(--dur-1) var(--ease-out);
}
.add-btn:hover { background: var(--brand-hover); transform: translateY(-1px); }
.add-btn:active { transform: scale(.96); }
.add-btn.is-wa { background: var(--surface-2); color: var(--fg); border: 1px solid var(--border-strong); }
.add-btn.is-wa:hover { background: var(--brand); color: var(--brand-fg); border-color: var(--brand); }
@media (prefers-reduced-motion: reduce) { .add-btn:hover { transform: none; } }

/* ==================================================================== category card */
.cat-card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 300px;
  padding: var(--s-6);
  border-radius: var(--r-card);
  overflow: hidden;
  text-decoration: none;
  color: #fff;
  isolation: isolate;
  background: var(--raw-ink);
  transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out);
}
.cat-card:hover { transform: translateY(-5px); box-shadow: var(--shadow-lg); }
.cat-card:focus-visible { outline: 3px solid var(--border-focus); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .cat-card:hover { transform: none; } }

.cat-card img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: -2;
  transition: transform 720ms var(--ease-out);
}
.cat-card:hover img { transform: scale(1.07); }
@media (prefers-reduced-motion: reduce) { .cat-card:hover img { transform: none; } }

.cat-card::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(to top, rgba(6, 20, 12, .92) 4%, rgba(6, 20, 12, .58) 42%, rgba(6, 20, 12, .12) 78%);
}

.cat-card .cat-ico { width: 30px; height: 30px; stroke: var(--raw-sprout); stroke-width: 1.5; fill: none; stroke-linecap: round; stroke-linejoin: round; margin-bottom: var(--s-3); }
.cat-card h3 { font-size: var(--t-xl); margin: 0 0 var(--s-2); color: #fff; }
.cat-card p { font-size: var(--t-sm); color: rgba(255, 255, 255, .82); margin: 0 0 var(--s-4); max-width: 34ch; }
.cat-go {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: #F0973F;
}
.cat-go .ico { width: 15px; height: 15px; transition: transform var(--dur-1) var(--ease-out); }
.cat-card:hover .cat-go .ico { transform: translateX(4px); }
.cat-count {
  position: absolute;
  top: var(--s-5); right: var(--s-5);
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  letter-spacing: var(--tr-mono);
  text-transform: uppercase;
  color: rgba(255, 255, 255, .82);
  background: rgba(0, 0, 0, .34);
  backdrop-filter: blur(6px);
  padding: 5px 10px;
  border-radius: var(--r-pill);
}

/* ==================================================================== usp strip

   FOUR CARDS, AND THE SURFACE HAS TO BE REAL.

   The version this replaces was `--glass`: white at 74%, which composites to
   1.03:1 against the page, with a 1.29:1 border, a 1.19:1 icon tile and no
   shadow at all. Nothing in it cleared the point where an edge reads as an
   edge, so four cards came across as four smudges.

   The fix is not more border — it is elevation. `--shadow-sm` is what lifts a
   card off a near-white page; the border only keeps the edge crisp where the
   shadow is weakest. That is also why `.usp-item` is no longer in the glass
   list in atmosphere.css and must not go back: it is opaque on purpose.

   HOVER IS TWO BEATS, NOT A LIFT AND A PRAYER.
   One: the tile floods brand, the glyph inverts to --brand-fg, and the tile's
   radius eases open a few pixels so it reads as pressed rather than recoloured.
   Two: a rule sweeps the bottom edge left to right, brand into accent. That
   gradient is the site's own two-way story — produce out in forest, machinery
   back in harvest — so the detail carries the argument the section is making
   instead of just moving.

   THESE ARE NOT LINKS, AND THE HOVER IS TUNED SO THEY DO NOT CLAIM TO BE.
   No `cursor: pointer`, a 3px lift rather than the usual 8, and `.usp-item` is
   absent from RULES in cursor.js so the custom cursor stays at rest over them.
   The card answers the pointer; it does not offer to be clicked.

   Every duration here is a `--dur-*` token, which tokens.css collapses to 1ms
   under prefers-reduced-motion — so this needs no media query of its own. */
.usp {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.usp-item {
  position: relative;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  gap: var(--s-4);
  align-items: center;
  padding: var(--s-5);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-sm);
  overflow: hidden;                    /* clips the sweep to the radius */
  transition: transform var(--dur-2) var(--ease-spring),
              border-color var(--dur-1) var(--ease-out),
              box-shadow var(--dur-2) var(--ease-out);
}

/* beat two — the sweep. Sits on the bottom edge and draws from the left. */
.usp-item::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: 2px;
  background: linear-gradient(90deg, var(--brand), var(--accent));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-3) var(--ease-soil);
}

.usp-item:hover {
  transform: translateY(-3px);
  border-color: var(--brand);
  box-shadow: var(--shadow-md);
}
.usp-item:hover::after { transform: scaleX(1); }

/* beat one — the tile */
.usp-ico {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: var(--brand-soft);
  transition: background-color var(--dur-1) var(--ease-out),
              border-radius var(--dur-2) var(--ease-spring),
              transform var(--dur-2) var(--ease-spring);
}
.usp-ico .ico { color: var(--brand); transition: color var(--dur-1) var(--ease-out); }
.usp-item:hover .usp-ico {
  background: var(--brand);
  border-radius: 15px;
  transform: scale(1.06);
}
.usp-item:hover .usp-ico .ico { color: var(--brand-fg); }

.usp-item b { display: block; font-size: var(--t-sm); font-weight: 700; line-height: 1.3; }
.usp-item span { font-size: var(--t-xs); color: var(--fg-subtle); line-height: 1.4; }

/* Four across needs about 1100px. At 880 the cells measured 199px, which wraps
   "Field crate to your door, no gap" to three lines and orphans the last word
   in three of the four. Below that they fold to a 2x2, which is roomier than
   four cramped columns and keeps the cards square-ish rather than letterboxed. */
@media (max-width: 1099px) {
  .usp { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ==================================================================== seals, badges */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: var(--r-chip);
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--fg-muted);
  white-space: nowrap;
}
.badge-accent  { background: var(--accent-soft);  border-color: transparent; color: var(--accent-ink); }
.badge-brand   { background: var(--brand-soft);   border-color: transparent; color: var(--brand); }
.badge-danger  { background: var(--danger-soft);  border-color: transparent; color: var(--danger); }
.badge-solid   { background: var(--raw-ink); border-color: transparent; color: #fff; }
.on-band .badge { background: rgba(255, 255, 255, .07); border-color: var(--band-border); color: var(--band-fg-muted); }

.seal {
  display: inline-grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  background: var(--accent-soft);
}
.seal .ico { color: var(--accent-ink); }
.seal-text { display: grid; line-height: 1.3; }
.seal-text b { font-size: var(--t-sm); font-weight: 700; }
.seal-text span { font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: .07em; text-transform: uppercase; color: var(--fg-subtle); }
.on-band .seal { background: rgba(240, 151, 63, .12); border-color: var(--band-border); }
.on-band .seal-text span { color: var(--band-fg-muted); }
.on-band .seal .ico, .on-band .seal-text b { color: var(--band-accent); }

/* ==================================================================== spec table */
.spec { width: 100%; border-collapse: collapse; font-family: var(--font-mono); font-size: var(--t-sm); }
.spec th, .spec td { text-align: left; padding: var(--s-3) 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.spec th { width: 44%; font-weight: 500; color: var(--fg-subtle); letter-spacing: .04em; text-transform: uppercase; font-size: 11px; padding-right: var(--s-4); }
.spec td { font-weight: 500; font-variant-numeric: tabular-nums; }
.spec tr:last-child th, .spec tr:last-child td { border-bottom: 0; }

/* ==================================================================== facts */
.facts { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.fact { display: grid; gap: var(--s-3); padding: var(--s-6); border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); align-content: start; }
.on-band .fact { background: rgba(255, 255, 255, .035); border-color: var(--band-border); }
.fact .ico { color: var(--accent-ink); }
.on-band .fact .ico { color: var(--band-accent); }
.fact b { font-family: var(--font-display); font-size: var(--t-md); font-weight: 700; letter-spacing: -.018em; }
.fact span { font-size: var(--t-sm); color: var(--fg-muted); line-height: 1.55; }
.on-band .fact span { color: var(--band-fg-muted); }

/* ==================================================================== cart drawer */
.cart-drawer { width: min(440px, 100vw) !important; }
.cart-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-5) var(--s-6); border-bottom: 1px solid var(--border); }
.cart-head h2 { font-size: var(--t-lg); margin: 0; }
.cart-body { flex: 1; overflow-y: auto; padding: var(--s-4) var(--s-6); }
.cart-foot { border-top: 1px solid var(--border); padding: var(--s-5) var(--s-6); background: var(--surface-2); display: grid; gap: var(--s-3); }

.cart-line { display: grid; grid-template-columns: 66px minmax(0, 1fr) auto; gap: var(--s-4); padding: var(--s-4) 0; border-bottom: 1px solid var(--border); }
.cart-line:last-child { border-bottom: 0; }
.cart-thumb { width: 66px; height: 66px; border-radius: var(--r-ctl); overflow: hidden; background: var(--surface-2); border: 1px solid var(--border); }
.cart-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-thumb .specimen-tag { display: none; }
.cart-thumb .specimen svg { width: 54%; }
.cart-line-name { font-weight: 700; font-size: var(--t-sm); line-height: 1.3; margin: 0 0 3px; }
.cart-line-meta { font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-subtle); }
.cart-line-price { font-family: var(--font-display); font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }

.qty { display: inline-flex; align-items: center; border: 1px solid var(--border-strong); border-radius: var(--r-pill); overflow: hidden; margin-top: var(--s-2); }
.qty button {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  background: transparent; border: 0; cursor: pointer; color: var(--fg);
  transition: background-color var(--dur-1) var(--ease-out);
}
.qty button:hover { background: var(--surface-2); }
.qty button:disabled { opacity: .35; cursor: not-allowed; }
.qty output { min-width: 34px; text-align: center; font-family: var(--font-mono); font-size: var(--t-sm); font-weight: 600; font-variant-numeric: tabular-nums; }

.cart-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); font-size: var(--t-sm); }
.cart-row b { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.cart-row.is-total { font-size: var(--t-md); font-weight: 700; padding-top: var(--s-3); border-top: 1px solid var(--border); }
.cart-row.is-total b { font-size: var(--t-xl); font-family: var(--font-display); font-weight: 800; letter-spacing: -.03em; }

.empty { display: grid; justify-items: center; text-align: center; gap: var(--s-3); padding: var(--s-10) var(--s-4); color: var(--fg-muted); }
.empty .ico { width: 44px; height: 44px; color: var(--border-strong); }
.empty b { font-family: var(--font-display); font-size: var(--t-lg); color: var(--fg); }
.empty p { font-size: var(--t-sm); margin: 0; max-width: 32ch; }

/* ==================================================================== toast */
.toast-zone {
  position: fixed;
  left: 50%; bottom: var(--s-6);
  transform: translateX(-50%);
  z-index: var(--z-toast);
  display: grid;
  gap: var(--s-2);
  width: min(430px, calc(100vw - 32px));
  pointer-events: none;
}
.toast-msg {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-ctl);
  background: var(--raw-night);
  color: #F3F0E6;
  border: 1px solid #1E3B2A;
  box-shadow: var(--shadow-xl);
  font-size: var(--t-sm);
  font-weight: 600;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out);
}
.toast-msg.is-in { opacity: 1; transform: none; }
.toast-msg .ico { color: var(--raw-sprout); flex: none; }
.toast-msg.is-warn .ico { color: #F0973F; }

/* ==================================================================== footer */
.site-footer { background: var(--raw-night); color: #F3F0E6; padding-block: var(--s-11) var(--s-7); position: relative; overflow: hidden; }
/* Brand block plus FOUR link columns — Shop, Company, Help, Reach us. The
   count is in the track list, so adding a fifth column without widening this
   silently wraps it under the brand. */
.foot-grid { display: grid; gap: var(--s-8); }
@media (min-width: 780px)  { .foot-grid { grid-template-columns: 1.6fr 1fr 1fr; } }
@media (min-width: 1060px) { .foot-grid { grid-template-columns: 2fr repeat(4, 1fr); } }

.foot-brand .brand { color: #F3F0E6; }
.foot-brand .brand-tag { color: #A3B8A9; }
.foot-blurb { color: #A3B8A9; font-size: var(--t-sm); max-width: 42ch; margin: var(--s-5) 0 var(--s-6); }

.foot-col h4 { font-family: var(--font-mono); font-size: var(--t-2xs); font-weight: 500; letter-spacing: var(--tr-mono); text-transform: uppercase; color: #A3B8A9; margin-bottom: var(--s-4); }
.foot-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-3); }
.foot-col a { color: #F3F0E6; text-decoration: none; font-size: var(--t-sm); transition: color var(--dur-1) var(--ease-out); display: inline-flex; align-items: center; gap: 8px; }
.foot-col a:hover { color: #F0973F; }

.foot-line {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--s-4);
  margin-top: var(--s-10); padding-top: var(--s-6);
  border-top: 1px solid #1E3B2A;
  font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: .06em; text-transform: uppercase;
  color: #A3B8A9;
}
.foot-line a { color: inherit; }
.foot-line a:hover { color: #F0973F; }

/* ==================================================================== misc */
.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--fg-subtle); margin-bottom: var(--s-6);
}
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--brand); }
.breadcrumb .ico { width: 13px; height: 13px; opacity: .55; }

.note {
  display: flex; gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--accent);
  background: var(--surface-2);
  border-radius: 0 var(--r-ctl) var(--r-ctl) 0;
  font-size: var(--t-sm);
  color: var(--fg-muted);
}
.note .ico { color: var(--accent-ink); flex: none; }
.on-band .note { background: rgba(255, 255, 255, .045); color: var(--band-fg-muted); }
.on-band .note .ico { color: var(--band-accent); }

.divider-lead {
  display: flex; align-items: center; gap: var(--s-4);
  font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: var(--fg-subtle); margin-bottom: var(--s-6);
}
.divider-lead::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* ==================================================================== steps

   A RULED INDEX, NOT THREE CHIPS ON A STRING.

   The previous pass hung a 38px node in a 62px gutter and ran a hairline stub
   between the nodes. It had hover states and an arrival sequence and it still
   looked thin: the numerals were smaller than the body copy they indexed, the
   gutter was mostly empty, and the rail connected two things that were already
   obviously connected. Motion cannot fix proportion.

   This sets the numeral as type — 1.4rem mono, hanging in its own column,
   larger than the heading it labels — and rules the rows like a contents page.
   Density and typographic contrast do the work the decoration was doing badly.

   `list-style: none` FIXES A VISIBLE BUG and must stay. This is an <ol>, and
   the items were drawing the browser's own marker on top of the
   `counter(step, decimal-leading-zero)` in ::before, so every step read
   "1. 01", "2. 02", "3. 03". `display: grid` does not suppress it — the <li>
   keeps `display: list-item` and draws its ::marker regardless. */
.steps {
  counter-reset: step;
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--hairline);
}

/* Explicit placement, because ::before, h3 and p are three siblings and a
   two-column grid would otherwise wrap the paragraph under the numeral. */
.step {
  position: relative;
  counter-increment: step;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  column-gap: var(--s-4);
  padding: var(--s-5) 0;
  border-bottom: 1px solid var(--hairline);
}
/* The numeral is a box, not bare type. `align-self`/`justify-self: start` keep
   it a 38px square at the top of its column — without them a grid item spanning
   two rows stretches to fill them. */
.step::before {
  content: counter(step, decimal-leading-zero);
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: start;
  justify-self: start;
  margin-top: -2px;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--accent-ink);
  transition: background-color var(--dur-1) var(--ease-out),
              color var(--dur-1) var(--ease-out),
              border-color var(--dur-1) var(--ease-out),
              border-radius var(--dur-2) var(--ease-spring),
              transform var(--dur-2) var(--ease-spring);
}
.step h3 { grid-column: 2; grid-row: 1; font-size: var(--t-md); margin-bottom: var(--s-2); }
.step p  { grid-column: 2; grid-row: 2; font-size: var(--t-sm); color: var(--fg-muted); margin: 0; }

/* the row rule inks in, the same gesture the credential wall and the crate
   list make. One idea, used three times, instead of three different ones. */
.step::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-3) var(--ease-soil);
}
.step:hover::before {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
  border-radius: 15px;
  transform: scale(1.06);
}
.step:hover::after { transform: scaleX(1); }

/* THE WALK-DOWN. The rows arrive in sequence, so the list reads in the order
   it is meant to be read. Guarded on html.m-ready exactly like `.sec-rule` and
   `.crate-list`: motion.js sets that class, so with no script the class never
   appears and all three steps are simply already there.

   NOTHING HERE MAY TOUCH ::after. It used to drive the rail's scaleY on
   arrival, but ::after is the hover ink rule now — and at (0,4,1) these
   selectors out-rank `.step:hover::after` at (0,2,1), which would pin every
   rule open and kill the hover outright. The arrival animates the <li>; the
   hover animates its pseudo-elements. Keep them on separate elements. */
html.m-ready [data-rise] .step {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--dur-2) var(--ease-out),
              transform var(--dur-2) var(--ease-soil);
}
html.m-ready [data-rise].is-in .step { opacity: 1; transform: none; }
html.m-ready [data-rise].is-in .step:nth-child(1) { transition-delay: 140ms; }
html.m-ready [data-rise].is-in .step:nth-child(2) { transition-delay: 260ms; }
html.m-ready [data-rise].is-in .step:nth-child(3) { transition-delay: 380ms; }

/* the specimen tile: authored artwork for products with no photograph */
.specimen {
  --tint: var(--brand);
  /* per-product, written by A.media() from a hash of the product id, so no two
     photograph-less tiles carry the same texture */
  --sp-a: 155deg;
  --sp-s: 15px;
  position: relative;
  display: grid; place-items: center;
  width: 100%; height: 100%;
  overflow: hidden;
  background: linear-gradient(var(--sp-a), color-mix(in srgb, var(--tint) 16%, var(--surface)), var(--surface));
}
/* the lattice is its own layer so it can rotate without taking the wash with
   it; oversized and centred so the rotation never exposes a corner */
.specimen::before {
  content: '';
  position: absolute;
  inset: -35%;
  pointer-events: none;
  transform: rotate(var(--sp-a));
  background:
    radial-gradient(circle at 1.2px 1.2px, color-mix(in srgb, var(--tint) 26%, transparent) 1.2px, transparent 0)
    0 0 / var(--sp-s) var(--sp-s);
}
.specimen svg {
  position: relative;   /* above the rotated lattice in ::before */
  width: 44%; max-width: 96px; height: auto; aspect-ratio: 1;
  stroke: var(--tint); stroke-width: 1.05; fill: none; stroke-linecap: round; stroke-linejoin: round;
  opacity: .8;
}
.specimen-tag {
  position: absolute; left: var(--s-4); bottom: var(--s-3); z-index: 1;
  font-family: var(--font-mono); font-size: var(--t-2xs); letter-spacing: var(--tr-mono); text-transform: uppercase;
  color: color-mix(in srgb, var(--tint) 70%, var(--fg));
}
.tint-clay    { --tint: var(--raw-clay); }
.tint-forest  { --tint: var(--brand); }
.tint-harvest { --tint: var(--accent); }
.tint-sprout  { --tint: var(--sprout); }
.tint-chill   { --tint: var(--chill); }

/* ==========================================================================
   Corrections that must beat the component rules above, so they live last.
   ========================================================================== */

/* Four 44px controls plus the wordmark do not fit a 375px phone. Search moves
   into the menu drawer below this width rather than being squeezed. */
@media (max-width: 559px) {
  .nav-search-btn { display: none; }
  .nav-in { gap: var(--s-2); min-height: 66px; }
  .brand img { width: 68px; height: 31px; }
  .brand-name { font-size: 19px; }
}

/* Compact controls stay compact with a mouse; every touch target grows to the
   44px minimum on a finger-driven device. */
@media (pointer: coarse) {
  .btn-sm { min-height: 44px; }
  .add-btn { min-height: 44px; }
  .qty button { width: 44px; height: 44px; }
  .filter-opt { min-height: 48px; }
}
