/* ==========================================================================
   PAK SHILAJIT — COMPONENT LIBRARY
   Build once, use everywhere. Every page on the site is assembled from
   THESE components. If a page seems to need a new one, it does not —
   it needs an existing one. (§5B.5)
   ========================================================================== */


/* ==========================================================================
   1. BUTTONS  (§5B.2 — four variants, zero exceptions)
   Every geometric property below is shared by all four variants. A button
   in the checkout is pixel-identical to a button in a blog post.
   ========================================================================== */

.btn {
  --_bg: transparent;
  --_fg: var(--ink);
  --_bd: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);

  block-size: var(--btn-h-mob);
  padding-inline: var(--btn-pad-x);

  font-family: var(--font);
  font-size: var(--btn-fs);
  font-weight: var(--btn-fw);
  letter-spacing: var(--btn-tr);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;

  background: var(--_bg);
  color: var(--_fg);
  border: 1px solid var(--_bd);
  border-radius: var(--btn-radius);
  cursor: pointer;

  transition: background-color var(--dur) var(--ease),
              color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

@media (min-width: 768px) { .btn { block-size: var(--btn-h); } }

.btn:hover { color: var(--_fg); }

/* Primary — amber fill, ink text (10.67:1). The brand signature. */
.btn--primary { --_bg: var(--accent); --_fg: var(--ink); }
.btn--primary:hover { --_bg: var(--accent-hover); }

/* Secondary — ink outline on transparent. */
.btn--secondary { --_bd: var(--ink); --_fg: var(--ink); }
.btn--secondary:hover { --_bg: var(--ink); --_fg: var(--bg); }

/* Quiet — inline text action. Remove, Edit, View all. */
.btn--quiet {
  --_fg: var(--accent-deep);
  padding-inline: 0;
  block-size: auto;
  min-block-size: 44px;         /* touch target held even without padding */
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: .3em;
}
.btn--quiet:hover { text-decoration-color: currentColor; }
/* Quiet is an inline text action, not a fixed-geometry control, so its label
   wraps instead of overflowing a narrow column — a long one pushed a 360px
   page sideways. The other three variants keep nowrap: their width is allowed
   to grow with the label, but their line count is not. */
.btn--quiet { white-space: normal; text-align: start; }

/* On-band — identical to primary, declared separately so dark sections
   can never accidentally inherit a light-on-light variant. */
.btn--onband { --_bg: var(--accent); --_fg: var(--ink); }
.btn--onband:hover { --_bg: var(--accent-hover); }
.band .btn--secondary { --_bd: var(--on-band-soft); --_fg: var(--on-band); }
.band .btn--secondary:hover { --_bg: var(--on-band); --_fg: var(--ink); }

/* Full-width. Padding is NOT overridden — a second padding value would be a
   second button signature, and §5B.2 allows exactly one per variant. */
.btn--block { inline-size: 100%; }

.btn[disabled], .btn[aria-disabled="true"] {
  opacity: .4;
  cursor: not-allowed;
  pointer-events: none;
}

/* Loading — text swaps for a spinner AT THE SAME WIDTH. The button must
   not resize, or add-to-cart (the highest-frequency interaction on the
   site) shifts the layout every time it is pressed. */
.btn.is-loading { color: transparent !important; position: relative; }
.btn.is-loading::after {
  content: "";
  position: absolute;
  inline-size: 16px; block-size: 16px;
  border: 2px solid currentColor;
  border-block-start-color: transparent;
  border-radius: 50%;
  color: var(--ink);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* --- Spacing around buttons (§5B.3) — the owner's specific instruction.
   A button never touches another element. */

.btn-group { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
@media (max-width: 479px) {
  .btn-group { flex-direction: column; }
  .btn-group .btn { inline-size: 100%; }
}

/* Clearance when a button follows copy. */
.btn-after-text { margin-block-start: var(--sp-5); }

/* Icon-only control — still 44px, still labelled. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 44px; block-size: 44px;
  background: none; border: 0; padding: 0;
  color: inherit; cursor: pointer;
  border-radius: var(--radius);
  transition: color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.icon-btn:hover { color: var(--accent-deep); }
.band .icon-btn:hover { color: var(--accent); }
.icon-btn svg { inline-size: 20px; block-size: 20px; }


/* ==========================================================================
   2. ANNOUNCEMENT BAR — rotating, above the header
   ========================================================================== */

.announce {
  position: relative;
  z-index: var(--z-bar);
  background: var(--band);
  color: var(--on-band);
  border-block-end: 1px solid var(--band-line);
}
.announce__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  block-size: var(--bar-h);
}
.announce__track {
  position: relative;
  flex: 1;
  block-size: var(--bar-h);
  overflow: hidden;
}
.announce__item {
  position: absolute;
  inset: 0;
  /* The items are sibling <p>s, so the global `p + p` spacing rule was
     shifting every item after the first 16px down — the bar looked centred on
     slide 1 and bottom-heavy on slides 2–4. Margins are zeroed explicitly. */
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  line-height: 1.2;
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  text-align: center;
  opacity: 0;
  transform: translate3d(0, 100%, 0);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.announce__item.is-active { opacity: 1; transform: none; }
.announce__item.is-out { opacity: 0; transform: translate3d(0, -100%, 0); }
.announce__item svg { inline-size: 14px; block-size: 14px; color: var(--accent); flex: none; }
/* Tighten the tracking on narrow screens so every message stays on one line
   inside the fixed-height track rather than clipping. */
@media (max-width: 599px) {
  .announce__item { font-size: 10px; letter-spacing: .1em; gap: 6px; padding-inline: var(--sp-2); }
}
.announce__item a { color: var(--accent); text-decoration-color: currentColor; }
.announce .icon-btn { inline-size: 44px; block-size: 44px; color: var(--on-band-soft); flex: none; }
.announce .icon-btn svg { inline-size: 14px; block-size: 14px; }
@media (max-width: 599px) { .announce .icon-btn { display: none; } }


/* ==========================================================================
   3. HEADER — sticky
   ========================================================================== */

.header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--z-header);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(12px);
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
  border-block-end: 1px solid transparent;
  transition: border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.header.is-stuck {
  background: color-mix(in srgb, var(--bg) 96%, transparent);
  border-block-end-color: var(--line);
}
.header__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  block-size: var(--header-h);
}
.header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  flex: none;
}
.header__brand { min-block-size: 44px; }   /* hit area, not mark size */
.header__brand img { block-size: 34px; inline-size: auto; }
.header__brand:hover { color: var(--ink); }

.nav { display: none; }
@media (min-width: 1000px) {
  .nav {
    display: flex;
    align-items: center;
    gap: var(--sp-6);
    margin-inline-end: auto;
    /* Breathing room between the mark and the first nav item. Without it the
       logo and "Shop" read as one cluster, and the header looks cramped at
       exactly the widths where there is most room to spare. */
    margin-inline-start: var(--sp-7);
  }
}
@media (min-width: 1200px) {
  .nav { margin-inline-start: var(--sp-8); gap: var(--sp-7); }
}
.nav a {
  font-size: var(--fs-small);
  font-weight: var(--fw-med);
  text-decoration: none;
  /* 44px hit area on a 38px line — the underline still tracks the text,
     because ::after is pinned to the bottom of the padded box. */
  padding-block: var(--sp-3);
  position: relative;
}
.nav a::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 1px;
  background: var(--accent-deep);
  transform: scaleX(0);
  transform-origin: inline-start;
  transition: transform var(--dur) var(--ease);
}
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }

.header__actions { display: flex; align-items: center; gap: var(--sp-1); margin-inline-start: auto; }
@media (min-width: 1000px) { .header__actions { margin-inline-start: 0; } }
.header__cta { display: none; }
@media (min-width: 1200px) { .header__cta { display: inline-flex; margin-inline-start: var(--sp-3); } }

.cart-btn { position: relative; }
.cart-btn__count {
  position: absolute;
  inset-block-start: 4px; inset-inline-end: 2px;
  min-inline-size: 17px; block-size: 17px;
  display: grid; place-items: center;
  padding-inline: 4px;
  background: var(--accent);
  color: var(--ink);
  font-size: 10px; font-weight: var(--fw-bold);
  border-radius: 9px;
  font-variant-numeric: tabular-nums;
}
.menu-btn { display: inline-flex; }
@media (min-width: 1000px) { .menu-btn { display: none; } }


/* ==========================================================================
   4. MOBILE MENU + CART DRAWER — one panel component, two instances
   ========================================================================== */

.scrim {
  position: fixed; inset: 0;
  background: rgba(12, 11, 10, .48);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur) var(--ease);
  z-index: var(--z-drawer);
}
.scrim.is-open { opacity: 1; pointer-events: auto; }

.panel {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  inline-size: min(420px, 100%);
  background: var(--bg);
  z-index: calc(var(--z-drawer) + 1);
  display: flex; flex-direction: column;
  transform: translate3d(100%, 0, 0);
  transition: transform var(--dur-slow) var(--ease-out);
  border-inline-start: 1px solid var(--line);
}
[dir="rtl"] .panel { transform: translate3d(-100%, 0, 0); }
.panel.is-open { transform: none; }
.panel--start { inset-inline: 0 auto; border-inline: 0 1px solid var(--line); transform: translate3d(-100%, 0, 0); }
[dir="rtl"] .panel--start { transform: translate3d(100%, 0, 0); }
.panel--start.is-open { transform: none; }

.panel__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-block-end: 1px solid var(--line);
  flex: none;
}
.panel__body { flex: 1; overflow-y: auto; padding: var(--sp-5); }
.panel__foot {
  flex: none;
  padding: var(--sp-5);
  border-block-start: 1px solid var(--line);
  background: var(--surface);
  padding-block-end: max(var(--sp-5), env(safe-area-inset-bottom));
}
.panel__nav { display: flex; flex-direction: column; }
.panel__nav a {
  padding-block: var(--sp-4);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  letter-spacing: var(--tr-h4);
  text-decoration: none;
  border-block-end: 1px solid var(--line);
}


/* ==========================================================================
   5. TRUST ROW + STARS + BADGES
   ========================================================================== */

.trust-row {
  display: flex; flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-4) var(--sp-6);
}
.trust-row__item {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.band .trust-row__item { color: var(--on-band-soft); }
.trust-row__item svg { inline-size: 16px; block-size: 16px; color: var(--accent-deep); flex: none; }
.band .trust-row__item svg { color: var(--accent); }

.stars { display: inline-flex; gap: 2px; color: var(--accent); flex: none; }
.stars i { display: inline-flex; }
.stars i.is-off { color: color-mix(in srgb, currentColor 22%, transparent); }
.stars svg { inline-size: 15px; block-size: 15px; }
.stars--lg svg { inline-size: 19px; block-size: 19px; }
/* Trustpilot renders stars as filled squares — this matches that convention
   so the widget reads as authentically third-party. */
.tp-stars { display: inline-flex; gap: 3px; flex: none; }
.tp-stars i {
  inline-size: 22px; block-size: 22px;
  background: #00B67A;
  display: grid; place-items: center;
  border-radius: 1px;
}
.tp-stars i svg { inline-size: 15px; block-size: 15px; color: #fff; }
.tp-stars i.is-half { background: linear-gradient(90deg, #00B67A 50%, #DCDCE6 50%); }
.tp-stars i.is-off { background: #DCDCE6; }

.badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: 5px var(--sp-3);
  background: var(--accent);
  color: var(--ink);
  font-size: 10px; font-weight: var(--fw-bold);
  letter-spacing: .13em; text-transform: uppercase;
  border-radius: var(--radius);
}
.badge--quiet { background: var(--surface-2); color: var(--ink-soft); }
.badge--outline { background: none; border: 1px solid var(--line-strong); color: var(--ink-soft); }


/* ==========================================================================
   6. PRODUCT CARD + THE CARD ROW
   Note the auto margin on the CTA: every card's button lands on one visual
   line across a grid row regardless of title length above it. (§5B.3)
   ========================================================================== */

/* The row. A peek carousel on mobile, a grid from 700px.
   One card fills the column and the next shows about 20% — which is the
   clearest possible signal that the row scrolls, clearer than an arrow, and
   it needs no JavaScript at all. Below 700px a four-up grid would give four
   cards nobody can read; a two-up gives eight thumbnails. */
/* Two per row on a phone (owner, 10 Aug). This used to be a swipe track with
   one 85%-wide card and a peek of the next; two-up shows the whole range at a
   glance and needs no gesture to discover the fourth product. */
.cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-3);
}

@media (min-width: 700px) {
  .cards { gap: var(--sp-5); }
}
@media (min-width: 1000px) {
  .cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .cards--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (prefers-reduced-motion: reduce) { .cards { scroll-behavior: auto; } }

.card {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color var(--dur) var(--ease);
}
.card:hover { border-color: var(--line-strong); }

/* The whole card is the tap target, not the 22px title link.
   Mobile carries 77% of impressions and ranks five positions better than
   desktop, so a card-sized target beats a line-of-text target by a wide
   margin. The CTA and the flag are lifted above the overlay so they stay
   independently clickable — and the title link remains the accessible name
   for the card, which a wrapping <a> around block content would not be. */
.card__title a::after { content: ""; position: absolute; inset: 0; }
.card__cta, .card__flag, .card form { position: relative; z-index: 1; }

.card__media {
  position: relative;
  /* Square, not 4:5 — the taller box made every packshot read oversized and
     pushed the buy bar below the fold on phones (owner, 2026-08-03). */
  aspect-ratio: 1 / 1;
  background: var(--surface-2);
  display: grid; place-items: center;
  overflow: hidden;
  border-block-end: 1px solid var(--line);
}
.card__media::before {
  content: "";
  position: absolute;
  inline-size: 82%; aspect-ratio: 1;
  background: radial-gradient(circle,
    rgba(253,185,19,.38),
    rgba(253,185,19,.10) 46%,
    rgba(253,185,19,0) 70%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.card:hover .card__media::before { transform: scale(1.08); }
.card__media img {
  position: relative;
  inline-size: 68%;
  max-block-size: 80%;
  object-fit: contain;
  filter: drop-shadow(var(--shadow-product));
  transition: transform var(--dur-slow) var(--ease-out);
}
.card:hover .card__media img { transform: scale(1.045); }
/* Photo variant: the live WooCommerce packshots ship on solid white, so the
   media box goes white and the image fills it — no glow, no drop-shadow, or
   the white square would read as a sticker on the stone panel. */
.card__media--photo { background: #fff; }
.card__media--photo::before { display: none; }
.card__media--photo img { inline-size: 92%; max-block-size: 92%; filter: none; }
.card__flag { position: absolute; inset-block-start: var(--sp-4); inset-inline-start: var(--sp-4); }
@media (max-width: 699px) {
  .card__flag { inset-block-start: var(--sp-2); inset-inline-start: var(--sp-2); font-size: 9px; padding: 2px 7px; }
}

.card__body {
  display: flex; flex-direction: column;
  flex: 1;
  padding: var(--sp-5);
  gap: var(--sp-3);
}
.card__title { font-size: var(--fs-h4); letter-spacing: var(--tr-h4); line-height: 1.28; }
.card__title a { text-decoration: none; }
.card:hover .card__title a { color: var(--accent-deep); }

/* Kicker strip under the photo (owner's reference, 3 Aug): micro caps in
   bronze on a hairline — a one-line positioning statement per product, not a
   spec dump. */
.card__kicker {
  padding: var(--sp-3) var(--sp-5);
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-deep);
  /* Exactly ONE line on every card — a wrapping kicker pushes the title,
     description and rating rows out of alignment across the whole grid. The
     copy is written to fit; the ellipsis is the guard, not the plan. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* On the photo, bottom-left (owner, 5 Aug) — a small label chip over the
   image rather than a strip between image and body. */
.card__kicker--onmedia {
  position: absolute;
  inset-block-end: var(--sp-3);
  inset-inline-start: var(--sp-3);
  z-index: 1;
  margin: 0;
  padding: 5px var(--sp-3);
  max-inline-size: calc(100% - var(--sp-6));
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 9.5px;
  letter-spacing: .1em;
}

/* Items inside a swipe track NEVER reveal-animate: sliding a card into view
   while it is still translating upward reads as the whole carousel shaking. */
.cards > .reveal, .benefits > .reveal { opacity: 1; transform: none; transition: none; }

/* Dot pagination for the CSS-only swipe tracks on phones. Built by main.js
   only when the track actually scrolls; the grid breakpoints hide it. */
.snap-dots { display: flex; justify-content: center; gap: var(--sp-2); padding-block-start: var(--sp-4); }
.snap-dots button {
  inline-size: 8px; block-size: 8px;
  padding: 0; border: 0; cursor: pointer;
  border-radius: 999px;
  background: var(--line-strong);
  transition: background-color var(--dur) var(--ease), inline-size var(--dur) var(--ease);
}
.snap-dots button[aria-current="true"] { inline-size: 20px; background: var(--accent-deep); }
@media (min-width: 700px) { .snap-dots { display: none; } }

/* Loop clones (main.js makeLoop) only exist for the swipe layouts. On the
   grid breakpoints the cards/benefits tracks stop scrolling, so the clones
   would render as duplicate items — hide them there. */
@media (min-width: 700px) {
  .cards > .is-clone,
  .benefits > .is-clone,
  .shop-strip > .is-clone,
  .checks--strip > .is-clone,
  .posts-slider > .is-clone { display: none; }
}
/* The comparison rail keeps its own breakpoint (800px). */
@media (min-width: 800px) { .vs > .is-clone { display: none; } }

/* Perks: swipe on touch, drag on desktop, no dots (owner, 9 Aug). */
.perks--tiles + .snap-dots { display: none; }

/* A rail being dragged must not select text or fire the click underneath. */
.is-dragging { cursor: grabbing; user-select: none; }
.is-dragging * { pointer-events: none; }

/* The standing pack offer, on every product card. */
.card__offer {
  align-self: flex-start;
  margin-block-start: var(--sp-2);
  padding: 3px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 20%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .02em;
  color: var(--ink);
}

/* Title row: name left, size chip right. The chip is the amber capsule from
   the reference, in our tokens. */
.card__titlerow {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-3);
}
.card__size {
  flex: none;
  padding: 3px var(--sp-2);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
  border-radius: var(--radius);
  font-size: var(--fs-micro);
  font-weight: var(--fw-bold);
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Three lines are RESERVED whether the copy uses two or three, so the rating
   row and buy bar sit at identical heights across the whole grid. */
.card__desc { font-size: var(--fs-small); color: var(--ink-soft); line-height: 1.5; min-block-size: 4.5em; }

/* Kept for non-card uses (comparison contexts). */
.card__meta {
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.5;
}
/* The rating row is pinned to the bottom stack (rating → buy bar), so
   different description lengths breathe mid-card and every card's last two
   rows still align across the grid. */
.card__rate { display: inline-flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-small); color: var(--ink-soft); margin-block-start: auto; }

/* The combined buy bar: label left, price capsule right, inside ONE primary
   button. Height, font and radius still come from .btn (§5B.2 single primary
   signature); the inline padding and tracking are tightened here because this
   is the only .btn that carries TWO pieces of content, and the reference bar
   is edge-to-edge in the card. The price capsule may never escape the button:
   the label is the flexible part, the capsule is not. */
.card__cta { inline-size: 100%; }
.btn--buy {
  justify-content: space-between;
  inline-size: 100%;
  padding-inline: var(--sp-4);
  gap: var(--sp-2);
  letter-spacing: .08em;
}
.btn--buy__label {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.btn--buy__plus { font-size: var(--fs-h4); font-weight: var(--fw-head); line-height: 1; flex: none; }
.btn--buy__price {
  flex: none;
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  padding: 4px var(--sp-2);
  background: var(--ink);
  color: var(--accent);
  border-radius: var(--radius);
  font-variant-numeric: tabular-nums;
}
.btn--buy__from { font-size: 9px; letter-spacing: .08em; opacity: .75; }

/* Price sits on its own hairline, directly above the CTA, so the eye runs
   title → spec → rating → price → button in one column every time. */
.card__price-row {
  margin-block-start: auto;
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line);
}

.price { display: inline-flex; align-items: baseline; gap: var(--sp-2); font-weight: var(--fw-head); letter-spacing: -.01em; }
.price__now { font-size: var(--fs-h3); letter-spacing: var(--tr-h3); }
.price__was { font-size: var(--fs-small); color: var(--ink-soft); text-decoration: line-through; font-weight: var(--fw-body); }
.price__unit {
  font-size: var(--fs-micro);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: var(--fw-head);
}

/* The line that guarantees CTA alignment across a row. With .card__price-row
   present the auto margin lives there instead, which keeps BOTH the price and
   the button on one visual line across the row. */
.card__cta { margin-block-start: auto; padding-block-start: var(--sp-4); }
.card__price-row ~ .card__cta { margin-block-start: 0; }
.card__cta .btn { inline-size: 100%; }


/* ==========================================================================
   7. CAROUSEL — one component, used by reviews and video reviews
   Native scroll-snap: no library, works without JS, keyboard accessible,
   and the arrows are progressive enhancement rather than the only control.
   ========================================================================== */

.carousel { position: relative; }

.carousel__viewport {
  display: flex;
  gap: var(--sp-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding-block-end: var(--sp-2);
  /* Bleed to the viewport edge on mobile so cards feel continuous, while
     the first card still aligns to the container. */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scroll-padding-inline-start: var(--gutter);
}
.carousel__viewport::-webkit-scrollbar { display: none; }
.carousel__item { scroll-snap-align: start; flex: none; }

.carousel__nav { display: flex; gap: var(--sp-3); }
.carousel__nav .icon-btn {
  border: 1px solid var(--line-strong);
  inline-size: 44px; block-size: 44px;
}
.carousel__nav .icon-btn:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.band .carousel__nav .icon-btn { border-color: var(--band-line); color: var(--on-band); }
.band .carousel__nav .icon-btn:hover { background: var(--accent); color: var(--ink); border-color: var(--accent); }
.carousel__nav .icon-btn[disabled] { opacity: .3; }

/* Progress rail — replaces dots. Reads as an editorial detail, not a widget. */
.carousel__rail {
  block-size: 2px;
  background: var(--line);
  position: relative;
  margin-block-start: var(--sp-5);
  overflow: hidden;
}
.carousel__rail span {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  background: var(--ink);
  transition: transform var(--dur) var(--ease), inline-size var(--dur) var(--ease);
}
.band .carousel__rail { background: var(--band-line); }
.band .carousel__rail span { background: var(--accent); }


/* ==========================================================================
   8. REVIEW CARD — Trustpilot convention
   ========================================================================== */

.review {
  display: flex; flex-direction: column;
  gap: var(--sp-4);
  inline-size: 300px;
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
@media (min-width: 700px) { .review { inline-size: 340px; } }
.review__quote { font-size: var(--fs-body); line-height: 1.55; }
.review__quote strong { font-weight: var(--fw-head); }
.review__foot {
  margin-block-start: auto;
  padding-block-start: var(--sp-4);
  border-block-start: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
}
.review__who { font-size: var(--fs-small); font-weight: var(--fw-head); }
.review__when { font-size: var(--fs-small); color: var(--ink-soft); }
.review__verified {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: var(--fs-micro); letter-spacing: .1em; text-transform: uppercase;
  font-weight: var(--fw-head); color: var(--ok);
}
.review__verified svg { inline-size: 13px; block-size: 13px; }

/* Trustpilot-style aggregate block */
.tp-summary {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sp-4) var(--sp-6);
  padding: var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.tp-summary__score { display: flex; align-items: center; gap: var(--sp-4); }
.tp-summary__num { font-size: 34px; font-weight: var(--fw-head); letter-spacing: -.03em; line-height: 1; }
.tp-summary__stat { display: flex; flex-direction: column; gap: 2px; }
.tp-summary__stat b { font-size: var(--fs-h4); font-weight: var(--fw-head); letter-spacing: -.02em; }
.tp-summary__stat span { font-size: var(--fs-micro); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.tp-summary__div { inline-size: 1px; align-self: stretch; background: var(--line); }
@media (max-width: 767px) { .tp-summary__div { display: none; } }


/* ==========================================================================
   9. VIDEO CARD — the centre item is deliberately larger
   ========================================================================== */

.vid {
  position: relative;
  /* Two videos per screen at every width (owner, 12 Aug). */
  inline-size: calc((100vw - 2 * var(--gutter) - var(--sp-4)) / 2);
  flex: none;
  aspect-ratio: 9 / 16;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface-2);
  transition: transform var(--dur) var(--ease);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: transform var(--dur-slow) var(--ease-out),
              border-color var(--dur) var(--ease);
}
/* Desktop: five-up rail where the CENTRE card is clearly the big one and
   its neighbours sit smaller (owner, 13 Aug — reference screenshot). The
   track gets vertical padding so the scaled-up card never clips. Mobile
   keeps the mandated two-up with no scaling. */
@media (min-width: 700px) {
  [data-carousel="vids"] [data-viewport],
  .vids__viewport { padding-block: var(--sp-6); }
  .vid {
    inline-size: calc((100vw - 2 * var(--gutter) - 4 * var(--sp-4)) / 5);
    transform: scale(0.88);
    opacity: 0.8;
  }
  .vid.is-near { transform: scale(0.96); opacity: 0.95; }
  .vid.is-center { transform: scale(1.06); opacity: 1; z-index: 1; }
}

.vid video, .vid img { inline-size: 100%; block-size: 100%; object-fit: cover; }
.vid:hover { border-color: var(--line-strong); }

/* Click-to-play: the inline player element replaces the poster button in the
   same box, so no video bytes load until someone actually presses play. */
video.vid--playing { background: #0C0B0A; object-fit: cover; }
.vid__overlay {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(12,11,10,0) 38%, rgba(12,11,10,.62) 70%, rgba(12,11,10,.92) 100%);
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: var(--sp-4);
  gap: var(--sp-2);
  pointer-events: none;
}
.vid__name { color: var(--on-band); font-size: var(--fs-small); font-weight: var(--fw-head); }
.vid__loc  { color: #C8C1B8; font-size: var(--fs-micro); letter-spacing: .1em; text-transform: uppercase; }
.vid__play {
  position: absolute;
  inset-block-start: 50%; inset-inline-start: 50%;
  transform: translate(-50%, -50%);
  inline-size: 52px; block-size: 52px;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--ink);
  border-radius: 50%;
  transition: transform var(--dur) var(--ease);
}
.vid:hover .vid__play { transform: translate(-50%, -50%) scale(1.08); }
.vid__play svg { inline-size: 18px; block-size: 18px; margin-inline-start: 2px; }


/* ==========================================================================
   10. ACCORDION — FAQ, PDP tabs and policy pages all use THIS. Three
   separate accordions would drift within a month.
   ========================================================================== */

.acc { border-block-start: 1px solid var(--line); }
.acc__item { border-block-end: 1px solid var(--line); }
.acc__trigger {
  inline-size: 100%;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-5);
  padding-block: var(--sp-5);
  background: none; border: 0;
  font-family: var(--font);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  letter-spacing: var(--tr-h4);
  line-height: 1.35;
  color: var(--ink);
  text-align: start;
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}
.acc__trigger:hover { color: var(--accent-deep); }
.acc__icon {
  flex: none;
  inline-size: 22px; block-size: 22px;
  position: relative;
  color: var(--accent-deep);
}
.acc__icon::before, .acc__icon::after {
  content: ""; position: absolute;
  inset-block-start: 50%; inset-inline-start: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.acc__icon::before { inline-size: 13px; block-size: 1.5px; }
.acc__icon::after  { inline-size: 1.5px; block-size: 13px; }
.acc__trigger[aria-expanded="true"] .acc__icon::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }
.acc__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--dur-slow) var(--ease-out); }
.acc__panel[data-open="true"] { grid-template-rows: 1fr; }
.acc__panel > div { overflow: hidden; }
.acc__panel .prose { padding-block-end: var(--sp-5); color: var(--ink-soft); }
.band .acc, .band .acc__item { border-color: var(--band-line); }
.band .acc__trigger { color: var(--on-band); }
.band .acc__icon { color: var(--accent); }


/* ==========================================================================
   11. FORM FIELD — identical on contact, checkout, account, newsletter
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field__label {
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.field__input, .field__textarea, .field__select {
  block-size: var(--input-h);            /* equal to --btn-h, deliberately */
  inline-size: 100%;
  padding-inline: var(--sp-4);
  font-family: var(--font);
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease);
}
.field__textarea { block-size: auto; padding-block: var(--sp-3); resize: vertical; min-block-size: 132px; }
.field__input:hover, .field__textarea:hover { border-color: var(--ink-soft); }
.field__input::placeholder, .field__textarea::placeholder { color: #9C948A; }
.field__hint { font-size: var(--fs-small); color: var(--ink-soft); }
/* Errors sit next to the field, never only at the top of the form, and
   never rely on colour alone. */
.field__error { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-small); color: var(--err); font-weight: var(--fw-med); }
.field__error svg { inline-size: 14px; block-size: 14px; flex: none; }
.field.has-error .field__input, .field.has-error .field__textarea { border-color: var(--err); }

/* --- Checkbox ------------------------------------------------------------
   Real input, visually replaced by a drawn box so its checked state cannot
   drift from what is rendered. 44px row, label clickable across its width. */

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 44px;
  cursor: pointer;
  font-size: var(--fs-small);
}
.checkbox input {
  position: absolute;
  inline-size: 1px; block-size: 1px;
  opacity: 0; margin: 0; pointer-events: none;
}
.checkbox__box {
  flex: none;
  inline-size: 20px; block-size: 20px;
  display: grid; place-items: center;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.checkbox__box svg {
  inline-size: 13px; block-size: 13px;
  color: var(--ink);
  transform: scale(0);
  transition: transform var(--dur) var(--ease);
}
.checkbox:hover .checkbox__box { border-color: var(--ink-soft); }
.checkbox:has(input:checked) .checkbox__box { background: var(--accent); border-color: var(--accent); }
.checkbox:has(input:checked) .checkbox__box svg { transform: scale(1); }
.checkbox:has(input:focus-visible) .checkbox__box { outline: 2px solid var(--accent-deep); outline-offset: 2px; }


/* --- Wallet buttons -------------------------------------------------------
   Apple Pay, Google Pay, PayPal. Deliberately NOT .btn — these are the payment
   provider's own branded controls, not ours, and giving them our button class
   would put a fifth signature into the §5B.2 audit for something we do not
   control the rendering of anyway. In production the provider replaces each
   one with its own element. */

.wallets { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-3); }
@media (max-width: 479px) { .wallets { grid-template-columns: 1fr; } }

.wallet {
  block-size: 48px;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--sp-2);
  padding-inline: var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: var(--fs-small);
  font-weight: var(--fw-head);
  color: var(--ink);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}
.wallet:hover { border-color: var(--ink-soft); background: var(--surface); }


.inline-form { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.inline-form .field { flex: 1 1 220px; }
/* Bottom-aligned so the input and the button sit on one baseline — the input
   is 48px precisely so it matches the button it stands next to. */
.inline-form .btn { flex: none; align-self: flex-end; }
@media (max-width: 479px) { .inline-form .btn { inline-size: 100%; } }


/* ==========================================================================
   11B. OPTION SET — size selector, pack ladder AND subscribe toggle
   ONE component, three modifiers. The subscribe toggle looked like a fourth
   component until you write it down: it is two mutually exclusive priced
   options, which is exactly what the pack ladder is. Building it separately
   would have given us two things to keep in sync forever. (§5B.5)

   Real radio inputs, visually hidden but focusable, so the whole thing works
   with JavaScript off and arrow keys move between options for free.
   ========================================================================== */

/* A fieldset groups the radios for assistive tech; its default border,
   padding and min-width are all removed so it lays out like a plain div. */
.optset-wrap { border: 0; padding: 0; margin: 0; min-inline-size: 0; }
.optset-wrap legend { padding: 0; margin-block-end: var(--sp-3); }

.optset { display: grid; gap: var(--sp-3); }
.optset--size { grid-template-columns: repeat(3, 1fr); }

.optset__opt {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-block-size: 44px;                 /* touch target, always */
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease),
              background-color var(--dur) var(--ease);
}
.optset__opt:hover { border-color: var(--ink-soft); }

.optset--size .optset__opt {
  justify-content: center;
  padding-inline: var(--sp-3);
  gap: var(--sp-2);
}

/* Hidden from sight, not from the keyboard or the accessibility tree. */
.optset__opt input {
  position: absolute;
  inline-size: 1px; block-size: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

/* The radio mark is drawn, so its selected state cannot drift from the
   container's. Hidden on the compact size row, where the fill says it. */
.optset__mark {
  flex: none;
  inline-size: 18px; block-size: 18px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  display: grid; place-items: center;
  transition: border-color var(--dur) var(--ease);
}
.optset__mark::after {
  content: "";
  inline-size: 9px; block-size: 9px;
  border-radius: 50%;
  background: var(--accent);
  transform: scale(0);
  transition: transform var(--dur) var(--ease);
}
.optset--size .optset__mark { display: none; }

.optset__opt:has(input:checked) { border-color: var(--ink); background: var(--accent-wash); }
.optset__opt:has(input:checked) .optset__mark { border-color: var(--ink); }
.optset__opt:has(input:checked) .optset__mark::after { transform: scale(1); }

/* Focus lives on the label because the input itself is 1px. Same ring as
   every other interactive element on the site. */
.optset__opt:has(input:focus-visible) {
  outline: 2px solid var(--accent-deep);
  outline-offset: 2px;
}

.optset__opt:has(input:disabled) { opacity: .4; cursor: not-allowed; }

.optset__label { display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
.optset__label b { font-size: var(--fs-body); font-weight: var(--fw-head); letter-spacing: -.01em; }
.optset__label > span { font-size: var(--fs-small); color: var(--ink-soft); }

/* One thumbnail per unit delivered. Four jars for the price of three is much
   easier to see than to read, and this is the only place on the site where a
   repeated image carries information rather than decoration. */
.optset__thumbs {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin-block-start: var(--sp-2);
  flex-wrap: wrap;
}
.optset__thumbs img {
  inline-size: 26px;
  block-size: 26px;
  object-fit: contain;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.optset__opt:has(input:checked) .optset__thumbs img { border-color: var(--line-strong); }

/* Price block sits at the end of the line. The PER-UNIT figure is what makes
   the ladder legible — without it the customer does the arithmetic in their
   head and defaults to the cheapest tier. It is not optional. */
.optset__price { margin-inline-start: auto; text-align: end; flex: none; }
.optset__price b { display: block; font-size: var(--fs-body); font-weight: var(--fw-head); letter-spacing: -.01em; }
.optset__price span { display: block; font-size: var(--fs-small); color: var(--ink-soft); }
.optset__price s { color: var(--ink-soft); font-weight: var(--fw-body); }


/* ==========================================================================
   11C. QUANTITY STEPPER
   ========================================================================== */

.qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  block-size: var(--input-h);           /* equal to a button, deliberately */
  overflow: hidden;
}
.qty__btn {
  inline-size: 44px;
  block-size: 100%;
  display: grid; place-items: center;
  background: none; border: 0; padding: 0;
  font-family: var(--font);
  font-size: var(--fs-h4);
  font-weight: var(--fw-head);
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--dur) var(--ease);
}
.qty__btn:hover { background: var(--surface-2); }
.qty__btn[disabled] { opacity: .35; cursor: not-allowed; }
.qty__input {
  inline-size: 48px;
  block-size: 100%;
  padding: 0;
  text-align: center;
  font-family: var(--font);
  font-size: var(--fs-body);
  font-weight: var(--fw-head);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  background: none;
  border: 0;
  border-inline: 1px solid var(--line);
  -moz-appearance: textfield;
}
.qty__input::-webkit-outer-spin-button,
.qty__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }


/* ==========================================================================
   12. NOTICE, TABLE, BREADCRUMB, PROGRESS, MEDIA SLOT
   ========================================================================== */

.notice {
  display: flex; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border: 1px solid var(--line-strong);
  border-inline-start: 3px solid var(--accent-deep);
  border-radius: var(--radius);
  background: var(--accent-wash);
  font-size: var(--fs-small);
}
.notice svg { inline-size: 18px; block-size: 18px; flex: none; color: var(--accent-deep); }

.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); }
.table { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-small); background: var(--surface); }
.table th, .table td { padding: var(--sp-4) var(--sp-5); text-align: start; border-block-end: 1px solid var(--line); }
.table th {
  font-size: var(--fs-micro); letter-spacing: .12em; text-transform: uppercase;
  font-weight: var(--fw-bold); color: var(--ink-soft); background: var(--surface-2);
  white-space: nowrap;
}
.table tr:last-child td { border-block-end: 0; }
/* A link filling a data cell is a standalone control, not an inline one, so it
   carries a full target. The cell is already ~50px tall, so this costs no
   density — it just makes the tappable area match what the eye sees. */
.table a { display: inline-flex; align-items: center; min-block-size: 44px; }

.crumb { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); font-size: var(--fs-small); color: var(--ink-soft); }
.crumb a { text-decoration: none; }
/* The separator is decorative and aria-hidden, so WCAG does not apply to it —
   but at --line-strong it measured 1.58:1 and was effectively invisible.
   Legible beats technically-exempt. */
.crumb span[aria-hidden] { color: var(--ink-soft); opacity: .5; }

.progress { block-size: 4px; background: var(--surface-2); border-radius: 2px; overflow: hidden; }
.progress span { display: block; block-size: 100%; background: var(--accent); transition: inline-size var(--dur-slow) var(--ease-out); }

/* Where a real photo or video is still pending. NEVER fill these with
   stock imagery (§5 rule 5) — an honest labelled gap is the point. */
.media-slot {
  display: grid;
  place-items: center;
  align-content: center;     /* pack the two rows together, not spread apart */
  gap: var(--sp-2);
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  color: var(--ink-soft);
  text-align: center;
  padding: var(--sp-5);
}
.media-slot b { font-size: var(--fs-micro); letter-spacing: .14em; text-transform: uppercase; }
.media-slot span { font-size: var(--fs-small); max-inline-size: 30ch; }

/* Filled slot: a real photo replaces the dashed placeholder. Same box, same
   aspect ratio, so nothing shifts when the owner uploads the image. */
.media-slot--filled {
  display: block;
  padding: 0;
  margin: 0;
  border: 1px solid var(--line);
  overflow: hidden;
}
.media-slot--filled img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}


/* ==========================================================================
   13. FOOTER
   ========================================================================== */

.footer { background: var(--band); color: var(--on-band-soft); }
.footer a { color: var(--on-band-soft); text-decoration: none; }
.footer a:hover { color: var(--accent); }

.footer__top { padding-block: var(--sp-8) var(--sp-7); border-block-end: 1px solid var(--band-line); }
@media (min-width: 768px) { .footer__top { padding-block: var(--sp-9) var(--sp-8); } }

.footer__grid { display: grid; gap: var(--sp-7); grid-template-columns: 1fr; }
@media (min-width: 700px)  { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .footer__grid { grid-template-columns: 1.6fr repeat(3, 1fr); gap: var(--sp-8); } }

.footer__brand img { block-size: 40px; inline-size: auto; margin-block-end: var(--sp-4); }
.footer__brand p { max-inline-size: 36ch; }
.footer__col h2 { color: var(--on-band); font-size: var(--fs-micro); letter-spacing: var(--tr-micro); text-transform: uppercase; margin-block-end: var(--sp-4); }
.footer__col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.footer__col li { font-size: var(--fs-small); }
.footer__col li a { display: inline-flex; align-items: center; min-block-size: 44px; }

/* Offices row: manufacturing, US, UK, and how to reach a person. */
.footer__offices {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--sp-6);
  padding-block: var(--sp-6);
  border-block-start: 1px solid var(--band-line);
}
@media (min-width: 700px)  { .footer__offices { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .footer__offices { grid-template-columns: repeat(4, 1fr); gap: var(--sp-7); } }
.footer__office h2 {
  color: var(--on-band);
  font-size: var(--fs-micro);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  margin-block-end: var(--sp-3);
}
.footer__office p { line-height: 1.7; }

.footer__bottom {
  padding-block: var(--sp-5);
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sp-4);
  font-size: var(--fs-small);
}
.footer__legal { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); }
/* Nav links, not prose links — so they carry a full 44px target. */
.footer__legal a { display: inline-flex; align-items: center; min-block-size: 44px; }
.footer__pay { display: flex; gap: var(--sp-2); align-items: center; }
.footer__pay img, .footer__pay svg { block-size: 22px; inline-size: auto; opacity: .8; }

.footer__disclaimer {
  padding-block: var(--sp-5);
  border-block-start: 1px solid var(--band-line);
  font-size: 12px;
  line-height: 1.55;
  color: #8A827A;              /* quiet, but still AA at 12px (5.20:1).
                                  Legally required text never fails contrast. */
  max-width: 100%;
}

.social { display: flex; gap: var(--sp-2); }
.social .icon-btn { border: 1px solid var(--band-line); color: var(--on-band-soft); }
.social .icon-btn:hover { border-color: var(--accent); color: var(--accent); }


/* ==========================================================================
   14. STICKY MOBILE CTA BAR
   ========================================================================== */

.sticky-buy {
  position: fixed;
  inset-inline: 0; inset-block-end: 0;
  z-index: var(--z-header);
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4);
  padding-block-end: max(var(--sp-4), env(safe-area-inset-bottom));
  background: var(--surface);
  border-block-start: 1px solid var(--line);
  transform: translate3d(0, 100%, 0);
  transition: transform var(--dur-slow) var(--ease-out);
}
.sticky-buy.is-in { transform: none; }
.sticky-buy .btn { flex: 1; }
@media (min-width: 1000px) { .sticky-buy { display: none; } }


/* ==========================================================================
   15. PROMISE BAND — appears on every page of the site, without exception.
   Owner-mandated. This is the brand's core statement, not a decoration:
   nothing added, nothing heated, nothing synthetic.
   ========================================================================== */

.promise { border-block: 1px solid var(--line); background: var(--accent-wash); }

/* Dark variant. It triggers automatically when the promise band follows a
   dark section, which happens on most pages — the 4-Checks band sits directly
   above it on the homepage, the process page and every PDP.

   The foreground rules below are NOT optional decoration. Setting the dark
   background without them left --ink text on obsidian at 1.06:1 — invisible,
   and caught by the §5B.6 contrast pass rather than by eye, because the
   homepage happens to place this band after the hero where it never fired. */
:is(.band + .promise, .promise.is-on-band) {
  background: var(--band);
  border-color: var(--band-line);
  color: var(--on-band);
}
:is(.band + .promise, .promise.is-on-band) .promise__lead { color: var(--on-band); }
:is(.band + .promise, .promise.is-on-band) .promise__sub  { color: var(--on-band-soft); }
:is(.band + .promise, .promise.is-on-band) .promise__mark {
  background: transparent;
  border-color: var(--band-line);
  color: var(--on-band);
}
:is(.band + .promise, .promise.is-on-band) .promise__mark svg { color: var(--accent); }

.promise__inner {
  display: grid;
  gap: var(--sp-6);
  padding-block: var(--sp-7);
  align-items: center;
}
@media (min-width: 900px) {
  .promise__inner { grid-template-columns: minmax(0, 1fr) auto; gap: var(--sp-8); }
}

.promise__lead {
  font-size: var(--fs-lead);
  line-height: 1.5;
  max-width: 54ch;
  text-wrap: pretty;
}
@media (min-width: 768px) { .promise__lead { font-size: 21px; } }
.promise__lead strong { font-weight: var(--fw-head); }

.promise__sub {
  margin-block-start: var(--sp-4);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  max-width: 52ch;
}

.promise__marks { display: flex; flex-wrap: wrap; gap: var(--sp-3); }
.promise__mark {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
}
.promise__mark svg { inline-size: 15px; block-size: 15px; color: var(--accent-deep); flex: none; }


/* ==========================================================================
   18. WOO ADAPTER — WooCommerce-generated markup, dressed in the system
   --------------------------------------------------------------------------
   Cart, checkout and account render through our template overrides, but the
   FIELDS, the review-order table, the payment method list and the notices
   are still printed by WooCommerce core (that is what keeps its JS working).
   This block maps that markup onto the same tokens as .field / .optset /
   .notice. WooCommerce's own stylesheets are dequeued in inc/wc.php - this
   is the only place its selectors may appear (design contract 5B).
   ========================================================================== */

/* --- Form rows -> .field ------------------------------------------------- */

.form-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-4);
}
.form-row label {
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.form-row label .required { color: var(--err); text-decoration: none; }
.form-row .woocommerce-input-wrapper { display: block; }
.form-row input.input-text,
.form-row select,
.form-row textarea {
  block-size: var(--input-h);
  inline-size: 100%;
  padding-inline: var(--sp-4);
  font-family: var(--font);
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease);
}
.form-row textarea { block-size: auto; padding-block: var(--sp-3); min-block-size: 100px; resize: vertical; }
.form-row input.input-text:hover, .form-row select:hover, .form-row textarea:hover { border-color: var(--ink-soft); }
.form-row.woocommerce-invalid input.input-text,
.form-row.woocommerce-invalid select { border-color: var(--err); }

/* Two-up name/city rows: Woo tags them form-row-first / form-row-last. */
.co__fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--sp-4); }
.co__fields .form-row-wide, .co__fields .form-row:not(.form-row-first):not(.form-row-last) { grid-column: 1 / -1; }
@media (max-width: 479px) { .co__fields { grid-template-columns: 1fr; } }

/* --- Notices -------------------------------------------------------------- */

.woocommerce-notices-wrapper:empty { display: none; }
.woocommerce-error, .woocommerce-message, .woocommerce-info {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0 0 var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-small);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-inline-start: 3px solid var(--accent-deep);
  border-radius: var(--radius);
}
.woocommerce-error { border-inline-start-color: var(--err); }
.woocommerce-error a, .woocommerce-message a, .woocommerce-info a { color: inherit; }
.woocommerce-message .button, .woocommerce-info .button, .woocommerce-error .button { align-self: flex-start; }

/* --- Review-order table (checkout aside) ---------------------------------- */

.woocommerce-checkout-review-order-table { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.woocommerce-checkout-review-order-table thead { display: none; }  /* items are rendered by the template above the table */
.woocommerce-checkout-review-order-table .cart_item { display: none; }
.woocommerce-checkout-review-order-table th,
.woocommerce-checkout-review-order-table td {
  padding: var(--sp-3) 0;
  text-align: start;
  font-weight: var(--fw-reg);
  color: var(--ink-soft);
  border-block-start: 1px solid var(--line);
}
.woocommerce-checkout-review-order-table td:last-child,
.woocommerce-checkout-review-order-table th + td { text-align: end; color: var(--ink); }
.woocommerce-checkout-review-order-table .order-total th,
.woocommerce-checkout-review-order-table .order-total td {
  font-weight: var(--fw-head);
  color: var(--ink);
  font-size: var(--fs-body);
  border-block-start: 1px solid var(--line-strong);
}
.woocommerce-checkout-review-order-table .woocommerce-shipping-methods { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.woocommerce-checkout-review-order-table .woocommerce-shipping-methods li { display: flex; align-items: center; gap: var(--sp-2); }
.blx-total-note td, .blx-total-note th { color: var(--ink-soft); font-size: var(--fs-micro); }

/* --- Payment methods (checkout left column) -------------------------------- */

.woocommerce-checkout-payment ul.wc_payment_methods {
  list-style: none;
  margin: 0 0 var(--sp-5);
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
}
.woocommerce-checkout-payment li.wc_payment_method { border-block-start: 1px solid var(--line); }
.woocommerce-checkout-payment li.wc_payment_method:first-child { border-block-start: 0; }
.woocommerce-checkout-payment li.wc_payment_method > label {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-block-size: 52px;
  padding-inline: var(--sp-5);
  font-weight: var(--fw-med);
  font-size: var(--fs-body);
  cursor: pointer;
}
.woocommerce-checkout-payment li.wc_payment_method input.input-radio { accent-color: var(--accent-deep); inline-size: 18px; block-size: 18px; flex: none; }
.woocommerce-checkout-payment .payment_box {
  margin: 0;
  padding: var(--sp-4) var(--sp-5);
  font-size: var(--fs-small);
  color: var(--ink-soft);
  background: var(--paper);
  border-block-start: 1px solid var(--line);
}
.woocommerce-checkout-payment .payment_box p:last-child { margin-block-end: 0; }
.woocommerce-checkout-payment .place-order { margin-block-start: var(--sp-5); }
.woocommerce-terms-and-conditions-wrapper { margin-block-end: var(--sp-4); font-size: var(--fs-small); color: var(--ink-soft); }

/* --- Subscription consent box (biloraux-subscriptions) ---------------------
   Rendered by the theme templates above the payment step / under the cart
   items. The plugin's markup is fixed (title span, plain-text list, foot
   span), so the design work is all here: a proper consent card — accent
   spine, clear title, one hairline row per renewing item, quiet legal foot. */

/* Compact (owner, 12 Aug): it sits UNDER the Pay button now, so it reads as
   a quiet disclosure line, not a card competing with the button. Still plain
   sight — a renewal consent must never be hidden, only calm. */
.blx-sub-note {
  display: flex;
  flex-direction: column;
  margin-block: var(--sp-3) 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--accent-deep);
  border-radius: var(--radius);
}
.blx-sub-note__title {
  display: block;
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink);
  margin-block-end: 2px;
}
.blx-sub-note__list {
  list-style: none;
  margin: 0 0 var(--sp-2);
  padding: 0;
}
.blx-sub-note__list li {
  padding-block: 3px;
  font-size: var(--fs-micro);
  color: var(--ink);
  line-height: 1.45;
}
.blx-sub-note__foot { font-size: var(--fs-micro); color: var(--ink-soft); line-height: 1.45; }

/* --- Ship-to-different / order notes --------------------------------------- */

.woocommerce-shipping-fields h3, .woocommerce-additional-fields h3 {
  font-size: var(--fs-body);
  font-weight: var(--fw-head);
  margin-block: var(--sp-5) var(--sp-4);
}
#ship-to-different-address { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-small); }
#ship-to-different-address input { accent-color: var(--accent-deep); inline-size: 18px; block-size: 18px; }

/* --- My Account ------------------------------------------------------------
   Woo's account area in the system: nav as quiet buttons, tables as .table,
   forms as fields. Subscriptions (biloraux) render their own list here too. */

.woocommerce-MyAccount-navigation ul { list-style: none; margin: 0 0 var(--sp-6); padding: 0; display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.woocommerce-MyAccount-navigation a {
  display: inline-flex;
  align-items: center;
  min-block-size: 40px;
  padding-inline: var(--sp-4);
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
}
.woocommerce-MyAccount-navigation li.is-active a,
.woocommerce-MyAccount-navigation a:hover { background: var(--ink); color: var(--bg); border-color: var(--ink); }

.woocommerce-MyAccount-content { font-size: var(--fs-body); }
.woocommerce-MyAccount-content table { inline-size: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.woocommerce-MyAccount-content th, .woocommerce-MyAccount-content td { padding: var(--sp-3); text-align: start; border-block-end: 1px solid var(--line); }
.woocommerce-MyAccount-content .button,
.woocommerce-form-login .button, .woocommerce-form-register .button, .woocommerce-ResetPassword .button {
  display: inline-flex; align-items: center; justify-content: center;
  min-block-size: 44px; padding-inline: var(--sp-5);
  background: var(--accent); color: var(--ink);
  border: 0; border-radius: var(--radius);
  font-size: var(--fs-micro); font-weight: var(--fw-head); letter-spacing: .1em; text-transform: uppercase;
  cursor: pointer; text-decoration: none;
}
.woocommerce-form-login, .woocommerce-form-register { max-inline-size: 420px; }
@media (min-width: 900px) {
  .woocommerce-MyAccount-navigation { float: none; inline-size: auto; }
}

/* ==========================================================================
   UGC PHOTO STRIP — real customer photos under the review numbers
   (homepage) and on every PDP. One swipeable row, native snap, no controls:
   41 photos are for browsing, not for stepping through one by one.
   ========================================================================== */

.ugc { margin-block: var(--sp-5) var(--sp-6); }
.ugc__track {
  display: flex;
  gap: var(--sp-3);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  -ms-overflow-style: none;
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  padding-block: var(--sp-2);
  overscroll-behavior-x: contain;
}
.ugc__track::-webkit-scrollbar { display: none; }
.ugc__item { flex: 0 0 auto; margin: 0; scroll-snap-align: start; }
.ugc__item img {
  display: block;
  inline-size: 128px;
  block-size: 128px;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
}
@media (min-width: 900px) {
  .ugc__item img { inline-size: 152px; block-size: 152px; }
}
/* --- Two-up cards on a phone -------------------------------------------
   At 165px per card the buy bar cannot hold "Add to bag" and a price capsule
   side by side, and the generous body padding was most of the card's height.
   Below 700px the bar stacks and everything tightens. */
@media (max-width: 699px) {
  /* Claw back half the page gutter so two cards are not squeezed into 165px. */
  .cards { margin-inline: calc(var(--sp-3) * -1); }

  .cards .card__body { padding: var(--sp-3); gap: var(--sp-2); }
  .cards .card__title { font-size: 14px; line-height: 1.28; }
  /* The size chip rides on the end of the title instead of taking a row of
     its own (owner, 10 Aug) — one less line on every card. */
  .cards .card__titlerow { display: block; }
  .cards .card__title { display: inline; }
  /* Not a pill any more: as plain type it flows as part of the title and fits
     on the same line, which is the whole point. As a padded chip it was 55px
     wide and simply wrapped, costing a line rather than saving one. */
  .cards .card__size {
    display: inline;
    margin-inline-start: 5px;
    padding: 0;
    background: none;
    border: 0;
    font-size: inherit;
    font-weight: var(--fw-body);
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-soft);
    white-space: nowrap;
  }
  .cards .card__rate { font-size: var(--fs-micro); gap: 4px; }
  .cards .card__rate .stars svg { inline-size: 11px; block-size: 11px; }
  .cards .card__offer { margin-block-start: 0; font-size: 9.5px; padding: 2px 7px; }
  /* The on-image label chips hid the product on a small card (owner). */
  .cards .card__kicker--onmedia { display: none; }

}

/* --- Card price + compact buy button -------------------------------------
   The price sits above the button as plain type instead of a dark capsule
   inside it, so the button is one short line and the card carries a single
   amber element rather than three. */
/* No auto margin here: .card__rate already carries the one that pushes the
   last rows down. Two of them split the free space and the four cards stopped
   lining up with each other. */
.card__price {
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  line-height: 1;
  color: var(--ink);
}
.card__price-now { font-weight: var(--fw-bold); letter-spacing: -.01em; }
.card__price-from {
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Desktop keeps the price capsule in the bar; the standalone price line is
   for phones only. Exactly one is displayed at any width. */
.card__price { display: none; }

.btn--buy__cta-sm { display: none; }

@media (max-width: 699px) {
  .card__price { display: flex; }
  .btn--buy__price { display: none; }

  /* Back to the product's own label — "Options" — on phones too (owner,
     12 Aug); the "+" stays hidden so the short button reads clean. */
  .btn--buy__cta-sm { display: none; }
  .btn--buy__plus { display: none; }

  /* Air between the price and the button. The price sits INSIDE .card__cta,
     so the margin belongs on the price, not on the wrapper. */
  .cards .card__price { margin-block-end: var(--sp-2); }

  .btn--buy {
    justify-content: center;
    block-size: auto;
    min-block-size: 0;
    padding-block: 9px;
    padding-inline: var(--sp-2);
    gap: 5px;
    font-size: 11.5px;
    letter-spacing: .04em;
  }
  .btn--buy__label { overflow: visible; gap: 4px; }
  .btn--buy__plus { font-size: 1.15em; line-height: 1; }
  .cards .card__price { font-size: var(--fs-body); }
}

/* --- My Account v2 ---------------------------------------------------------
   Sidebar + content on desktop, chip rail on phones. The nav override in
   woocommerce/myaccount/navigation.php provides the icons; dashboard.php the
   greeting, latest order and endpoint cards; form-login.php the two-card
   sign-in. Everything below assumes those templates. */

/* Layout: Woo prints nav + content as siblings inside the entry content. */
@media (min-width: 900px) {
  .woocommerce-account .woocommerce {
    display: grid;
    grid-template-columns: 230px minmax(0, 1fr);
    gap: var(--sp-7);
    align-items: start;
  }
  .woocommerce-account .woocommerce > .woocommerce-notices-wrapper { grid-column: 1 / -1; }
  /* The login screen has no sidebar. */
  .woocommerce-account:not(.logged-in) .woocommerce { display: block; }
}

/* v3 (owner, 12 Aug): the rail is a card of its own — profile on top,
   destinations in the middle, log out separated at the bottom. */
@media (min-width: 900px) {
  .acct-nav {
    position: sticky;
    top: calc(var(--sp-6) + 60px);
    padding: var(--sp-3);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--surface);
  }
}
.acct-avatar {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 42px;
  block-size: 42px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--accent);
  font-family: var(--font-display);
  font-size: var(--fs-h4);
  font-weight: var(--fw-bold);
  line-height: 1;
}
.acct-nav__profile {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-2) var(--sp-3);
  margin-block-end: var(--sp-2);
  border-block-end: 1px solid var(--line);
}
.acct-nav__who { min-inline-size: 0; }
.acct-nav__who b { display: block; font-size: var(--fs-small); line-height: 1.3; }
.acct-nav__who span {
  display: block;
  font-size: var(--fs-micro);
  color: var(--ink-soft);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Log out lives apart from the destinations — leaving is not a destination. */
.acct-nav .acct-nav__logout { margin-block-start: var(--sp-2); padding-block-start: var(--sp-2); border-block-start: 1px solid var(--line); }
.acct-nav .acct-nav__logout a { color: var(--ink-soft); }
@media (max-width: 899px) {
  .acct-nav__profile { display: none; }
  .acct-nav .acct-nav__logout { margin: 0; padding: 0; border: 0; }
}

.acct-nav ul { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.acct-nav a {
  display: flex; align-items: center; gap: var(--sp-3);
  min-block-size: 42px; padding-inline: var(--sp-3);
  border: 0; border-radius: var(--radius);
  font-size: var(--fs-small); font-weight: var(--fw-med);
  letter-spacing: 0; text-transform: none;
  color: var(--ink-soft); text-decoration: none;
}
.acct-nav a { transition: background var(--dur) var(--ease), color var(--dur) var(--ease); }
.acct-nav a:hover { background: var(--surface-2); color: var(--ink); }
.acct-nav li.is-active a {
  background: var(--accent-wash); color: var(--ink); font-weight: var(--fw-head);
  box-shadow: inset 3px 0 0 var(--accent);
}
.acct-nav__icon { display: inline-flex; color: var(--accent-deep); }
.acct-nav__icon svg { inline-size: 17px; block-size: 17px; }

@media (max-width: 899px) {
  .acct-nav ul {
    flex-direction: row; flex-wrap: nowrap; overflow-x: auto;
    gap: var(--sp-2); padding-block-end: var(--sp-2); margin-block-end: var(--sp-5);
    scrollbar-width: none;
  }
  .acct-nav ul::-webkit-scrollbar { display: none; }
  .acct-nav a { flex: none; border: 1px solid var(--line-strong); }
  .acct-nav li.is-active a { box-shadow: none; border-color: var(--ink); }
}

/* Dashboard */
.acct-hello {
  display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap;
  margin-block-end: var(--sp-5);
  padding: var(--sp-5);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--line));
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg, var(--accent-wash), var(--surface) 70%);
}
.acct-hello__text { flex: 1 1 auto; min-inline-size: 0; }
.acct-hello > .btn { margin-inline-start: auto; }
.acct-avatar--lg { inline-size: 52px; block-size: 52px; font-size: var(--fs-h3); }
.acct-hello__title { font-size: var(--fs-h3); margin: 0; }
.acct-hello__meta { font-size: var(--fs-small); color: var(--ink-soft); margin-block-start: 2px; }
.acct-hello__meta a { color: var(--accent-deep); margin-inline-start: var(--sp-2); }

.acct-order {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); padding: var(--sp-4);
  margin-block-end: var(--sp-5);
}
.acct-order__head { display: flex; justify-content: space-between; align-items: center; margin-block-end: var(--sp-3); }
.acct-order__status {
  font-size: var(--fs-micro); font-weight: var(--fw-head);
  letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px;
  background: var(--surface-2); color: var(--ink-soft);
}
.acct-order__status--completed { background: color-mix(in srgb, var(--accent) 25%, var(--surface)); color: var(--ink); }
.acct-order__status--processing { background: var(--accent-wash); color: var(--accent-deep); }
.acct-order__items { display: flex; gap: var(--sp-2); margin-block-end: var(--sp-3); }
.acct-order__thumb {
  inline-size: 56px; block-size: 56px;
  object-fit: cover;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.acct-order__row { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }
.acct-order__actions { display: flex; gap: var(--sp-3); }
.acct-order--empty { text-align: center; padding-block: var(--sp-6); }
.acct-order--empty p { margin-block-end: var(--sp-4); color: var(--ink-soft); }

.acct-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-3); }
@media (min-width: 700px) { .acct-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.acct-card {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface);
  text-decoration: none; color: inherit;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.acct-card:hover {
  border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
  box-shadow: 0 6px 18px rgba(26, 22, 12, .07);
  transform: translateY(-2px);
}
.acct-card:hover .acct-card__go { color: var(--ink); transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .acct-card, .acct-card__go { transition: none; }
  .acct-card:hover { transform: none; }
}
.acct-card b { display: block; font-size: var(--fs-body); }
.acct-card__desc { display: block; font-size: var(--fs-small); color: var(--ink-soft); margin-block-start: 1px; }
.acct-card__icon {
  flex: none; inline-size: 44px; block-size: 44px;
  display: grid; place-items: center;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  background: var(--accent-wash); color: var(--accent-deep);
  border-radius: var(--radius);
}
.acct-card__icon svg { inline-size: 18px; block-size: 18px; }
.acct-card__go { margin-inline-start: auto; color: var(--ink-soft); display: inline-flex; transition: color var(--dur) var(--ease), transform var(--dur) var(--ease); }
.acct-card__go svg { inline-size: 16px; block-size: 16px; }

/* Login / register */
.acct-login { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); max-inline-size: 480px; margin-inline: auto; }
@media (min-width: 900px) {
  .acct-login--two { grid-template-columns: repeat(2, minmax(0, 1fr)); max-inline-size: 880px; }
}
.acct-login__card {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); padding: var(--sp-6);
  box-shadow: 0 10px 30px rgba(26, 22, 12, .06);
}
.acct-login__card .button { inline-size: 100%; }
.acct-login__card h2 { font-size: var(--fs-h3); margin-block-end: var(--sp-2); }
.acct-login__card--register {
  background: linear-gradient(160deg, var(--accent-wash), var(--surface-2) 60%);
  border-color: color-mix(in srgb, var(--accent) 30%, var(--line));
}
.acct-login__row { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3); margin-block: var(--sp-4); }
.acct-login__lost { font-size: var(--fs-small); color: var(--accent-deep); }
.acct-login__perks { list-style: none; margin: 0 0 var(--sp-5); padding: 0; display: grid; gap: var(--sp-3); }
.acct-login__perks li { display: flex; gap: var(--sp-3); align-items: flex-start; font-size: var(--fs-small); color: var(--ink-soft); }
.acct-login__perks svg { inline-size: 16px; block-size: 16px; color: var(--accent-deep); flex: none; margin-block-start: 2px; }

/* Woo form fields across the whole account area, matched to the checkout. */
.woocommerce-account .woocommerce label { display: block; font-size: var(--fs-small); font-weight: var(--fw-med); margin-block-end: 4px; }
.woocommerce-account .woocommerce .input-text,
.woocommerce-account .woocommerce select {
  inline-size: 100%; min-block-size: 46px;
  padding-inline: var(--sp-3);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: #fff; font: inherit; font-size: var(--fs-body); color: var(--ink);
}
.woocommerce-account .woocommerce .input-text:focus,
.woocommerce-account .woocommerce select:focus { outline: 2px solid var(--ink); outline-offset: -1px; }
.woocommerce-account .woocommerce .form-row { margin-block-end: var(--sp-4); }
.woocommerce-account .woocommerce fieldset {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: var(--sp-4); margin-block: var(--sp-5);
}
.woocommerce-account .woocommerce fieldset legend { font-weight: var(--fw-head); padding-inline: var(--sp-2); }
.woocommerce-account .woocommerce span em { font-size: var(--fs-micro); color: var(--ink-soft); }
.woocommerce-account .woocommerce-form__label-for-checkbox { display: inline-flex; align-items: center; gap: var(--sp-2); }
.woocommerce-form-login__rememberme { display: inline-flex; align-items: center; gap: var(--sp-2); margin: 0; }

/* Orders table */
.woocommerce-orders-table { border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.woocommerce-orders-table thead th { background: var(--surface-2); font-size: var(--fs-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.woocommerce-orders-table .woocommerce-button { margin-inline-end: var(--sp-2); }

/* Addresses as cards */
.woocommerce-Addresses { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-4); }
@media (min-width: 700px) { .woocommerce-Addresses { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.woocommerce-Address { border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface); padding: var(--sp-4); }
.woocommerce-Address-title { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); margin-block-end: var(--sp-3); }
.woocommerce-Address-title h2, .woocommerce-Address-title h3 { font-size: var(--fs-h4); margin: 0; }
.woocommerce-Address-title .edit { font-size: var(--fs-small); color: var(--accent-deep); }
.woocommerce-Address address { font-style: normal; color: var(--ink-soft); line-height: 1.6; }

/* --- Login v4 (owner, 12 Aug) ----------------------------------------------
   Same design system — squared radii, uppercase micro labels — composed
   properly: icon chips give each card a face, buttons span the card,
   the register card carries its reasons, focus states are real. */
.acct-login { padding-block: var(--sp-6) var(--sp-8); }
.acct-login__chip {
  display: inline-grid; place-items: center;
  inline-size: 44px; block-size: 44px;
  margin-block-end: var(--sp-4);
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line));
  border-radius: var(--radius);
  color: var(--accent-deep);
}
.acct-login__chip svg { inline-size: 20px; block-size: 20px; }
.woocommerce-account .acct-login__card .button { inline-size: 100%; justify-content: center; }
.woocommerce-account .acct-login .woocommerce label {
  font-size: var(--fs-micro);
  font-weight: var(--fw-head);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.acct-login .input-text {
  border-radius: var(--radius);
  transition: border-color var(--dur) var(--ease);
}
.acct-login .input-text:hover { border-color: var(--ink-soft); }
.acct-login .input-text:focus { outline: 2px solid var(--accent-deep); outline-offset: -1px; }
.acct-login__row { margin-block: var(--sp-4) var(--sp-5); }
.acct-login__lost { text-decoration: underline; text-underline-offset: .15em; }
.acct-login__card--register .acct-login__perks { margin-block-end: var(--sp-5); }
/* Woo's privacy paragraph reads as legal small print, not body copy. */
.acct-login .woocommerce-privacy-policy-text p,
.acct-login .woocommerce-privacy-policy-text {
  font-size: var(--fs-micro);
  color: var(--ink-soft);
  line-height: 1.55;
  margin-block: var(--sp-4);
}
@media (max-width: 899px) {
  .acct-login { padding-block: var(--sp-4) var(--sp-6); }
}


/* The free line in the cart: the badge that says why it costs nothing. */
.badge--free {
  background: var(--accent);
  color: var(--ink);
  font-weight: var(--fw-head);
  letter-spacing: .06em;
  text-transform: uppercase;
}

/* ==========================================================================
   WHATSAPP FLOATING BUTTON (owner, 13 Aug)
   Bottom-right on every page. The language pill owns bottom-left, so the two
   never collide; on phones the PDP sticky buy bar owns the very bottom, so
   the button lifts above it whenever that bar is in.
   ========================================================================== */

.wa-fab {
  position: fixed;
  inset-inline-end: var(--gutter);
  inset-block-end: max(var(--gutter), env(safe-area-inset-bottom));
  z-index: 200;
  display: inline-flex;
  align-items: center;
  gap: 0;
  /* 56px is the floating-action standard and clears the 44px minimum with
     room to spare for a thumb reaching across a phone. */
  min-inline-size: 56px;
  block-size: 56px;
  padding: 0;
  border-radius: 999px;
  background: #25D366;              /* WhatsApp brand green — their asset guidelines */
  color: #FFFFFF;
  box-shadow: 0 10px 28px -10px rgba(37, 211, 102, .8), 0 2px 8px rgba(12, 11, 10, .18);
  overflow: hidden;
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease);
}
.wa-fab__icon {
  inline-size: 56px;
  block-size: 56px;
  display: grid;
  place-items: center;
  flex: none;
}
.wa-fab__icon svg { inline-size: 30px; block-size: 30px; display: block; }

/* The label is revealed on hover on pointer devices only: on a phone it
   would eat the screen edge, and the glyph alone is universally read. */
.wa-fab__label {
  max-inline-size: 0;
  opacity: 0;
  white-space: nowrap;
  font-size: var(--fs-small);
  font-weight: var(--fw-head);
  transition: max-inline-size var(--dur-slow) var(--ease-out), opacity var(--dur) var(--ease), padding var(--dur-slow) var(--ease-out);
}
@media (hover: hover) and (min-width: 700px) {
  .wa-fab:hover .wa-fab__label,
  .wa-fab:focus-visible .wa-fab__label {
    max-inline-size: 160px;
    opacity: 1;
    padding-inline-end: var(--sp-5);
  }
  .wa-fab:hover { transform: translateY(-2px); }
}
.wa-fab:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
}

/* Clear the PDP sticky buy bar (it only exists below 1000px). */
@media (max-width: 999px) {
  .sticky-buy.is-in ~ .wa-fab,
  body:has(.sticky-buy.is-in) .wa-fab {
    inset-block-end: calc(84px + env(safe-area-inset-bottom));
  }
}

/* The cart drawer and the welcome popup sit above it; hide it there so it
   never floats over a dialog. */
body.wlc-open .wa-fab,
body.is-drawer-open .wa-fab { opacity: 0; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .wa-fab, .wa-fab__label { transition: none; }
}
