/* =====================================================
   DROPLET دروبلت — Theme v2.0
   Editorial Minimalism · Wabi-Sabi Luxury
   RTL Arabic-first · No backdrop-filter · No blur
   ===================================================== */

/* ===== 1. DESIGN TOKENS ===== */
:root {
  /* Brand Palette */
  --espresso:      #2d1c1c;
  --espresso-mid:  #3d2424;
  --copper:        #b5622a;
  --copper-light:  #cc7a3d;
  --caramel:       #c9956c;
  --mint:          #6b8f71;
  --mint-soft:     #eef3ef;
  --foam:          #faf6f0;
  --foam-mid:      #f0e8de;
  --foam-dark:     #e3d7c8;
  --stone:         #8a7464;
  --stone-light:   #c4b6a4;
  --ink:           #1a1208;
  --linen:         #ddd5c6;
  --success:       #4f8a6b;
  --danger:        #c0533f;
  --white:         #ffffff;

  /* Typography */
  --font-head:    'Cairo', 'Almarai', 'Tajawal', system-ui, sans-serif;
  --font-body:    'Almarai', 'Tajawal', system-ui, sans-serif;
  --font-accent:  'Cormorant', Georgia, serif;
  --font-numeric: 'Cairo', 'Almarai', system-ui, sans-serif;

  /* Geometry */
  --radius-sm:   8px;
  --radius-md:   14px;
  --radius-lg:   20px;
  --radius-xl:   28px;
  --radius-pill: 999px;

  /* Shadows — espresso-tinted, no blue */
  --shadow-sm: 0 4px 16px rgba(45,28,28,.10);
  --shadow-md: 0 10px 32px rgba(45,28,28,.14);
  --shadow-lg: 0 20px 60px rgba(45,28,28,.18);

  /* Transitions */
  --t-fast: 150ms ease;
  --t-base: 250ms cubic-bezier(.4,0,.2,1);
  --t-slow: 400ms cubic-bezier(.4,0,.2,1);

  /* Z-index */
  --z-overlay: 90;
  --z-nav:     100;
  --z-toast:   150;

  /* Layout */
  --container:  1280px;
  --section-v:  clamp(56px, 8vw, 96px);
  --gap:        20px;
}

/* ===== 2. RESET & BASE ===== */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

/* Sitewide press-feedback rule: every interactive element's :active state may
   change color/background/opacity/shadow freely, but any scale/translate
   motion is suppressed under reduced-motion — one rule covers every
   component rather than repeating the guard per element. */
@media (prefers-reduced-motion: reduce) {
  *:active { transform: none !important; }
}

body {
  background: var(--foam);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.app.rtl  { direction: rtl; }
.app:not(.rtl) { direction: ltr; }

/* ===== 3. TYPOGRAPHY ===== */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-head);
  color: var(--espresso);
  line-height: 1.15;
  font-weight: 900;
  letter-spacing: -0.01em;
}
h1 { font-size: clamp(30px, 5vw, 56px); font-weight: 900; }
h2 { font-size: clamp(24px, 4vw, 42px); font-weight: 900; }
h3 { font-size: clamp(18px, 3vw, 26px); font-weight: 700; }
h4 { font-size: 17px; font-weight: 700; }

a { color: var(--copper); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--espresso); }
a:active { opacity: 0.75; }
p { line-height: 1.75; }
img { max-width: 100%; display: block; }

/* ===== 4. LAYOUT ===== */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 32px);
}

/* ===== 5. BUTTONS ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 0;
  cursor: pointer;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 15px;
  padding: 13px 28px;
  border-radius: var(--radius-pill);
  transition: transform var(--t-fast), box-shadow var(--t-base),
              background var(--t-fast), color var(--t-fast),
              border-color var(--t-fast);
  white-space: nowrap;
  text-decoration: none;
}
@media (hover: hover) { .btn:hover  { transform: translateY(-1px); } }
/* Press feedback fires on every device, hover only on pointer devices that have it —
   a tap must always feel acknowledged, not just a desktop mouse-over. */
.btn:active { transform: translateY(0) scale(0.92); filter: brightness(0.93); transition-duration: 80ms; }
/* .is-pressed mirrors :active exactly — the JS-driven guaranteed-minimum-press
   acknowledgment (main.js, PRESS_ACK_SELECTOR) needs a visible effect on
   buttons whose handler can run before :active ever paints on a fast tap.
   See docs/MOTION-LANGUAGE.md §7 (Intent Acknowledgment) / IB-001. */
.btn.is-pressed { transform: translateY(0) scale(0.92); filter: brightness(0.93); transition-duration: 80ms; }

.btn-primary  { background: var(--espresso); color: var(--white); }
/* Hover only on real pointer devices — prevents the dark pressed colour
   sticking after a tap on touch screens. */
@media (hover: hover) {
  .btn-primary:hover { background: var(--espresso-mid); color: var(--white); box-shadow: var(--shadow-sm); }
}
.btn-primary:active,
.btn-primary.is-pressed { background: var(--espresso-mid); }

/* Add-to-cart button feedback states */
.btn.is-loading { position: relative; color: transparent !important; pointer-events: none; }
.btn.is-loading::after {
  content: "";
  position: absolute; top: 50%; left: 50%;
  width: 18px; height: 18px; margin: -9px 0 0 -9px;
  border: 2px solid rgba(255, 255, 255, .45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: btn-spin 0.6s linear infinite;
}
@keyframes btn-spin { to { transform: rotate(360deg); } }
/* Warm sage success — calmer than a clinical green, on-brand with Droplet */
.btn.is-success { background: #5f8463 !important; color: #fff !important; }
/* The brand mark, briefly, at the moment of success — small and calm,
   not a flourish. Fixed height only; the image's own aspect ratio sets
   width, so it never distorts. */
.success-droplet {
  height: 16px;
  width: auto;
  vertical-align: middle;
  filter: brightness(0) invert(1); /* white, to match the success state's white text */
}
@media (prefers-reduced-motion: no-preference) {
  .success-droplet {
    animation: success-droplet-in 0.4s cubic-bezier(0.16, 1, 0.3, 1);
  }
}
@keyframes success-droplet-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.6); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Cart badge pop when the count changes */
@keyframes badge-pop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.35); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: no-preference) {
  .cart-badge.badge-pop { animation: badge-pop 280ms cubic-bezier(.34, 1.56, .64, 1); }
}

/* Add-to-cart "fly to cart" dot — purely decorative, created and removed by
   flyToCart() in main.js. The JS never creates this element at all under
   prefers-reduced-motion, so no separate CSS media guard is needed here
   (matches the rail-glide precedent elsewhere in this file). */
.atc-fly-dot {
  position: fixed;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--copper);
  z-index: var(--z-toast);
  pointer-events: none;
  transform: translate(0, 0) scale(1);
  opacity: 1;
  transition: transform 900ms cubic-bezier(.3, .7, .4, 1), opacity 320ms ease 620ms;
}

.btn-copper  { background: var(--copper); color: var(--white); }
.btn-copper:hover { background: var(--copper-light); color: var(--white); box-shadow: var(--shadow-sm); }
.btn-copper:active,
.btn-copper.is-pressed { background: #9c5224; }

.btn-ghost   { background: transparent; color: var(--espresso); border: 1.5px solid var(--linen); }
@media (hover: hover) {
  .btn-ghost:hover { border-color: var(--copper); color: var(--copper); }
}
.btn-ghost:active,
.btn-ghost.is-pressed { border-color: var(--copper); color: var(--copper); background: rgba(181,98,42,.06); }

.btn-mint    { background: var(--mint); color: var(--white); }
.btn-mint:hover { background: #5a7d61; color: var(--white); }
.btn-mint:active,
.btn-mint.is-pressed { background: #4d6c52; }

.btn-outline-white {
  background: transparent;
  color: var(--white);
  border: 1.5px solid rgba(255,255,255,.5);
}
.btn-outline-white:hover {
  background: rgba(255,255,255,.1);
  border-color: rgba(255,255,255,.8);
  color: var(--white);
}
.btn-outline-white:active,
.btn-outline-white.is-pressed { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.9); }

.btn-block { width: 100%; }

/* ===== 7. HEADER ===== */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: var(--foam);
  border-bottom: 1px solid var(--linen);
  transition: box-shadow 280ms ease, background 280ms ease;
}
/* Merchant opted out of the sticky header (header.schema.json → general.sticky).
   The scroll-driven .header-scrolled shadow/pour JS stays harmless when static. */
.site-header--static { position: static; }

/* ── Pour Progress ──
   Slim copper→caramel fill at the header's bottom edge that "pours" across
   as the page scrolls. Decorative ::after, scaleX driven by --scroll-progress
   (set by JS, 0→1). Absolutely positioned and out of flow, so it never
   affects header height — no reflow, no jitter. Fills from the inline-start
   edge (right in RTL, left in LTR). */
.site-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--copper), var(--caramel));
  transform: scaleX(var(--scroll-progress, 0));
  transform-origin: left center;
  pointer-events: none;
  z-index: 3;
}
.app.rtl .site-header::after {
  transform-origin: right center;
  background: linear-gradient(270deg, var(--copper), var(--caramel));
}
@media (prefers-reduced-motion: no-preference) {
  .site-header::after { transition: transform 120ms ease-out; }
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding-block: 14px;
  direction: ltr;
}

/* Scrolled state — neutral stable baseline (shadow + background only).
   No glass, no blur, no decorative line. Paint-only, no reflow.
   Placeholder pending a Droplet-aligned scroll concept. */
.site-header.header-scrolled {
  background: var(--foam-soft, var(--foam));
  box-shadow: 0 4px 20px rgba(45, 28, 28, .07);
  border-bottom-color: transparent;
}

/* ===== 8. LOGO ===== */
.logo { display: inline-flex; align-items: center; flex: 0 0 auto; }
.logo img { height: 38px; width: auto; object-fit: contain; }
@media (max-width: 480px) { .logo img { height: 32px; } }

/* Only present when a merchant sets a distinct mobile logo (logo.jinja);
   otherwise a single <img> renders and these rules are inert. */
.logo-mobile { display: none; }
@media (max-width: 480px) {
  .logo-desktop { display: none; }
  .logo-mobile { display: block; }
}

/* ===== 9. DESKTOP NAV ===== */
.nav {
  display: flex;
  align-items: center;
  gap: 2px;
  list-style: none;
  flex: 1;
  justify-content: center;
}
.nav .navlink {
  display: inline-block;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  color: var(--stone);
  font-weight: 600;
  font-size: 15px;
  font-family: var(--font-body);
  background: none;
  border: none;
  cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.nav .navlink:hover { color: var(--espresso); background: var(--foam-mid); }
.nav .navlink:active,
.nav .navlink.is-pressed { color: var(--espresso); background: var(--foam-dark); transform: scale(0.92); transition-duration: 80ms; }

/* ===== 9b. CATEGORY NAVIGATION — desktop hover panel / mobile accordion =====
   Text-first, two-pane on desktop: a list of categories plus a detail pane
   for whichever one is hovered/focused (subcategories + a CTA, no images,
   no product counts). Click on the trigger or any category row always
   navigates; hover/focus only ever previews — never intercepted on desktop. */
.nav-cats-item { position: relative; }

.nav-cats-trigger {
  display: inline-flex !important;
  align-items: center;
  gap: 5px;
}
/* Shared chevron for every disclosure trigger (Categories + generic submenus).
   Rotation is keyed on the aria-expanded state of whatever trigger contains it,
   so one rule serves all consumers and the glyph never drifts between them. */
.nav-chevron {
  flex-shrink: 0;
  color: var(--stone-light, var(--stone));
}
@media (prefers-reduced-motion: no-preference) {
  .nav-chevron { transition: transform .2s ease; }
}
[aria-expanded="true"] .nav-chevron { transform: rotate(180deg); }

/* Anchored, not floating: the trigger's open state shares the panel's
   background and flush bottom corners, so the panel reads as an
   extension of the trigger rather than an independent floating box. */
.nav-cats-trigger[aria-expanded="true"] {
  background: var(--foam);
  color: var(--espresso);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.nav-cats-panel {
  position: absolute;
  inset-inline-start: 0;
  top: 100%;
  z-index: var(--z-nav);
  background: var(--foam);
  border: 1px solid var(--linen);
  border-top: none;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 20px 24px;
  grid-template-columns: 160px 1fr;
  min-width: 420px;
  opacity: 0;
  transform: translateY(-4px);
}
.nav-cats-panel[hidden] { display: none; }
.nav-cats-panel:not([hidden]) { display: grid; }
.nav-cats-panel.open { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: no-preference) {
  .nav-cats-panel { transition: opacity 120ms ease, transform 120ms ease; }
}

.nav-cats-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-inline-end: 20px;
}
.nav-cats-row {
  font-size: 13px;
  color: var(--stone);
  text-decoration: none;
  white-space: nowrap;
}
.nav-cats-row.is-active,
.nav-cats-row:hover,
.nav-cats-row:focus-visible {
  color: var(--espresso);
  font-weight: 600;
}
.nav-cats-row:active { color: var(--copper); opacity: 0.8; }

.nav-cats-detail {
  border-inline-start: 1px solid var(--linen);
  padding-inline-start: 24px;
  min-width: 200px;
}
.nav-cats-detail-label {
  font-size: 11px;
  color: var(--stone-light, var(--stone));
  margin-bottom: 10px;
}
.nav-cats-sublist {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 16px;
}
.nav-cats-sub {
  font-size: 13px;
  color: var(--espresso);
  text-decoration: none;
}
.nav-cats-sub:hover { color: var(--copper); }
.nav-cats-sub:active { color: var(--copper); opacity: 0.7; }
.nav-cats-sub--parent { font-weight: 700; }
.nav-cats-subsublist {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 6px;
  margin-bottom: 4px;
  padding-inline-start: 14px;
  border-inline-start: 1px solid var(--linen);
}
.nav-cats-subsub { font-size: 12.5px; color: var(--stone); text-decoration: none; }
.nav-cats-subsub:hover { color: var(--copper); }
.nav-cats-subsub:active { color: var(--copper); opacity: 0.7; }
.nav-cats-cta {
  font-size: 13px;
  color: var(--copper);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.nav-cats-cta:hover { text-decoration: underline; }
.nav-cats-cta:active { opacity: 0.7; }

/* ---- Generic nav submenu (menu items with children, other than Categories) ----
   Same visual language as .nav-cats-panel (foam surface, linen border,
   radius-md) but a plain single-column link list — no live category data,
   no two-pane preview. Driven by the shared HeaderDisclosure foundation.

   Two shapes, per the parent-nav contract:
     • .nav-has-sub--split — item has a URL: a navigating label link + a
       separate chevron toggle button sit side by side.
     • .nav-has-sub (plain) — no URL: a single toggle button is the whole item.
   The chevron rotation is handled by the shared [aria-expanded] .nav-chevron
   rule above. */
.nav-has-sub { position: relative; }
.nav-has-sub--split { display: inline-flex; align-items: center; }
.nav-has-sub--split .nav-item-label { padding-inline-end: 4px; }
.nav-sub-toggle {
  display: inline-flex !important;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
  font: inherit;
  color: var(--stone);
  border-radius: var(--radius-sm);
  padding: 8px 10px;
  transition: color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.nav-has-sub--split .nav-sub-toggle { padding: 8px 6px; }
.nav-sub-toggle:hover { color: var(--espresso); background: var(--foam-mid); }
.nav-sub-toggle:active,
.nav-sub-toggle.is-pressed { color: var(--espresso); background: var(--foam-dark); transform: scale(0.92); transition-duration: 80ms; }
.nav-sub-panel {
  position: absolute;
  inset-inline-start: 0;
  top: 100%;
  z-index: var(--z-nav);
  background: var(--foam);
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 8px;
  min-width: 180px;
  list-style: none;
  margin: 4px 0 0;
}
.nav-sub-panel[hidden] { display: none; }
.nav-sub-link {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 14px;
  color: var(--espresso);
  text-decoration: none;
  white-space: nowrap;
}
.nav-sub-link:hover { background: var(--linen); color: var(--copper); }
.nav-sub-link:active,
.nav-sub-link.is-pressed { color: var(--copper); background: var(--linen); opacity: 0.85; }

@media (max-width: 768px) {
  /* Inside the mobile drawer the item stacks and the panel is part of the
     flow, not a floating popover — same pattern as the drawer's nav list.
     The split row (label + chevron) keeps its inline-flex layout but wraps so
     the now-static panel drops onto its own full-width line below the row. */
  .nav-has-sub--split { width: 100%; justify-content: space-between; flex-wrap: wrap; }
  .nav-has-sub--split .nav-item-label { flex: 1; }
  .nav-sub-panel {
    position: static;
    box-shadow: none;
    border: none;
    background: none;
    padding-inline-start: 16px;
    min-width: 0;
  }
  .nav-has-sub--split .nav-sub-panel { flex-basis: 100%; }
}

/* ===== 10. HEADER ACTIONS ===== */
.header-actions {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}
.icon-btn {
  position: relative;
  width: 40px; height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--foam-mid);
  color: var(--espresso);
  border: 0;
  cursor: pointer;
  transition: background var(--t-fast), transform var(--t-fast);
}
.icon-btn:hover { background: var(--foam-dark); }
.icon-btn:active,
.icon-btn.is-pressed { background: var(--linen); transform: scale(0.92); transition-duration: 80ms; }

/* ---- Account / auth UI (client-toggled) ----
   Zid's server-side `customer` is unreliable on this platform (renders
   logged-out for authenticated sessions — see header.jinja), so the logged-in
   account UI is revealed by main.js adding .is-authed to [data-auth-root] once
   a session is confirmed (on load AND on bfcache restore). The default — no
   .is-authed — hides the logged-in block, so a logged-out visitor sees nothing
   in the account slot (the intended state), correct even if JS never runs.
   !important beats the inline display:flex on the mobile drawer links. */
[data-auth-root]:not(.is-authed) [data-auth-in]  { display: none !important; }
[data-auth-root].is-authed       [data-auth-out] { display: none !important; }
.header-auth { display: contents; }

/* Logged-out: a quiet text link, no icon/border */
.header-login {
  display: inline-flex; align-items: center; height: 40px;
  padding: 0 10px;
  font-family: var(--font-head);
  font-size: 14px; font-weight: 700;
  color: var(--espresso);
  transition: color var(--t-fast);
}
.header-login:hover { color: var(--copper); }

.header-account {
  display: inline-flex;
  direction: rtl;              /* avatar leads on the RIGHT, name flows RTL to its left */
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 8px;
  border-radius: var(--radius-pill);
  color: var(--espresso);
  transition: background var(--t-fast);
}
.header-account { transition: background var(--t-fast), transform var(--t-fast); }
.header-account:hover { background: var(--foam-mid); }
.header-account:active,
.header-account.is-pressed { background: var(--foam-dark); transform: scale(0.98); transition-duration: 80ms; }
.header-greeting { text-align: right; }
/* Initial-letter avatar (first letter of the customer's name) */
.header-account__ic {
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--espresso);
  color: var(--foam);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-head); font-weight: 700; font-size: 15px;
  line-height: 1;
}
.header-greeting {
  display: inline-flex;        /* column — never a horizontal row, so the RTL
                                  greeting text is one run and is not reversed */
  flex-direction: column;
  justify-content: center;
  line-height: 1.12;
}
.header-greeting__hi   { font-size: 11px; font-weight: 700; color: var(--copper); }
.header-greeting__name {
  font-family: var(--font-head);
  font-size: 14px; font-weight: 700; color: var(--espresso);
  max-width: 18ch; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  /* Arabic needs a taller line box than the parent's tight 1.12: Cairo's
     descenders (ب ن ي ...) sink below it, and the overflow:hidden required for
     the ellipsis then shaves them off — the "name looks cut from the bottom"
     bug. Depends on which letters a name contains, hence intermittent.
     Applies to the drawer's .nav-account name too (same class). */
  line-height: 1.45;
}

/* Mobile drawer account card */
/* The whole card is the link to /account — tapped like the desktop chip, with
   the same hover + press feedback (js-press-ack drives .is-pressed on touch). */
.nav-account {
  display: flex; direction: rtl; align-items: center; gap: 10px;
  padding: 9px 12px;
  background: var(--foam); border-radius: var(--radius-sm);
  color: var(--espresso);
  transition: background var(--t-fast), transform var(--t-fast);
}
.nav-account:hover { background: var(--foam-mid); }
.nav-account:active,
.nav-account.is-pressed { background: var(--foam-dark); transform: scale(0.98); transition-duration: 80ms; }
.nav-account__ic {
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--espresso); color: var(--foam);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-head); font-weight: 700; font-size: 15px; line-height: 1;
}
.nav-account .nav-greeting { display: inline-flex; flex-direction: column; line-height: 1.15; text-align: right; }
.nav-account .header-greeting__hi   { font-size: 11px; }
.nav-account .header-greeting__name { font-size: 14px; }

.cart-badge {
  position: absolute;
  top: -3px; inset-inline-end: -3px;
  min-width: 18px; height: 18px;
  padding: 0 4px;
  background: var(--copper);
  color: var(--white);
  font-size: 10px; font-weight: 700;
  border-radius: var(--radius-pill);
  display: flex; align-items: center; justify-content: center;
}

/* Account items — sidebar only */
.nav-account-item { display: none; }

/* ===== 11. MOBILE SIDEBAR ===== */
/* Overlay */
.nav-overlay {
  display: block;
  position: fixed;
  inset: 0;
  background: rgba(26,18,8,.55);
  z-index: var(--z-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
  /* NO backdrop-filter — causes iOS freeze */
}
.nav-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

/* Toggle button — hidden on desktop */
.nav-toggle { display: none; }

/* ===== 12. HERO ===== */
.hero {
  padding-block: clamp(48px, 8vw, 96px);
  background: var(--foam);
  position: relative;
  overflow: hidden;
}
/* Subtle tinted half — right side warm wash */
.hero::after {
  content: "";
  position: absolute;
  inset-inline-end: 0;
  top: 0;
  width: 42%;
  height: 100%;
  background: var(--foam-mid);
  clip-path: ellipse(100% 100% at 100% 50%);
  pointer-events: none;
  z-index: 0;
}
.hero-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  align-items: center;
  gap: 48px;
}
.hero-tag {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--foam-mid);
  border: 1px solid var(--linen);
  border-radius: var(--radius-pill);
  padding: 6px 16px;
  font-size: 13px;
  font-weight: 700;
  color: var(--stone);
  margin-bottom: 20px;
}
.hero-tag::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--copper);
  flex-shrink: 0;
}
.hero h1 {
  font-size: clamp(44px, 7vw, 84px);
  line-height: 1.05;
  color: var(--espresso);
  margin-bottom: 16px;
  letter-spacing: -.02em;
}
.hero-sub {
  font-size: 17px;
  color: var(--stone);
  margin-bottom: 28px;
  max-width: 40ch;
  line-height: 1.65;
}
.hero-brands {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 32px;
}
.hero-brand-tag {
  font-family: var(--font-accent);
  font-size: 12px;
  color: var(--stone);
  border: 1px solid var(--linen);
  border-radius: var(--radius-pill);
  padding: 4px 14px;
  text-transform: uppercase;
}
.hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }

/* Hero image side — portrait 3:4 */
.hero-media { position: relative; }
.hero-img-frame {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--foam-dark);
  box-shadow: var(--shadow-lg);
  max-height: 520px;
}
.hero-img-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero-img-frame .img-placeholder {
  object-fit: contain;
  padding: 20%;
  opacity: .5;
}
/* Thin copper border accent */
.hero-img-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px solid rgba(181,98,42,.25);
  border-radius: var(--radius-xl);
  pointer-events: none;
  z-index: 2;
}
/* Floating stat card */
.hero-stat {
  position: absolute;
  inset-inline-start: -24px;
  bottom: 48px;
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  padding: 14px 20px;
  box-shadow: var(--shadow-sm);
  min-width: 130px;
  z-index: 3;
}
.hero-stat-num {
  font-family: var(--font-accent);
  font-size: 30px;
  font-weight: 700;
  color: var(--copper);
  line-height: 1;
  display: block;
}
.hero-stat-label {
  font-size: 12px;
  color: var(--stone);
  font-weight: 600;
  margin-top: 4px;
  display: block;
}

/* ===== 13. MARQUEE STRIP ===== */
.marquee-strip {
  background: var(--espresso);
  padding-block: 14px;
  overflow: hidden;
  white-space: nowrap;
}
.marquee-inner {
  display: inline-flex;
  animation: marquee-scroll 28s linear infinite;
}
.marquee-strip:hover .marquee-inner { animation-play-state: paused; }
.marquee-item {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  padding-inline-end: 32px;
  font-family: var(--font-accent);
  font-size: 13px;
  color: rgba(255,255,255,.65);
  text-transform: uppercase;
}
.marquee-dot {
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--copper);
  flex-shrink: 0;
}

@keyframes marquee-scroll {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

/* ===== 14. SECTIONS ===== */
.section { padding-block: var(--section-v); }

.section-head { margin-bottom: clamp(28px, 5vw, 52px); }
.section-head.centered { text-align: center; }

.eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  color: var(--copper);
  margin-bottom: 12px;
}

.section-head h2 { margin-bottom: 8px; }
.section-head p {
  color: var(--stone);
  font-size: 17px;
  max-width: 48ch;
  margin-top: 4px;
}
.section-head.centered p { margin-inline: auto; }

/* ===== 15. CATEGORY GRID — editorial discovery ===== */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
.cat-tile {
  position: relative;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  text-decoration: none;
  cursor: pointer;
  /* Unified warm treatment — espresso deepening into copper.
     Also the fallback backdrop for categories without an image. */
  background: linear-gradient(160deg, var(--espresso) 0%, #5c3010 60%, var(--copper) 100%);
  transition: transform var(--t-base), box-shadow var(--t-base);
}
.cat-tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.cat-tile:active,
.cat-tile.is-pressed { transform: translateY(-1px) scale(0.98); box-shadow: var(--shadow-sm); transition-duration: 80ms; }

.cat-tile img {
  position: absolute;
  inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
  z-index: 0;
}
.cat-tile:hover img { transform: scale(1.06); }

/* Fallback glyph for image-less categories */
.cat-tile-glyph {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 0;
  color: rgba(255, 255, 255, .22);
}
.cat-tile-glyph svg { width: 42%; height: 42%; }

.cat-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(26,18,8,.78) 0%, rgba(26,18,8,.18) 45%, transparent 75%);
  z-index: 1;
}
.cat-tile-label {
  position: relative;
  z-index: 2;
  width: 100%;
  padding: 18px 18px 20px;
  color: var(--white);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cat-tile-name {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 18px;
  line-height: 1.2;
}
.cat-tile-meta {
  font-family: var(--font-body);
  font-size: 12.5px;
  color: rgba(255, 255, 255, .75);
}
.cat-tile-cue {
  margin-top: 6px;
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--caramel);
}
.cat-tile-cue span { display: inline-block; }
@media (hover: hover) {
  .cat-tile-cue {
    opacity: 0;
    transform: translateX(4px);
    transition: opacity var(--t-base), transform var(--t-base);
  }
  .cat-tile:hover .cat-tile-cue {
    opacity: 1;
    transform: translateX(0);
  }
}

/* ===== 16. PRODUCT GRID ===== */
.product-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
}

/* ===== 17. PRODUCT CARD ─ Direction B: object on warm surface ===== */
.product-card {
  background: var(--foam-mid);
  border: none;
  border-radius: 12px 22px 12px 12px; /* v1.0 directional-bias law: leading (top-right) corner always larger */
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 2px 10px rgba(45,28,28,.06);
  transition: transform var(--t-base), box-shadow var(--t-base);
  cursor: pointer;
}
.product-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 18px rgba(45,28,28,.09);
}
/* Excludes the moment the Quick Buy circle itself is pressed — without this,
   pressing the small trigger also visibly shrinks the whole card around it,
   two motions answering one tap. */
.product-card:active:not(:has(.product-quick-trigger:active)) { transform: scale(0.98); box-shadow: 0 1px 6px rgba(45,28,28,.08); transition-duration: 80ms; }
/* .is-pressed mirror: main.js's press-ack delegation already resolves the
   same trigger-vs-card exclusion structurally (closest() stops at the
   trigger before ever reaching .product-card), so no :has() guard is
   needed here — .is-pressed is only ever added to one or the other. */
.product-card.is-pressed { transform: scale(0.98); box-shadow: 0 1px 6px rgba(45,28,28,.08); transition-duration: 80ms; }

/* Whole card is a single link — fills the card, stacks thumb + body */
.product-card-link {
  display: flex;
  flex-direction: column;
  flex: 1;
  color: inherit;
  text-decoration: none;
}

/* SQUARE, matching the photography. Measured across the live catalogue:
   37 of 40 product images are exactly 770x770 — Zid's own square thumbnails.
   The tile was 4/5 portrait, so `cover` was cutting 20% off the top and bottom
   of every one of them, which is the "photo is cut" the merchant reported.
   A square frame and a square photo agree exactly: `cover` crops nothing, the
   photo fills the tile edge to edge on any background, and the card now shows
   what the lightbox shows. Fixing the FRAME rather than the fit is what makes
   both true at once — `contain` in a portrait frame solved the crop but
   letterboxed every dark or lifestyle shot into a floating rectangle. */
.product-thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  margin: 8px 8px 0;
  border-radius: 14px 26px 14px 14px; /* v1.0: same leading-corner bias as .product-card, offset +4px per corner */
  background: var(--foam);
  box-shadow: inset 0 0 0 1px rgba(45,28,28,.04);
  overflow: hidden;
  flex-shrink: 0;
}
.product-thumb img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--t-slow);
}
/* Lazy-load fade: image fades in once decoded instead of popping.
   .img-loaded is added by JS (and immediately for cached images). */
@media (prefers-reduced-motion: no-preference) {
  .product-thumb img:not(.img-placeholder) {
    opacity: 0;
    transition: transform var(--t-slow), opacity 550ms ease;
  }
  .product-thumb img.img-loaded { opacity: 1; }
}
.product-card:hover .product-thumb img { transform: scale(1.04); }
.img-placeholder {
  object-fit: contain !important;
  padding: 22%;
  opacity: .5;
  transform: none !important;
  transition: none !important;
}

/* ── Product badge ─────────────────────────────── */
.product-badge {
  position: absolute;
  inset-block-start: 12px;
  inset-inline-start: 12px;
  background: rgba(255,255,255,0.95);
  color: #6b3b18;
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  padding: 6px 13px;
  border-radius: 20px;
  border: 1px solid rgba(181,98,42,0.28);
  pointer-events: none;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
/* Copper dot — for editorial badge types */
.product-badge--special_product::before,
.product-badge--staff_pick::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--copper);
  flex-shrink: 0;
}
.product-oos-label {
  position: absolute;
  bottom: 10px;
  inset-inline-start: 10px;
  background: rgba(245, 240, 232, 0.93);
  color: var(--stone);
  font-family: 'Almarai', 'Tajawal', sans-serif;
  font-size: 10px;
  font-weight: 400;
  padding: 4px 9px;
  border-radius: 20px;
  border: 1px solid rgba(120, 100, 80, 0.18);
  pointer-events: none;
  z-index: 2;
}

/* ── Product card footer action row (v3) ──
   A real in-flow row at the bottom of the card: price block at the start,
   Quick Buy trigger at the end. NOT absolutely positioned — it cannot float
   over or overlap the price/text on any screen size. */
.product-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 2px 12px 12px;
}
.product-foot .price-row { margin: 0; }
.product-foot-spacer { flex: 1; }

/* Quick Buy trigger (v5) — flat, no background/border/shadow/circle. Reads as
   part of the card's own quiet typographic language (same family as the
   .product-cue arrow) rather than an attached UI control glued onto the row.
   Calm stone color at rest, copper only on interaction — integration over
   decoration. Box is a comfortable 42px tap target even though only the
   20px glyph is visually drawn — the hit area grows without the icon
   itself getting louder. */
.product-quick-trigger {
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  background: rgba(181,98,42,0.05); /* soft circular tint at rest — present but almost disappears into the card */
  border: none;
  border-radius: 50%;
  color: var(--stone);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent; /* no native blue/grey tap flash on touch */
  outline: none;
  transition: background var(--t-base);
}
.product-quick-trigger svg { width: 20px; height: 20px; position: relative; z-index: 1; }
.qb-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1px solid var(--copper);
  opacity: 0;
  transform: scale(0.7);
  pointer-events: none;
}
/* Hover strengthens the same tint only — no color change on the icon itself,
   keeping the calm, editorial feel rather than a marketplace-CTA color swap. */
@media (hover: hover) {
  .product-quick-trigger:hover { background: rgba(181,98,42,0.09); }
  .product-quick-trigger:hover .qb-ring { animation: qb-ring-pulse 0.6s ease-out; }
}
/* Soft, brand-colored focus ring — distinct from hover, not a thick browser
   default outline. */
.product-quick-trigger:focus-visible {
  background: rgba(181,98,42,0.09);
  box-shadow: 0 0 0 3px rgba(181,98,42,0.18);
}
.product-quick-trigger:focus-visible .qb-ring { animation: qb-ring-pulse 0.6s ease-out; }
/* Press feedback — same scale/timing as before; only the tint strengthens
   further rather than shifting to a darker, heavier fill. */
.product-quick-trigger:active,
.product-quick-trigger.is-pressed {
  background: rgba(181,98,42,0.12);
  transform: scale(0.92);
  transition-duration: 80ms;
}
.product-quick-trigger:active svg,
.product-quick-trigger.is-pressed svg { transform: scale(0.92); }
@media (prefers-reduced-motion: reduce) {
  .product-quick-trigger.is-pressed,
  .product-quick-trigger.is-pressed svg { transform: none; }
}
@keyframes qb-ring-pulse {
  0%   { opacity: 0.55; transform: scale(0.7); }
  100% { opacity: 0; transform: scale(1.35); }
}
@media (prefers-reduced-motion: reduce) {
  .qb-ring { animation: none !important; }
}

/* ── Quick Buy modal ── */
.qb-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
}
.qb-modal.open { display: block; }
.qb-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(45,28,28,0.32);
  opacity: 0;
  transition: opacity var(--t-base);
}
.qb-modal.open .qb-backdrop { opacity: 1; }

.qb-sheet {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--foam-mid);
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -8px 30px rgba(45,28,28,.18);
  padding: 0;
  transform: translateY(100%);
  transition: transform var(--t-base);
}
.qb-modal.open .qb-sheet { transform: translateY(0); }

/* Desktop: a true centered card — not a side drawer. The .open rule below must
   match the specificity of `.qb-modal.open { display:block }` above (both 0,2,0)
   so that, being later in source, it wins and the flex centering actually applies.
   Earlier this was `.qb-modal { display:flex }` (0,1,0) which lost to the block
   rule, leaving the sheet pinned to the bottom/edge like a drawer. */
@media (min-width: 769px) {
  .qb-modal.open { display: flex; align-items: center; justify-content: center; padding: 24px; }
  .qb-sheet {
    position: relative;
    left: auto; right: auto; bottom: auto;
    width: 100%;
    max-width: 500px;
    max-height: 86vh;
    border-radius: 20px;
    box-shadow: 0 24px 70px rgba(45,28,28,.24);
    transform: translateY(8px) scale(0.98);
    opacity: 0;
    transition: transform var(--t-base), opacity var(--t-base);
  }
  .qb-modal.open .qb-sheet { transform: translateY(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .qb-backdrop, .qb-sheet { transition: none !important; }
}

/* The visible bar stays a thin 4px pill (unchanged look), but the actual
   drag/tap target is a full-width 30px-tall zone around it — comfortable to
   grab without making the handle itself look bigger or louder. touch-action:
   none stops the browser's own scroll/refresh gestures from fighting the
   drag-to-close gesture while a finger is on the handle. */
.qb-handle {
  width: 100%;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  touch-action: none;
}
.qb-handle::before {
  content: '';
  width: 36px;
  height: 4px;
  border-radius: 4px;
  background: rgba(120,100,80,0.22);
}
@media (min-width: 769px) { .qb-handle { display: none; } }

.qb-content { padding: 16px 18px 20px; }

/* Small calm heading so the sheet reads as an intentional purchase surface,
   not a bare popup — sits on its own row with the close button, aligned. */
.qb-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}
.qb-title {
  font-family: var(--font-head);
  font-size: 13.5px;
  font-weight: 700;
  color: var(--stone);
}
.qb-close {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: var(--foam);
  color: var(--stone);
  font-size: 17px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}
.qb-close:hover { color: var(--copper); }
.qb-close:active,
.qb-close.is-pressed { color: var(--copper); background: var(--foam-mid); transform: scale(0.9); transition-duration: 80ms; }

/* Mini-cart style header row — small framed image beside name + price, the
   same compact "image | info" pattern as .cart-product-row on the cart page.
   Not a large hero image stacked above everything else. */
.qb-row {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  column-gap: 14px;
  align-items: center;
}
.qb-media {
  width: 84px;
  height: 84px;
  border-radius: var(--radius-md);
  background: var(--foam);
  overflow: hidden;
  flex-shrink: 0;
}
.qb-media img { width: 100%; height: 100%; object-fit: cover; }
.qb-row-info { min-width: 0; }

.qb-name {
  font-family: var(--font-head);
  font-size: 15.5px;
  font-weight: 700;
  color: var(--espresso);
  line-height: 1.3;
  margin: 0 0 5px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.qb-row-info .price-row { margin: 0; }
.qb-options { margin-top: 18px; }
.qb-option-group + .qb-option-group { margin-top: 12px; }
.qb-option-label {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--espresso);
  margin-bottom: 7px;
  display: block;
}
.qb-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.qb-pill {
  padding: 7px 14px;
  border-radius: 20px;
  border: 1.5px solid var(--linen);
  background: transparent;
  color: var(--espresso);
  font-size: 13px;
  font-family: var(--font-body);
  cursor: pointer;
  transition: border-color var(--t-base), background var(--t-base), color var(--t-base);
}
@media (hover: hover) { .qb-pill:hover:not(.qb-pill--oos):not(.qb-pill--selected) { border-color: var(--stone-light); } }
/* Excludes --selected so pressing an already-chosen option doesn't flash
   its copper text/border back to neutral — selected pills get scale-only
   feedback below, keeping their own color intact. */
.qb-pill:active:not(.qb-pill--oos):not(.qb-pill--selected),
.qb-pill.is-pressed:not(.qb-pill--oos):not(.qb-pill--selected) { border-color: var(--copper); background: rgba(181,98,42,0.1); transform: scale(0.92); transition-duration: 80ms; }
.qb-pill--selected { border-color: var(--copper); background: rgba(181,98,42,0.08); color: var(--copper); font-weight: 600; }
.qb-pill--selected:active,
.qb-pill--selected.is-pressed { transform: scale(0.92); transition-duration: 80ms; }
/* Same rule as .option-pill--oos: sold out here, but still clickable, because
   it is the way through to the in-stock combinations. Only a pill that is sold
   out everywhere gets `disabled` (and with it the not-allowed cursor). */
.qb-pill--oos { color: var(--stone-light); border-color: var(--linen); text-decoration: line-through; opacity: 0.6; }
.qb-pill:disabled { cursor: not-allowed; opacity: 0.45; }
.qb-prompt {
  margin-top: 10px;
  font-size: 12.5px;
  color: var(--stone);
}
.qb-oos-msg {
  margin-top: 14px;
  font-size: 13px;
  color: var(--stone);
  background: var(--foam);
  border-radius: 10px;
  padding: 10px 12px;
}
.qb-qty-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
  margin-bottom: 16px;
}
.qb-qty-label { font-weight: 700; font-size: 13px; color: var(--espresso); }

/* Clear separation between the option/quantity controls and the purchase
   actions, so the two action buttons read as their own decisive group. */
.qb-actions-divider {
  height: 1px;
  background: var(--linen);
  margin: 18px 0 16px;
}
.qb-actions { display: flex; flex-direction: column; gap: 10px; }
.qb-actions .btn:disabled { opacity: 0.45; cursor: not-allowed; }
/* أضف إلى السلة is now primary (stronger weight); اشترِ الآن is secondary/calmer */
.qb-actions .btn-primary { font-size: 16px; padding: 14px 28px; }
.qb-actions .btn-ghost { font-size: 14.5px; }

/* Inline feedback near the actions — replaces the global top-page flash for
   everything that happens inside this modal (add/buy success, stock limits,
   SDK errors). Calm, small, never a popup of its own. */
.qb-feedback {
  margin: 12px 0 0;
  font-size: 13px;
  text-align: center;
  border-radius: 10px;
  padding: 9px 12px;
}
.qb-feedback--success { background: rgba(95,132,99,0.12); color: #4a6b4e; }
.qb-feedback--error { background: rgba(185,64,64,0.1); color: #b94040; }

/* ── Product detail page badge (inline, not absolute) ── */
.product-info-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--foam);
  color: #6b3b18;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 6px 14px;
  border-radius: 20px;
  border: 1px solid rgba(181, 98, 42, 0.28);
  margin-block-end: 10px;
}

/* ── Out-of-stock notify-me form ── */
.notify-toggle-btn { margin-block-start: 16px; }
.notify-form-wrap {
  margin-block-start: 14px;
  padding: 16px;
  background: var(--foam);
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.notify-intro {
  font-size: 13px;
  color: var(--stone);
  margin: 0;
  line-height: 1.55;
}
.notify-input {
  width: 100%;
  padding: 10px 14px;
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-sm);
  background: var(--white);
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  box-sizing: border-box;
  outline: none;
  transition: border-color var(--t-fast);
}
.notify-input:focus { border-color: var(--copper); }
.notify-result {
  font-size: 13px;
  text-align: center;
  margin: 0;
  color: var(--stone);
}
.notify-result--ok  { color: var(--success); font-weight: 600; }
.notify-result--err { color: var(--danger); }


/* Badges */
.badge {
  position: absolute;
  top: 10px; inset-inline-start: 10px;
  background: var(--copper);
  color: var(--white);
  font-size: 11px; font-weight: 700;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  z-index: 2;
}
.badge.soldout { background: var(--stone); }

/* Card body — caption sits on the warm card surface, gently inset */
.product-body {
  padding: 12px 12px 7px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.product-brand {
  font-family: var(--font-accent);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--copper);
}
.product-name {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 14px;
  color: var(--espresso);
  line-height: 1.4;
  letter-spacing: -0.01em;
  flex: 1;
}

/* Hover cue — replaces the per-card button.
   Always visible on touch devices (no hover); on devices that support
   hover it stays subtle and sharpens when the card is hovered. */
.product-cue {
  margin-top: 7px;
  font-size: 13px;
  font-weight: 400;
  font-family: var(--font-body);
  color: var(--stone);
  opacity: 0.7;
}
.product-cue span { display: inline-block; }
@media (hover: hover) {
  .product-cue {
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity var(--t-base), transform var(--t-base), color var(--t-base);
  }
  .product-card:hover .product-cue {
    opacity: 1;
    transform: translateX(0);
    color: var(--copper);
    font-weight: 600;
  }
}

.product-excerpt {
  font-size: 12.5px;
  color: var(--stone);
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.price-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid rgba(45,28,28,.07);
}
.price {
  font-family: var(--font-numeric);
  font-weight: 700;
  color: var(--espresso);
  font-size: 17px;
}
.price-old {
  font-family: var(--font-body);
  font-weight: 300;
  color: var(--stone-light);
  text-decoration: line-through;
  text-decoration-color: var(--stone-light);
  font-size: 13px;
}
/* Sale price — copper and prominent. Discount treatment: a VERTICAL STACK —
   the struck-through original sits quietly on top, the new copper price below,
   giving a clear before/after with no label (the strikethrough already says
   "old price") and no crowding on one line. */
.price--sale {
  color: var(--copper);
  font-weight: 700;
}

/* CARD (and Quick Buy): the discount stays on ONE line so every card is the
   same height — a two-line stack here left non-sale cards with an ugly empty
   gap in the grid. New copper price leads, struck original beside it, no label
   (the strikethrough already says "old price"). Inline is inherited from
   .price-row (flex row, baseline). */
.product-card .price-row--sale { flex-wrap: wrap; }
.product-card .price-row--sale .price--sale { font-size: 20px; }
.product-card .price-row--sale .price-old { font-size: 12px; }

/* PRODUCT PAGE only: vertical stack — there's room (single product, no grid),
   so the struck original sits on top and the big copper price below.
   column-reverse keeps the new price first in the DOM (prominent) while
   rendering it on the lower line. */
.product-info .price-row--sale {
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: 2px;
}
.product-card .btn { margin-top: 10px; font-size: 14px; padding: 10px 18px; }

/* ===== 18. PRODUCT PAGE ===== */
.product-detail {
  display: grid;
  grid-template-columns: minmax(0, 520px) minmax(300px, 400px);
  gap: 64px;
  padding-block: 56px;
  align-items: start;
  justify-content: center;
}

/* Desktop: purchase column stays in view while the gallery scrolls. */
@media (min-width: 769px) {
  .product-info {
    position: sticky;
    top: 88px;
    align-self: start;
  }
}

/* Gallery container for single image */
.gallery-main {
  position: relative;          /* anchors the pending-swap shimmer */
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--foam-mid);
  /* Square for the same reason as .product-thumb — the catalogue is shot
     770x770, so a 4/5 frame was cropping every photo top and bottom. */
  aspect-ratio: 1 / 1;
  max-height: 620px;
}

/* ── Pending image swap ──
   While a newly selected photo is still decoding, the <img> is transparent, so
   the frame — not the image — has to say "loading". A slow shimmer over the
   frame's own foam, not a spinner: the wait is short and bounded, and a
   spinner would overstate it. Only ever applied after a threshold, so a cached
   photo never flashes one (see galleryShowImage). */
.gallery-main.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg,
    rgba(255,255,255,0) 20%,
    rgba(255,255,255,0.55) 50%,
    rgba(255,255,255,0) 80%);
  transform: translateX(-100%);
  animation: gallery-shimmer 1100ms ease-in-out infinite;
  pointer-events: none;
  z-index: 1;
}
@keyframes gallery-shimmer {
  to { transform: translateX(100%); }
}
@media (prefers-reduced-motion: reduce) {
  /* Still disclose the wait — just hold it still rather than sweeping. */
  .gallery-main.is-loading::after {
    animation: none;
    transform: none;
    background: rgba(255,255,255,0.35);
  }
}
.gallery-main img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: opacity var(--t-fast);
}
/* Crossfade target for gallerySelect()/galleryNav() — fade out before the
   src swap, fade back in after, instead of an instant hard cut. */
.gallery-main img.is-fading { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .gallery-main img { transition: none; }
}

/* Gallery nav: arrows physically beside the image */
.gallery-with-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  direction: ltr;          /* ← always LTR so ← stays left, → stays right */
}
.gallery-with-nav .gallery-main {
  flex: 1;
  min-width: 0;            /* prevent flex overflow */
}

/* ── Gallery arrow controls (beside-image layout) ── */
.gallery-arrow {
  flex-shrink: 0;
  background: var(--foam-mid);
  border: 1.5px solid var(--linen);
  border-radius: 50%;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  color: var(--espresso);
  padding: 0;
  transition: background var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}
.gallery-arrow:hover {
  background: white;
  border-color: var(--copper);
  box-shadow: var(--shadow-sm);
}
.gallery-arrow:active,
.gallery-arrow.is-pressed { transform: scale(0.92); transition-duration: 80ms; }

/* ── Thumbnail rail ──
   One line that scrolls, never a wrapping grid. A wrapping strip grows a row
   per 6-7 images and pushes the whole buy box down; a rail keeps the gallery a
   fixed height whatever the image count. The rail is the scroll container and
   owns the edge fades; .gallery-thumbs is just the track inside it. */
/* A grid item's automatic minimum size is its CONTENT size, so the mobile
   `grid-template-columns: 1fr` column would size itself to the full unwrapped
   thumbnail track (10 thumbs = 712px) and push the whole page into horizontal
   overflow instead of letting the rail scroll. min-width:0 on the item — and on
   the rail itself — is what makes the overflow land where it belongs. */
.gallery { min-width: 0; }
.gallery-thumb-rail {
  position: relative;
  min-width: 0;
  margin-top: 10px;
}
/* Edge fades signal "there is more this way". Only painted while the rail can
   actually scroll that way (JS toggles .can-start / .can-end), so a short strip
   that fits entirely shows no misleading fade. */
.gallery-thumb-rail::before,
.gallery-thumb-rail::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  width: 40px;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-fast);
  z-index: 1;
}
.gallery-thumb-rail::before {
  inset-inline-start: 0;
  background: linear-gradient(to right, var(--foam), rgba(255,255,255,0));
}
.gallery-thumb-rail::after {
  inset-inline-end: 0;
  background: linear-gradient(to left, var(--foam), rgba(255,255,255,0));
}
.app.rtl .gallery-thumb-rail::before { background: linear-gradient(to left,  var(--foam), rgba(255,255,255,0)); }
.app.rtl .gallery-thumb-rail::after  { background: linear-gradient(to right, var(--foam), rgba(255,255,255,0)); }
.gallery-thumb-rail.can-start::before { opacity: 1; }
.gallery-thumb-rail.can-end::after    { opacity: 1; }

.gallery-thumbs {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;            /* the rail's own fades are the affordance */
  /* Room for the 2px active border + 0.92 press scale so neither is clipped
     by the scroll container's edges. */
  padding-block: 2px;
}
.gallery-thumbs::-webkit-scrollbar { display: none; }
.gallery-thumbs img {
  flex: 0 0 auto;
  scroll-snap-align: center;
  width: 64px; height: 64px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  border: 2px solid transparent;
  cursor: pointer;
  transition: border-color var(--t-fast), opacity var(--t-fast);
}
.gallery-thumbs img:hover          { border-color: var(--copper); }
.gallery-thumbs img:active,
.gallery-thumbs img.is-pressed     { border-color: var(--copper); transform: scale(0.92); transition-duration: 80ms; }
.gallery-thumbs img.active         { border-color: var(--copper); opacity: 1; }
.gallery-thumbs img:not(.active)   { opacity: 0.65; }

/* ── Zoom trigger ──
   The main image is a button (see product.jinja). Reset the button chrome so it
   still reads as the plain framed image it was, and add the one thing that
   marks it as openable: a zoom cue + zoom-in cursor. */
.gallery-zoom {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  font: inherit;
  cursor: zoom-in;
  -webkit-tap-highlight-color: transparent;
}
.gallery-zoom img { display: block; }
/* The image itself lifts very slightly on hover — the same "this responds"
   language the cards use, at a scale small enough not to read as a transition. */
@media (hover: hover) {
  .gallery-zoom:hover img { transform: scale(1.02); }
}
.gallery-zoom img { transition: opacity var(--t-fast), transform var(--t-base); }

.gallery-zoom-cue {
  position: absolute;
  inset-block-end: 12px;
  inset-inline-end: 12px;
  width: 36px; height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(255,255,255,0.86);
  color: var(--espresso);
  box-shadow: var(--shadow-sm);
  opacity: 0.85;
  transition: opacity var(--t-fast), transform var(--t-fast);
}
.gallery-zoom-cue svg { width: 17px; height: 17px; }
@media (hover: hover) {
  .gallery-zoom:hover .gallery-zoom-cue { opacity: 1; transform: scale(1.06); }
}
.gallery-zoom:active .gallery-zoom-cue,
.gallery-zoom.is-pressed .gallery-zoom-cue { transform: scale(0.92); transition-duration: 80ms; }
@media (prefers-reduced-motion: reduce) {
  .gallery-zoom img, .gallery-zoom-cue { transition: none; }
  .gallery-zoom:hover img { transform: none; }
}

/* ══ Gallery lightbox ══
   Full-bleed view of the current image. The inline gallery is a fixed square
   frame that matches the catalogue's square photography, so it no longer crops
   either; this surface exists to give the photo the whole viewport.
   Above the Quick Buy modal's 200 because it can be opened over nothing else. */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 240;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox[hidden] { display: none; }
/* The dialog itself takes focus on open (see lightboxOpen). It is the surface,
   not a control, so it must not draw a ring — the overlay appearing IS the
   feedback that focus moved. */
.lightbox:focus,
.lightbox:focus-visible { outline: none; }

.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(28,18,18,0.82);
  opacity: 0;
  transition: opacity var(--t-base);
}
.lightbox.open .lightbox-backdrop { opacity: 1; }

.lightbox-stage {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 72px 64px;
  pointer-events: none;          /* clicks fall through to the backdrop = dismiss */
}
/* The box is the STAGE, not the photo. Sizing it to the image (max-width /
   max-height on an auto box) meant the element's own dimensions changed every
   time the next photo had a different shape — a visible reflow mid-swap, with
   the outgoing photo's area still painted around the incoming smaller one.
   A constant box removes the reflow entirely: `contain` centres each photo
   inside it at whatever size it needs, and nothing moves but the picture.
   lightboxPhotoRect() recovers the photo's real rect for the FLIP. */
.lightbox-img {
  width: 100%;
  height: 100%;
  object-fit: contain;           /* the whole photo, never cropped */
  pointer-events: auto;
  /* transform is driven by the open/close zoom-from-origin animation in JS;
     no CSS transition here, or it would fight the explicit FLIP timing. */
}
.lightbox-img.is-fading { opacity: 0; transition: opacity var(--t-fast); }

/* Chrome (close, counter, arrows) fades in a beat after the image has landed,
   so the opening reads as "the photo grew", not "a dialog appeared". */
.lightbox-close,
.lightbox-counter,
.lightbox-arrow {
  position: absolute;
  pointer-events: auto;
  opacity: 0;
  transition: opacity var(--t-base) 120ms, background var(--t-fast), transform var(--t-fast);
}
.lightbox.open .lightbox-close,
.lightbox.open .lightbox-counter,
.lightbox.open .lightbox-arrow { opacity: 1; }

.lightbox-close,
.lightbox-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.22);
  background: rgba(255,255,255,0.12);
  color: var(--white);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  /* These two were missed when the rest of the site's controls got them (see
     .qb-close, .gallery-zoom, .option-pill): without them a tap on the close X
     paints the platform's native blue/grey circle over the button, and the
     focus ring left by that tap persists after the finger lifts. The press is
     already acknowledged by the shared scale(0.92). */
  -webkit-tap-highlight-color: transparent;
  outline: none;
}
/* outline:none above is only safe paired with this — keyboard users keep a
   visible ring, touch users don't get a stuck one. */
.lightbox-close:focus-visible,
.lightbox-arrow:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 2px;
}
@media (hover: hover) {
  .lightbox-close:hover,
  .lightbox-arrow:hover { background: rgba(255,255,255,0.24); border-color: rgba(255,255,255,0.5); }
}
.lightbox-close:active, .lightbox-close.is-pressed,
.lightbox-arrow:active, .lightbox-arrow.is-pressed { transform: scale(0.92); transition-duration: 80ms; }

.lightbox-close { top: 16px; inset-inline-end: 16px; }
/* Forced LTR arrow placement, matching the inline gallery: the left arrow is
   always physically left. galleryNav()'s deltas already encode the RTL reading
   order, so these reuse the same swapped mapping. */
.lightbox-prev { inset-inline-start: auto; left: 16px; }
.lightbox-next { inset-inline-end: auto; right: 16px; }

.lightbox-counter {
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  padding: 6px 14px;
  border-radius: 999px;
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,0.18);
  color: var(--white);
  font-family: var(--font-accent);
  font-size: 12px;
  letter-spacing: .08em;
  font-variant-numeric: tabular-nums;
  /* "5 / 10" is a position-in-set ratio, not prose. Under the RTL paragraph
     direction the bidi algorithm reorders the two numeric runs and renders it
     as "10 / 5" — i.e. image 10 of 5. Isolate it as an LTR run so current
     always stays on the left of the total. */
  direction: ltr;
  unicode-bidi: isolate;
}

@media (max-width: 768px) {
  .lightbox-stage { padding: 64px 12px; }
  /* Touch has swipe + thumbnails for traversal; the arrows would sit on top of
     the photo on a small screen for no added reach. */
  .lightbox-arrow { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox-backdrop,
  .lightbox-close, .lightbox-counter, .lightbox-arrow { transition-duration: 0.01ms !important; transition-delay: 0s !important; }
}

/* Pending swap inside the lightbox. A ring rather than the inline gallery's
   shimmer: here the image is the whole surface over a dark scrim, so there is
   no frame to shimmer, and the wait is genuinely longer (the large original,
   not the already-cached inline size). */
.lightbox.is-loading::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 34px; height: 34px;
  margin: -17px 0 0 -17px;
  border-radius: 50%;
  border: 2px solid rgba(255,255,255,0.25);
  border-top-color: rgba(255,255,255,0.9);
  animation: lightbox-spin 700ms linear infinite;
  pointer-events: none;
}
@keyframes lightbox-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox.is-loading::after { animation: none; border-top-color: rgba(255,255,255,0.55); }
}

/* The page behind a full-screen surface must not scroll under it. */
body.lightbox-open { overflow: hidden; }

/* Brand eyebrow above the title */
.product-info .product-brand {
  display: block;
  margin-bottom: 8px;
  font-family: var(--font-accent);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--copper);
}
.product-info h1 {
  font-size: clamp(24px, 4vw, 34px);
  line-height: 1.2;
  margin-bottom: 16px;
}
.product-info .price-row { display: flex; align-items: baseline; gap: 10px; border-top: none; padding-top: 0; margin-top: 0; }
/* Editorial numeral treatment, matching the homepage's .hero-stat-num
   precedent (Cormorant, 700) — the brand's own documented intent for
   "distinctive prices and numbers," not yet honored on the product page
   itself. Color is left untouched: copper already means "you touched
   something" elsewhere (sale price already inherits it via .price--sale)
   — this changes the typeface only, not the material-contact signal. */
.product-info .price { font-size: 32px; font-family: var(--font-accent); }
.product-info .price-old { font-size: 19px; font-family: var(--font-accent); }

/* Quieter stock chip — warm neutral pill, colour carried by the dot */
.stock-row { margin-block: 16px 0; }
.stock {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-weight: 600;
  font-size: 12.5px;
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  background: var(--foam-mid);
}
.stock.in  { color: var(--success); }
.stock.out { color: var(--danger); }

/* One-line trust cue under the stock chip */
.product-trust {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--linen);
  font-size: 13px;
  color: var(--stone);
}
.product-trust svg { width: 17px; height: 17px; stroke: var(--copper); flex-shrink: 0; }

.product-desc { color: var(--stone); margin-block: 22px; line-height: 1.85; font-size: 14.5px; }
.product-desc-placeholder { font-style: italic; opacity: 0.55; font-size: 14px; }

.field { margin-bottom: 16px; }
.field label { display: block; font-weight: 700; margin-bottom: 6px; color: var(--espresso); font-size: 14px; }
.field select,
.field input[type="number"],
.field input[type="text"],
.field textarea {
  width: 100%;
  padding: 11px 14px;
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-sm);
  background: var(--white);
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--ink);
  transition: border-color var(--t-fast);
}
.field select:focus,
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--copper); }

/* ── Product variant options (vitrin:v2/products/options/variant_options.jinja) ── */
.product-options { margin-block: 18px 4px; }
.product-options__group { display: flex; flex-direction: column; gap: 7px; }
.product-options__group + .product-options__group { margin-top: 14px; }
.product-options__label {
  font-size: 13px;
  font-weight: 700;
  color: var(--espresso);
}
.product-options__select {
  width: 100%;
  padding: 10px 14px;
  padding-left: 36px;                /* room for custom chevron (RTL: arrow on left) */
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-sm);
  background-color: var(--white);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' stroke='%238a7464' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left 10px center;
  -webkit-appearance: none;
  appearance: none;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  cursor: pointer;
  outline: none;
  box-sizing: border-box;
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.product-options__select:hover { border-color: var(--stone-light); }
.product-options__select:focus {
  border-color: var(--copper);
  box-shadow: 0 0 0 3px rgba(181, 98, 42, .12);
}

/* Option value pills replace native select dropdowns */
.option-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}
.option-pill {
  padding: 7px 18px;
  border: 1.5px solid var(--linen);
  border-radius: 20px;
  background: var(--white);
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--espresso);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast), transform var(--t-fast);
  white-space: nowrap;
  user-select: none;
  line-height: 1.4;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  outline: none;
}
.option-pill:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 2px;
}
@media (hover: hover) {
  .option-pill:hover:not(.option-pill--oos):not(.option-pill--selected) {
    border-color: var(--copper);
    color: var(--copper);
  }
}
.option-pill:active:not(.option-pill--oos):not(.option-pill--selected),
.option-pill.is-pressed:not(.option-pill--oos):not(.option-pill--selected) {
  border-color: var(--copper);
  color: var(--copper);
  background: rgba(181,98,42,0.06);
  transform: scale(0.92);
  transition-duration: 80ms;
}
.option-pill--selected {
  background: var(--espresso);
  color: var(--white);
  border-color: var(--espresso);
}
.option-pill--selected:active,
.option-pill--selected.is-pressed { transform: scale(0.92); transition-duration: 80ms; }
/* Sold out, but still the route to the combinations that aren't — so it keeps
   a pointer. Only --dead (sold out in every combination it appears in) is
   genuinely unclickable. */
.option-pill--oos {
  color: var(--stone);
  border-color: var(--linen);
  background: var(--foam);
}
.option-pill--dead {
  cursor: not-allowed;
  opacity: 0.55;
}
.option-pill--oos.option-pill--selected {
  background: var(--foam);
  color: var(--stone);
  border-color: var(--stone);
}

/* Options prompt and highlight (sticky ATC gate) */
.options-prompt {
  margin-top: 10px;
  padding: 9px 14px;
  background: var(--foam);
  border: 1px solid var(--copper);
  border-radius: var(--radius-sm);
  color: var(--espresso);
  font-size: 13px;
  text-align: center;
}
.options-highlight {
  animation: optionsFlash 1.6s ease-out forwards;
}
@keyframes optionsFlash {
  0%   { box-shadow: 0 0 0 0 rgba(181, 98, 42, 0); }
  25%  { box-shadow: 0 0 0 5px rgba(181, 98, 42, 0.22); }
  75%  { box-shadow: 0 0 0 5px rgba(181, 98, 42, 0.22); }
  100% { box-shadow: 0 0 0 0 rgba(181, 98, 42, 0); }
}

.qty-row { display: flex; gap: 14px; align-items: center; margin-block: 20px; }
.qty-control {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.qty-control button {
  width: 40px; height: 44px;
  border: 0;
  background: var(--foam-mid);
  font-size: 20px;
  cursor: pointer;
  color: var(--espresso);
  transition: background var(--t-fast), transform var(--t-fast);
}
.qty-control button:hover { background: var(--foam-dark); }
.qty-control button:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 2px;
}
.qty-control button:active:not(:disabled),
.qty-control-btn.is-pressed:not(:disabled) { background: var(--copper); color: #fff; transform: scale(0.92); transition-duration: 80ms; }
/* Matches the cart page's identical .qty-btn:disabled treatment — same
   control, same role, same disabled signal, on a different surface. */
.qty-control button:disabled { color: var(--stone-light); cursor: default; }
.qty-control input {
  width: 52px; height: 44px;
  border: 0;
  text-align: center;
  font-size: 16px;
  font-weight: 700;
  background: var(--white);
  color: var(--ink);
}

/* ===== 19. CART ===== */
.cart-wrap {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 28px;
  padding-block: 48px 32px;
  align-items: start;
}
.cart-items {
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-lg);
  padding: 0 20px;
}
.cart-item {
  display: grid;
  grid-template-columns: 88px 1fr auto;
  gap: 16px;
  padding-block: 20px;
  border-bottom: 1px solid var(--linen);
  align-items: center;
}
.cart-item:last-child { border-bottom: 0; }
.cart-item img {
  width: 88px; height: 88px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  background: var(--foam-mid);
}
.cart-item-name { font-weight: 700; color: var(--espresso); font-size: 15px; }
.cart-item-price {
  font-family: var(--font-numeric);
  font-weight: 700;
  font-size: 16px;
  color: var(--copper);
}
.cart-summary {
  background: var(--foam-mid);
  border: 1px solid var(--foam-dark);
  border-radius: var(--radius-lg);
  padding: 24px 24px 26px;
  position: sticky;
  top: 88px;
  box-shadow: 0 2px 10px rgba(45,28,28,.06);
}
.cart-summary h3 {
  margin-bottom: 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(45,28,28,.10);
  font-size: 18px;
  color: var(--espresso);
}
.totals { list-style: none; margin-bottom: 2px; transition: opacity var(--t-base); }
/* Ambient Status (Level B): dimmed while a quantity or coupon change is in
   flight and the shown numbers may not match what's about to be true.
   Reuses the same .4 opacity already used for temporarily-unavailable
   controls (.pagination .is-disabled) rather than inventing a new value. */
.totals.is-stale { opacity: .4; }
.totals li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding-block: 9px;
  font-size: 14px;
  color: var(--stone);
}
.totals li span:last-child {
  font-family: var(--font-numeric);
  font-weight: 600;
  color: var(--espresso);
  display: inline-flex;
  align-items: center;
  direction: ltr;
  gap: 5px;
}
.totals li.total-row {
  margin-top: 14px;
  padding-top: 18px;
  border-top: 1.5px solid rgba(45,28,28,.10);
  font-size: 22px;
  color: var(--espresso);
}
.totals li.total-row span:last-child {
  font-family: var(--font-numeric);
  font-weight: 700;
  color: var(--copper);
  gap: 6px;
}
/* Coupon row — connected input+button control */
.coupon-row {
  display: flex;
  gap: 0;
  margin: 18px 0 14px;
}
.coupon-row input {
  flex: 1;
  min-width: 0;
  padding: 10px 13px;
  border: 1.5px solid rgba(45,28,28,.12);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0; /* RTL: right side rounded */
  border-inline-end: none;                              /* remove join edge */
  background: var(--foam);
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--ink);
  letter-spacing: 0.04em;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.coupon-row input:focus {
  outline: none;
  border-color: var(--copper);
  background: var(--white);
  position: relative;
  z-index: 1;
}
/* Coupon apply button — part of the connected control, clearly secondary.
   min-width is sized to its longest label ("تم التطبيق", measured 90px live) —
   without it the button (and the connected input beside it, which is flex:1)
   visibly resize across تطبيق → ... → تم التطبيق, a real measured layout
   shift (67px → 41px → 90px) live-verified 2026-07-04, not a guess. */
.coupon-row .btn {
  padding: 10px 15px;
  min-width: 96px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--stone);
  background: var(--foam-dark);
  border: 1.5px solid rgba(45,28,28,.12);
  border-radius: var(--radius-sm) 0 0 var(--radius-sm); /* RTL: left side rounded */
  border-inline-start: none;                            /* remove join edge */
  white-space: nowrap;
  flex-shrink: 0;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
@media (hover: hover) {
  .coupon-row .btn:hover:not(:disabled) { color: var(--copper); border-color: var(--copper); background: var(--foam-mid); }
}
/* Matches .qb-actions .btn:disabled — same role (a CTA button currently
   blocked/in-flight), no reason found for the two to differ. The
   confirmed/applied sub-case below is a separate, deliberate override and
   takes precedence regardless of this base value. */
.coupon-row .btn:disabled { opacity: 0.45; cursor: not-allowed; }
/* Applied-coupon confirmed state — calm tick colour, not greyed-out */
#coupon-btn:disabled[aria-label] {
  opacity: 1;
  color: var(--copper);
  border-color: rgba(139,90,43,.35);
  background: rgba(139,90,43,.06);
  cursor: default;
}
/* Checkout CTA — sized via class, not inline style */
.btn-checkout { padding: 16px; font-size: 17px; }
/* Continue-shopping — demoted to a quiet text link */
.cart-continue {
  display: block;
  text-align: center;
  margin-top: 14px;
  font-size: 13px;
  color: var(--stone);
  text-decoration: none;
  transition: color var(--t-fast);
}
.cart-continue:hover { color: var(--copper); }
.cart-continue:active { color: var(--copper); opacity: 0.75; }
/* Coupon status — quiet inline row, not an alert card */
.coupon-status {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 8px;
  margin-bottom: 18px;
  padding: 6px 10px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  font-family: var(--font-body);
  line-height: 1.4;
}
.coupon-status--success {
  background: transparent;
  border: 1px dashed rgba(45,28,28,.14);
}
.coupon-status--error {
  background: rgba(192,98,79,.06);
  border: 1px solid rgba(192,98,79,.22);
}
/* Success/error status appears via a quiet fade+settle rather than an
   instant innerHTML pop-in — no new keyframe needed, a plain transition on
   entrance is enough for a small inline row (unlike qty-bump/optionsFlash,
   which exist for a value that changes in place, not an element that's
   freshly inserted). Runs on every appearance (success or error alike) since
   both are "a message just arrived" moments, not distinct in register. */
@media (prefers-reduced-motion: no-preference) {
  .coupon-status { animation: coupon-status-in var(--t-base) both; }
}
@keyframes coupon-status-in {
  from { opacity: 0; transform: translateY(-3px); }
  to   { opacity: 1; transform: translateY(0); }
}
.coupon-status__icon {
  font-size: 10px;
  flex-shrink: 0;
  line-height: 1;
  opacity: 0.75;
}
.coupon-status--success .coupon-status__icon { color: var(--copper); }
.coupon-status--error   .coupon-status__icon { color: #b94040; }
.coupon-status__text {
  flex: 1;
  color: var(--stone);
  font-size: 12px;
}
.coupon-status--error .coupon-status__text { color: #7a2a2a; }
/* Coupon chip — [tag icon] code × — always LTR internally, quiet by default */
.coupon-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  direction: ltr;
  font-family: 'Courier New', monospace;
  font-size: 9.5px;
  font-weight: 600;
  color: var(--stone);
  background: rgba(45,28,28,.04);
  border: 1px solid rgba(45,28,28,.13);
  border-radius: 20px;
  padding: 2px 4px 2px 6px;
  flex-shrink: 0;
  line-height: 1;
  transition: border-color var(--t-fast);
}
.coupon-chip__icon {
  display: block;
  flex-shrink: 0;
  opacity: 0.55;
}
.coupon-chip__code {
  display: inline;
  opacity: 1;
  color: var(--espresso);
}
.coupon-chip__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 13px;
  height: 13px;
  padding: 0;
  margin: 0;
  background: none;
  border: none;
  color: var(--stone);
  opacity: 0.7;
  cursor: pointer;
  transition: opacity var(--t-fast), color var(--t-fast);
  flex-shrink: 0;
}
@media (hover: hover) {
  .coupon-chip:has(.coupon-chip__remove:hover) { border-color: rgba(139,90,43,.3); }
  .coupon-chip__remove:hover:not(:disabled) { opacity: 1; color: #b94040; }
}
.coupon-chip__remove:active:not(:disabled),
.coupon-chip__remove.is-pressed:not(:disabled) { opacity: 1; color: #b94040; transform: scale(0.85); transition-duration: 80ms; }
.coupon-chip__remove:disabled { opacity: 0.25; cursor: default; }

/* Same small-dismiss-control language as .coupon-chip__remove, sized for a
   standalone control rather than nested in a chip (IB-002). */
.atc-error-dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  opacity: 0.7;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  flex-shrink: 0;
  transition: opacity var(--t-fast), transform var(--t-fast);
}
@media (hover: hover) {
  .atc-error-dismiss:hover { opacity: 1; }
}
.atc-error-dismiss:active,
.atc-error-dismiss.is-pressed { opacity: 1; transform: scale(0.92); transition-duration: 80ms; }
/* legacy standalone code span — kept as fallback, hidden when chip is used */
.coupon-status__code {
  font-family: 'Courier New', monospace;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.09em;
  color: var(--copper);
  background: var(--foam-mid);
  border: 1px solid rgba(45,28,28,.12);
  border-radius: 20px;
  padding: 2px 8px;
  flex-shrink: 0;
}
.empty-state { text-align: center; padding: 80px 20px; }
.empty-state svg { margin: 0 auto 16px; opacity: .3; }
/* ── No-results empty state — editorial, no card frame ── */
.empty-state--results {
  padding: 36px 24px 0;
  text-align: center;
}
.empty-results-title {
  font-family: var(--font-head);
  font-size: clamp(22px, 4.5vw, 28px);
  font-weight: 600;
  color: var(--espresso);
  line-height: 1.45;
  margin: 0 0 14px;
  letter-spacing: 0;
}
.empty-results-body {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  color: var(--stone);
  line-height: 1.85;
  max-width: 340px;
  margin: 0 auto 0;
}
.empty-results-fallback-cta {
  margin-top: 20px;
}
/* ── Recommendations section — connected continuation ── */
#fallback-rec-section {
  margin-top: 28px;
  padding-top: 28px;
  border-top: 1px solid var(--linen);
  padding-bottom: 32px;
  scroll-margin-top: 80px;
}
.fallback-rec-title {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--stone);
  text-align: center;
  margin: 0 0 20px;
}
.fallback-rec-cta {
  text-align: center;
  margin-top: 28px;
}
.empty-state--cart {
  padding: 48px 16px 80px;
}
.empty-cart-card {
  max-width: 480px;
  margin: 0 auto;
  background: var(--foam);
  border: 1px solid var(--linen);
  border-radius: 16px;
  padding: 52px 40px 48px;
  text-align: center;
}
.empty-cart-icon {
  color: var(--copper);
  margin: 0 auto 28px;
  line-height: 1;
}
.empty-cart-icon svg { display: block; margin: 0 auto; }
.empty-state__title {
  font-family: var(--font-body);
  font-size: clamp(22px, 5vw, 26px);
  font-weight: 700;
  color: var(--espresso);
  margin: 0 0 14px;
}
.empty-state__body {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--stone);
  line-height: 1.85;
  margin: 0 auto 36px;
  max-width: 300px;
}
.empty-state__cta {
  padding: 14px 40px;
  font-size: 15px;
}
@media (max-width: 480px) {
  .empty-cart-card { padding: 40px 24px 36px; }
}

/* ===== 404 page ===== */
.not-found-wrap {
  max-width: 520px;
  margin: 0 auto;
  padding: clamp(64px, 10vw, 120px) 24px clamp(80px, 12vw, 140px);
  text-align: center;
}
.not-found-code {
  display: block;
  font-family: var(--font-head);
  font-size: clamp(48px, 10vw, 72px);
  font-weight: 700;
  color: var(--linen);
  line-height: 1;
  margin-bottom: 16px;
  letter-spacing: -0.02em;
}
.not-found-title {
  font-family: var(--font-head);
  font-size: clamp(22px, 4.5vw, 28px);
  font-weight: 600;
  color: var(--espresso);
  line-height: 1.45;
  margin: 0 0 16px;
}
.not-found-body {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 400;
  color: var(--stone);
  line-height: 1.85;
  margin: 0 0 32px;
}
.not-found-cta { display: inline-flex; }

/* ===== CMS page (page.jinja) =====
   Content is merchant-authored HTML from the dashboard, so this styles
   descendants generically rather than a known structure. Measure is capped
   for readability — legal/policy copy is the primary use. */
.page-wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(48px, 8vw, 88px) 0 clamp(64px, 10vw, 112px);
}
.page-title {
  font-family: var(--font-head);
  font-size: clamp(24px, 5vw, 34px);
  font-weight: 600;
  color: var(--espresso);
  line-height: 1.4;
  margin: 0 0 clamp(24px, 4vw, 40px);
}
.page-content {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 400;
  color: var(--stone);
  line-height: 1.9;
}
/* Slate nests everything under a single `.slate-editor` wrapper, so the
   first/last-child reset has to reach inside it too or it only ever trims
   that wrapper. */
.page-content > :first-child,
.page-content .slate-editor > :first-child { margin-top: 0 !important; }
.page-content > :last-child,
.page-content .slate-editor > :last-child { margin-bottom: 0 !important; }
/* Zid stores page content as its editor's own serialized markup, not clean
   HTML: paragraphs arrive as `div.slate-p`, never `<p>`, so tag selectors
   alone match almost nothing. Every selector below is paired with its
   `.slate-*` equivalent. Verified live on /pages/privacy-policy: slate-p,
   slate-ul, slate-li, slate-lic, slate-bold, slate-underline, slate-a,
   slate-align-right. Heading classes follow the same convention but that
   page has no headings, so `.slate-h*` is covered defensively alongside the
   real tags. */
.page-content h2,
.page-content h3,
.page-content h4,
.page-content .slate-h2,
.page-content .slate-h3,
.page-content .slate-h4 {
  font-family: var(--font-head);
  font-weight: 600;
  color: var(--espresso);
  line-height: 1.5;
  margin: 2em 0 0.75em !important;
}
.page-content h2, .page-content .slate-h2 { font-size: 19px; }
.page-content h3, .page-content .slate-h3 { font-size: 17px; }
.page-content h4, .page-content .slate-h4 { font-size: 15px; }

/* The editor writes `style="position:relative;margin:6px 0"` onto each block.
   An inline style beats any stylesheet rule regardless of specificity, so
   restoring our vertical rhythm needs !important — the one place in this file
   where it's the mechanism rather than a shortcut. */
.page-content p,
.page-content .slate-p { margin: 0 0 1.25em !important; }

.page-content ul,
.page-content ol,
.page-content .slate-ul,
.page-content .slate-ol { margin: 0 0 1.25em !important; padding-inline-start: 1.5em; }
.page-content li,
.page-content .slate-li { margin-bottom: 0.5em; }
/* Slate wraps each list item's text in an inner `.slate-lic` block that would
   otherwise inherit the paragraph margin and double the list's spacing. */
.page-content .slate-lic { margin: 0 !important; }

.page-content .slate-bold { font-weight: 700; color: var(--espresso); }
.page-content .slate-underline { text-decoration: underline; text-underline-offset: 3px; }
/* Deliberately not styled: `.slate-align-right`, and any inline font-size the
   editor writes onto a run. Both are the merchant's own formatting choices
   made in the dashboard — the theme sets the page's defaults and leaves
   author intent alone. */
.page-content a {
  color: var(--espresso);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.page-content img { max-width: 100%; height: auto; }
.page-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1.25em;
}
.page-content th,
.page-content td {
  border: 1px solid var(--linen);
  padding: 10px 12px;
  text-align: start;
}

/* ===== Cart line items — Zid platform markup (vitrin:cart/products_list.jinja) =====
   REAL per-item structure (direct children of .cart-product-row):
     .cart-product-delete   → remove link (a[onclick=cartProductRemove])
     .cart-product-col-img  → image (a.cart-product-image-link > img.cart-product-image)
     .cart-product-col-details → .product-title-row > h1 > a  (product name)
     .cart-products-action  → .cart-product-quantity-dropdown > div > select
     .cart-product-prices   → .totals > .cart-product-total-price (+ .cart-product-price-each.d-none)
   NOTE: the name link ALSO carries .cart-product-image-link, so image-link
   styling must be scoped to .cart-product-col-img. */

.cart-items { background: transparent; border: 0; border-radius: 0; padding: 0; }
.section-cart-products-row { display: none; }   /* hide platform column header if present */

/* Item card: image one side, name → price → quantity stacked beside it;
   remove is a corner trash button (absolutely positioned). */
.cart-product-row {
  position: relative;
  display: grid;
  grid-template-columns: 80px minmax(0, 1fr);
  grid-template-areas:
    "img name"
    "img price"
    "img qty";
  column-gap: 14px;
  row-gap: 4px;
  align-items: center;
  padding: 10px 12px;
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  margin-bottom: 10px;
  transition: box-shadow var(--t-base), border-color var(--t-base), background-color 220ms ease;
}
.cart-product-row:last-child { margin-bottom: 0; }
.cart-product-row:hover { box-shadow: var(--shadow-sm); border-color: var(--foam-dark); }

/* Image */
.cart-product-col-img { grid-area: img; align-self: center; }
.cart-product-col-img .cart-product-image-link { display: block; line-height: 0; }
img.cart-product-image {
  width: 80px; height: 80px;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--foam-mid);
  display: block;
}

/* Product name — neutralise the platform <h1> size */
.cart-product-col-details { grid-area: name; min-width: 0; align-self: center; padding-inline-end: 32px; }
.cart-product-col-details .product-title-row { margin: 0; }
.cart-product-col-details h1 { margin: 0; font-size: 14.5px; line-height: 1.3; }
.cart-product-col-details h1 a {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 14.5px;
  line-height: 1.3;
  color: var(--espresso);
  text-decoration: none;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cart-product-col-details h1 a:hover { color: var(--copper); }
.cart-product-col-details h1 a:active { color: var(--copper); opacity: 0.75; }

/* Total price */
.cart-product-prices { grid-area: price; align-self: center; min-width: 0; }
.cart-product-prices .totals { display: block; margin: 0; }
.cart-product-prices .cart-product-total-price {
  font-family: var(--font-numeric);
  font-weight: 700;
  font-size: 17px;
  color: var(--copper);
  display: inline-flex;
  align-items: center;
  direction: rtl;
  gap: 5px;
}
.cart-product-prices .cart-product-total-price .riyal-svg { width: 14px; height: 16px; }
/* Old/before price in cart items */
.cart-product-prices .cart-product-total-before-price {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 12px;
  color: var(--stone-light);
  display: inline-flex;
  align-items: center;
  direction: rtl;
  gap: 4px;
}
.cart-product-prices .cart-product-total-before-price .riyal-svg { width: 11px; height: 13px; opacity: 0.7; }
.cart-product-prices .prefix,
.cart-product-prices .postfix { display: none; }
/* Unit price — subtle secondary line beneath the total (overrides platform .d-none) */
.cart-product-prices .cart-product-price-each {
  display: flex !important;
  align-items: baseline;
  gap: 4px;
  margin-top: 1px;
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 400;
  color: var(--stone);
}
.cart-product-prices .cart-product-price-each .prefix,
.cart-product-prices .cart-product-price-each .postfix { display: none; }
.cart-product-prices .cart-product-price-each .riyal-svg { width: 11px; height: 13px; }

/* Quantity — native select hidden (kept in DOM, driven by the JS stepper) */
.cart-products-action { grid-area: qty; justify-self: start; align-self: center; }
.cart-product-quantity-dropdown.form-group { margin: 0; }
.cart-product-quantity-dropdown select { display: none; }

/* − / number / + stepper (built by JS in templates/cart.jinja) */
.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-pill);
  background: var(--foam);
  overflow: hidden;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
/* Subtle control-only highlight when quantity updates (no row background change) */
@media (prefers-reduced-motion: no-preference) {
  .qty-stepper.qty-flash {
    border-color: var(--copper);
    box-shadow: 0 0 0 3px rgba(181, 98, 42, .12);
  }
}
.qty-btn {
  width: 28px; height: 28px;
  border: 0;
  background: transparent;
  color: var(--espresso);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  outline: none;
}
/* Hover fill only on real pointer devices — prevents the sticky "pressed"
   look on touch where :hover persists after a tap. */
@media (hover: hover) {
  .qty-btn:hover:not(:disabled) { background: var(--copper); color: #fff; }
}
.qty-btn:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 2px;
}
/* Immediate, self-releasing feedback for touch — same scale+timing as the
   product page / Quick Buy modal stepper (.qty-control button), so both
   quantity steppers on the site feel identical, not just visually similar. */
.qty-btn:active:not(:disabled),
.qty-btn.is-pressed:not(:disabled) { background: var(--copper); color: #fff; transform: scale(0.92); transition-duration: 80ms; }
.qty-btn:disabled { color: var(--stone-light); cursor: default; }
/* IB-006 rollback message — absolutely positioned so it never shifts
   surrounding layout (no CLS); the dropdown container becomes the
   positioning context. */
.cart-product-quantity-dropdown { position: relative; }
.qty-error {
  position: absolute;
  top: 100%;
  inset-inline-start: 0;
  margin-top: 4px;
  font-size: 12px;
  color: var(--danger);
  white-space: nowrap;
}
.qty-value {
  display: inline-block;
  min-width: 30px;
  text-align: center;
  font-family: var(--font-accent);
  font-weight: 700;
  font-size: 14px;
  color: var(--espresso);
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes qty-bump {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.18); }
    100% { transform: scale(1); }
  }
  .qty-value.qty-bump { animation: qty-bump 200ms ease; }
  /* Same treatment, applied to the product page's price when a variant
     change updates it — reused deliberately rather than a new keyframe,
     since both are "a real commerce number just changed" moments. */
  .product-info .price.price-updated { animation: qty-bump 200ms ease; }
}

/* Remove — refined round trash-icon button in the card's far corner.
   Hides the platform's empty icon-font glyph + loading spans; draws our own
   trash via a CSS mask so hover recolours it red. */
.cart-product-delete {
  position: absolute;
  top: 10px;
  inset-inline-end: 12px;
  margin: 0;
}
.cart-product-delete a {
  width: 28px; height: 28px;
  border-radius: 50%;
  background-color: var(--foam-mid);
  color: var(--stone);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: color var(--t-fast), background-color var(--t-fast), transform var(--t-fast);
}
@media (hover: hover) {
  .cart-product-delete a:hover { color: #d94f4f; background-color: rgba(217, 79, 79, .12); }
}
.cart-product-delete a:active,
.cart-product-delete a.is-pressed { color: #d94f4f; background-color: rgba(217, 79, 79, .2); transform: scale(0.92); transition-duration: 80ms; }
.cart-product-delete .icon-delete,
.cart-product-delete .prefix,
.cart-product-delete .postfix { display: none; }
.cart-product-delete a::before {
  content: "";
  width: 16px; height: 16px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3 6 5 6 21 6'/%3E%3Cpath d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'/%3E%3Cline x1='10' y1='11' x2='10' y2='17'/%3E%3Cline x1='14' y1='11' x2='14' y2='17'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='3 6 5 6 21 6'/%3E%3Cpath d='M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2'/%3E%3Cline x1='10' y1='11' x2='10' y2='17'/%3E%3Cline x1='14' y1='11' x2='14' y2='17'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Mobile */
@media (max-width: 600px) {
  .cart-product-row {
    grid-template-columns: 72px minmax(0, 1fr);
    column-gap: 12px;
    padding: 10px;
  }
  img.cart-product-image { width: 72px; height: 72px; }
}

/* ===== 20. LISTING PAGES ===== */
.page-head {
  background: var(--foam-mid);
  padding-block: clamp(40px, 6vw, 72px);
  text-align: center;
  border-bottom: 1px solid var(--linen);
}
.page-head h1 { margin: 0; }

.breadcrumb { font-size: 13px; color: var(--stone); margin-bottom: 8px; }
.breadcrumb a { color: var(--stone); }
.breadcrumb a:hover { color: var(--copper); }
.breadcrumb a:active { color: var(--copper); opacity: 0.7; }

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 28px;
  flex-wrap: wrap;
}
.toolbar .count { color: var(--stone); font-size: 14px; }

/* ===== 21. FEATURES SECTION ===== */
.features-section { background: var(--espresso); }
.features {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  padding-block: clamp(40px, 6vw, 64px);
}
.feature { text-align: center; }
.feature-icon {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.14);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 16px;
}
.feature-icon svg {
  width: 22px; height: 22px;
  stroke: var(--caramel);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.feature h4 { color: var(--white); font-size: 15px; margin-bottom: 6px; }
.feature p  { color: rgba(255,255,255,.55); font-size: 14px; }

/* ===== 22. BRAND STORY ===== */
.brand-story {
  background: var(--espresso);
  color: var(--white);
  padding-block: clamp(64px, 10vw, 120px);
  position: relative;
  overflow: hidden;
}
.brand-story::before {
  content: "DROPLET";
  position: absolute;
  inset-inline-end: -20px;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-accent);
  font-size: clamp(80px, 15vw, 200px);
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255,255,255,.05);
  pointer-events: none;
  letter-spacing: -.02em;
  white-space: nowrap;
  user-select: none;
}
.brand-story-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.brand-story h2 {
  color: var(--white);
  font-size: clamp(28px, 5vw, 52px);
  margin-bottom: 20px;
  line-height: 1.15;
}
.brand-story p { color: rgba(255,255,255,.72); font-size: 17px; line-height: 1.85; }
.brand-story .eyebrow { color: var(--caramel); }
.brand-story-img {
  aspect-ratio: 4 / 5;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.1);
}
.brand-story-img img { width: 100%; height: 100%; object-fit: cover; }

/* ===== 23. PROMO CARD ===== */
.promo-card-section { padding-block: clamp(16px, 3vw, 32px); }
.promo-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  padding: clamp(32px, 5vw, 60px);
  display: flex;
  align-items: center;
  gap: 40px;
  min-height: 240px;
  box-shadow: var(--shadow-md);
}
.promo-card--image-right { flex-direction: row; }
.promo-card--image-left  { flex-direction: row-reverse; }

.promo-card__body {
  flex: 1;
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
.promo-card__eyebrow {
  font-size: 11px; font-weight: 800;
}
.promo-card__title {
  font-family: var(--font-head);
  font-size: clamp(22px, 4vw, 36px);
  font-weight: 700;
  line-height: 1.2; margin: 0;
  color: inherit;
}
.promo-card__desc {
  font-size: 15px;
  line-height: 1.7;
  opacity: .85;
  max-width: 38ch;
  margin: 0;
}
.promo-card__btn { margin-top: 8px; }
.promo-card__media {
  flex: 0 0 40%; max-width: 40%;
  display: flex; align-items: center; justify-content: center;
  position: relative; z-index: 2;
}
.promo-card__media img {
  width: 100%; max-height: 260px;
  object-fit: contain;
  filter: drop-shadow(0 12px 24px rgba(0,0,0,.2));
}
.promo-card__ghost {
  position: absolute;
  inset-inline-end: -20px; top: 50%;
  transform: translateY(-50%);
  font-family: var(--font-accent);
  font-size: clamp(80px, 14vw, 160px);
  font-weight: 700;
  letter-spacing: -.03em; line-height: 1;
  opacity: .07;
  white-space: nowrap;
  pointer-events: none; user-select: none;
  z-index: 1;
}

/* ===== 24. FOOTER ===== */
.site-footer {
  background: var(--espresso);
  color: rgba(255,255,255,.8);
  margin-top: clamp(40px, 6vw, 80px);
}
.footer-top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: 32px;
  padding-block: clamp(48px, 7vw, 72px);
}
.footer-logo { height: 34px; width: auto; margin-bottom: 16px; }
.site-footer h4 {
  color: var(--white);
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  margin-bottom: 16px;
}
.site-footer p { font-size: 14px; color: rgba(255,255,255,.58); line-height: 1.7; }
.footer-links { list-style: none; }
.footer-links li { margin-bottom: 10px; }
.footer-links a {
  color: rgba(255,255,255,.58);
  font-size: 14px;
  transition: color var(--t-fast);
}
.footer-links a:hover { color: var(--caramel); }
.footer-links a:active { color: var(--caramel); opacity: 0.75; }
.footer-phone { margin-top: 16px; }
.footer-phone a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: rgba(255,255,255,.58);
  font-size: 14px;
  letter-spacing: .3px;
  transition: color var(--t-fast);
}
.footer-phone a:hover { color: var(--caramel); }
.footer-phone a:active { color: var(--caramel); opacity: 0.75; }
.footer-phone__ic { flex: none; opacity: .85; }
.newsletter { display: flex; gap: 8px; margin-top: 12px; }
.newsletter input {
  flex: 1; padding: 10px 14px;
  border: 1px solid rgba(255,255,255,.15);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.07);
  font-family: var(--font-body);
  color: var(--white); font-size: 14px;
}
.newsletter input::placeholder { color: rgba(255,255,255,.35); }
.newsletter input:focus { outline: none; border-color: var(--caramel); }
.newsletter .btn { flex-shrink: 0; padding: 10px 18px; font-size: 14px; }

.socials { display: flex; gap: 8px; margin-top: 16px; }
.socials a {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.12);
  display: inline-flex;
  align-items: center; justify-content: center;
  color: rgba(255,255,255,.65);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.socials a:hover {
  background: var(--caramel);
  color: var(--espresso);
  border-color: var(--caramel);
}
.socials a:active,
.socials a.is-pressed { background: var(--caramel); color: var(--espresso); border-color: var(--caramel); transform: scale(0.9); transition-duration: 80ms; }
.socials a svg { width: 16px; height: 16px; fill: currentColor; }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.08);
  padding-block: 18px;
  text-align: center;
  font-size: 13px;
  color: rgba(255,255,255,.38);
}

/* ===== 25. FORMS (global) ===== */
input, select, textarea, button {
  font-family: var(--font-body);
}

/* ===== 26. FLASH / ALERTS ===== */
#flash-host {
  position: fixed;
  inset-inline: 0;
  top: 0;
  z-index: var(--z-toast);
}
.flash {
  padding: 12px 18px;
  border-radius: var(--radius-sm);
  margin-bottom: 16px;
  font-weight: 600;
  font-size: 14px;
}
.flash-success { background: #e6f2eb; color: var(--success); border: 1px solid #c3dece; }
.flash-error   { background: #f8e7e3; color: var(--danger);  border: 1px solid #ecc5bb; }

/* ===== 27. PAGINATION ===== */
.pagination {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin-top: 48px;
  flex-wrap: wrap;
}
.pagination a,
.pagination span {
  min-width: 40px; height: 40px;
  padding: 0 12px;
  display: inline-flex;
  align-items: center; justify-content: center;
  border: 1px solid var(--linen);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--stone);
  font-weight: 600;
  font-size: 14px;
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.pagination a:hover { border-color: var(--copper); color: var(--copper); }
.pagination a:active,
.pagination a.is-pressed { border-color: var(--copper); color: var(--copper); background: var(--foam-mid); transform: scale(0.92); transition-duration: 80ms; }
.pagination .is-active { background: var(--espresso); color: var(--white); border-color: var(--espresso); }
.pagination .is-disabled { opacity: .4; pointer-events: none; }

/* ===== 28. ACCOUNT PAGES ===== */
.account-layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 28px;
  padding-block: 48px;
  align-items: start;
}
.account-nav {
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-lg);
  padding: 8px;
}
.account-nav a {
  display: block;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  color: var(--stone);
  font-weight: 600;
  font-size: 14px;
  transition: background var(--t-fast), color var(--t-fast);
}
.account-nav a:hover,
.account-nav a.active { background: var(--foam-mid); color: var(--espresso); }
.account-nav a:active { background: var(--foam-dark); color: var(--espresso); }
.account-card {
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-lg);
  padding: 28px;
}

/* ===== 29. FADE-UP ANIMATION (IntersectionObserver-driven) ===== */
@media (prefers-reduced-motion: no-preference) {
  .fade-up {
    opacity: 0;
    transform: translateY(36px);
    transition: opacity .65s ease, transform .65s cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 60ms);
  }
  .fade-up.visible {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ===== 30. REDUCED MOTION ===== */
@media (prefers-reduced-motion: reduce) {
  .marquee-inner { animation: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ===== 31. RESPONSIVE ===== */

/* ── Tablet landscape: 1024px ── */
@media (max-width: 1024px) {
  .product-grid  { grid-template-columns: repeat(3, 1fr); }
  .cat-grid      { grid-template-columns: repeat(3, 1fr); }
  .footer-top    { grid-template-columns: 1fr 1fr; gap: 24px; }
  .hero-inner    { gap: 32px; }
  .features      { grid-template-columns: repeat(2, 1fr); }
}

/* ── Tablet: 768px ── */
@media (max-width: 768px) {
  .product-grid  { grid-template-columns: repeat(2, 1fr); gap: 12px; }
  .cat-grid      { grid-template-columns: repeat(2, 1fr); gap: 10px; }

  /* Thumb is square at every breakpoint now — only inset and radius differ. */
  .product-card  { border-radius: 8px 16px 8px 8px; }
  .product-thumb { margin: 6px 6px 0; border-radius: 9px 18px 9px 9px; }
  .product-body  { padding: 9px 9px 4px; }
  .product-foot  { padding: 0 7px 9px; gap: 6px; }
  .product-name  { font-size: 13px; line-height: 1.35; }
  .product-cue   { margin-top: 3px; font-size: 12px; }
  .product-quick-trigger { width: 36px; height: 36px; }
  .product-quick-trigger svg { width: 16px; height: 16px; }
  .product-detail{ grid-template-columns: 1fr; gap: 28px; }
  .cart-wrap     { grid-template-columns: 1fr; }

  /* Listing/category/search mobile polish */
  .page-head        { padding-block: 28px 24px; }
  .toolbar          { margin-bottom: 18px; }
  .brand-story-inner { grid-template-columns: 1fr; }

  /* Product page — mobile purchase flow */
  .product-info h1 {
    line-height: 1.4;
    word-break: break-word;
    overflow-wrap: break-word;
    margin-bottom: 12px;
  }
  .stock-row     { margin-block: 12px 0; }
  .product-trust { margin-top: 10px; padding-top: 10px; }
  .product-desc  { margin-block: 14px; font-size: 14px; }
  .qty-row       { margin-block: 14px; }
  .brand-story-img   { display: none; }
  .account-layout    { grid-template-columns: 1fr; }

  /* Hero collapses */
  .hero-inner    { grid-template-columns: 1fr; text-align: center; }
  .hero::after   { display: none; }
  .hero-cta      { justify-content: center; }
  .hero-media    { display: none; }
  .hero-brands   { justify-content: center; }
  .hero-sub      { margin-inline: auto; }

  /* Hide desktop nav */
  .nav                          { display: none; }
  /* Account access already exists in the mobile drawer (.nav-account-item);
     avoid duplicating it in the already-tight mobile icon row. */
  .header-account-btn           { display: none; }

  /* Mobile sidebar — physical right + direction:rtl
     right: anchors the drawer to the RIGHT side of the viewport.
     direction:rtl keeps Arabic nav-link text correctly right-aligned. */
  .nav {
    display: flex;
    position: fixed;
    top: 0;
    right: -110%;
    direction: rtl;
    width: min(280px, 80vw);
    height: 100dvh;
    background: var(--foam);
    border-left: 1px solid var(--linen);
    flex-direction: column;
    align-items: flex-start;
    padding: 32px 20px;
    gap: 2px;
    z-index: var(--z-nav);
    box-shadow: var(--shadow-lg);
    transition: right .35s cubic-bezier(.4,0,.2,1);
    overflow-y: auto;
    /* NO overflow:hidden, NO backdrop-filter */
  }
  .nav.open {
    right: 0;
  }
  .nav .navlink {
    width: 100%;
    font-size: 17px;
    padding: 13px 14px;
    border-radius: var(--radius-sm);
  }
  .nav-account-item {
    display: block;
    border-top: 1px solid var(--linen);
    margin-top: 12px;
    padding-top: 12px;
  }
  .nav-toggle { display: inline-flex; }

  /* Category accordion — same cached data as desktop, rendered as a nested
     two-level list instead of a hover panel. Only categories that actually
     have subcategories get the expand chevron; the rest are plain links. */
  .nav-cats-item { width: 100%; }
  .nav-cats-trigger { width: 100%; justify-content: space-between; }
  .nav-cats-trigger[aria-expanded="true"] {
    background: none;
    border-radius: var(--radius-sm);
  }
  /* chevron rotation is handled by the shared [aria-expanded] .nav-chevron rule */
  .nav-cats-panel {
    position: static;
    border: none;
    box-shadow: none;
    background: none;
    padding: 0 0 0 14px;
    min-width: 0;
    opacity: 1;
  }
  .nav-cats-panel:not([hidden]) { display: block; }
  .nav-cats-detail { display: none; } /* desktop-only right pane */

  .nav-cats-list { gap: 0; padding-inline-end: 0; }
  .nav-cats-mrow { border-top: 1px solid var(--linen); }
  .nav-cats-mrow:first-child { border-top: none; }

  .nav-cats-mrow-toggle,
  .nav-cats-mrow-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 11px 2px;
    font-size: 14px;
    font-family: var(--font-body);
    color: var(--stone);
    background: none;
    border: none;
    text-align: inherit;
    text-decoration: none;
    cursor: pointer;
  }
  .nav-cats-mrow-toggle.is-open { font-weight: 600; color: var(--espresso); }
  .nav-cats-chevron { color: var(--stone-light, var(--stone)); flex-shrink: 0; }
  @media (prefers-reduced-motion: no-preference) {
    .nav-cats-chevron { transition: transform .2s ease; }
  }
  .nav-cats-mrow-toggle.is-open .nav-cats-chevron { transform: rotate(180deg); }

  .nav-cats-msublist[hidden] { display: none; }
  .nav-cats-msublist:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: 9px;
    padding: 0 2px 12px 14px;
  }
  .nav-cats-msub { font-size: 13px; color: var(--stone); text-decoration: none; }
  .nav-cats-msub--cta { color: var(--copper); }
  .nav-cats-msub--parent {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-size: 13px;
    color: var(--espresso);
    cursor: pointer;
    text-align: start;
  }
  .nav-cats-msub--parent.is-open { font-weight: 600; }
  .nav-cats-msubsublist[hidden] { display: none; }
  .nav-cats-msubsublist:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 2px 4px 14px;
    margin-inline-start: 2px;
    border-inline-start: 1px solid var(--linen);
  }
  .nav-cats-msubsub { font-size: 12.5px; color: var(--stone); text-decoration: none; }

  /* Promo cards */
  .promo-card {
    flex-direction: column !important;
    min-height: auto; gap: 20px;
  }
  .promo-card__media { flex: unset; max-width: 100%; }
}

/* ── Mobile: 640px — footer + newsletter ── */
@media (max-width: 640px) {
  .footer-top { grid-template-columns: 1fr; gap: 28px; }

  /* stack newsletter form so زر اشتراك لا يطلع بره */
  .newsletter { flex-direction: column; gap: 10px; }
  .newsletter input { width: 100%; min-width: 0; }
  .newsletter .btn  { width: 100%; }
}

/* ── Mobile: 480px ── */
@media (max-width: 480px) {
  .features   { grid-template-columns: 1fr 1fr; }
  .hero h1    { font-size: clamp(30px, 9vw, 48px); }

  /* Product card — tighter inset + body for narrow 2-col cards */
  .product-card  { border-radius: 9px 18px 9px 9px; }
  .product-thumb { margin: 8px 8px 0; border-radius: 10px 20px 10px 10px; }
  .product-body  { padding: 10px 11px 6px; }
  .product-foot  { padding: 0 8px 11px; gap: 8px; }
  .product-quick-trigger { width: 44px; height: 44px; }
  .product-quick-trigger svg { width: 18px; height: 18px; }
  .product-name  { font-size: 13.5px; }
  .product-cue   { margin-top: 6px; font-size: 12px; }

  /* Search overlay — reduce top offset so keyboard doesn't push it off-screen */
  .search-overlay { padding-block-start: 48px; padding-inline: 14px; }

  /* Listing/search page h1 — reduce size so "نتائج البحث عن: …" is not dominant */
  .page-head h1 { font-size: clamp(20px, 5.5vw, 26px); line-height: 1.15; }

  /* Product page — narrowest phones */
  .product-info h1   { font-size: clamp(20px, 5.5vw, 26px); }
  .product-info .price { font-size: 26px; }
  /* Sticky bar: compact button so product name has more room */
  .sticky-atc-btn    { padding: 10px 16px; font-size: 13px; }
}

/* ===== 32. UTILITIES ===== */
.text-center  { text-align: center; }
.text-copper  { color: var(--copper); }
.text-stone   { color: var(--stone); }
.bg-foam      { background: var(--foam); }
.bg-foam-mid  { background: var(--foam-mid); }
.bg-espresso  { background: var(--espresso); color: var(--white); }
.bg-mint-soft { background: var(--mint-soft); }
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ═══════════════════════════════════════════════
   HOME V2 — NEW SECTIONS
   ═══════════════════════════════════════════════ */

/* ── Hero V2 ── */
.hero-v2 {
  position: relative;
  padding-block: clamp(36px, 5vw, 72px);
  background: var(--foam);
  overflow: hidden;
}
.hero-blob {
  position: absolute;
  inset-inline-end: 0;
  top: 0;
  width: 45%;
  height: 100%;
  background: radial-gradient(ellipse 90% 80% at 100% 40%, var(--foam-mid) 0%, transparent 70%);
  pointer-events: none;
}
.hero-v2-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  align-items: center;
  gap: clamp(40px, 6vw, 80px);
}

/* eyebrow with pulse dot */
.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  font-weight: 700;
  color: var(--stone);
  text-transform: uppercase;
  margin-bottom: 20px;
}
.hero-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--copper);
  flex-shrink: 0;
  animation: hero-dot-pulse 2.4s ease infinite;
}
@keyframes hero-dot-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(181,98,42,.5); }
  50%      { box-shadow: 0 0 0 7px rgba(181,98,42,0); }
}

/* big title */
.hero-v2-title {
  font-family: var(--font-head);
  font-size: clamp(40px, 6.5vw, 76px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--espresso);
  margin-bottom: 20px;
}
.hero-line-1 { display: block; }
.hero-line-2 { display: block; color: var(--copper); }

.hero-v2-desc {
  font-size: clamp(15px, 1.8vw, 17px);
  color: var(--stone);
  max-width: 42ch;
  line-height: 1.75;
  margin-bottom: 32px;
}
.hero-v2-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 32px;
}
/* visual side */
.hero-v2-visual { position: relative; }
.hero-v2-frame {
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-xl);
  overflow: hidden;
  background: var(--foam-dark);
  box-shadow: var(--shadow-lg);
  max-height: 540px;
}
.hero-v2-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.hero-v2-frame .img-placeholder {
  object-fit: contain;
  padding: 20%;
  opacity: .5;
}

/* floating badges */
.hbadge {
  position: absolute;
  background: var(--white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--linen);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px;
  font-size: 12px;
  font-weight: 700;
  color: var(--espresso);
  z-index: 3;
  white-space: nowrap;
}
.hbadge svg {
  width: 15px;
  height: 15px;
  stroke: var(--copper);
  flex-shrink: 0;
}
.hbadge--ship {
  top: 20px;
  inset-inline-start: -16px;
}
.hbadge--stat {
  bottom: 32px;
  inset-inline-end: -16px;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 14px 20px;
}
.hbadge-num {
  font-family: var(--font-accent);
  font-size: 30px;
  font-weight: 700;
  color: var(--copper);
  line-height: 1;
}
.hbadge-label {
  font-size: 11px;
  color: var(--stone);
  font-weight: 600;
}

/* ── Hero Brand Panel — editorial warm surface, intentional without product image ── */
.hero-brand-panel {
  aspect-ratio: 4 / 5;
  max-height: 460px;
  border-radius: var(--radius-xl);
  background: linear-gradient(158deg, var(--foam-mid) 0%, var(--foam-dark) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}
.hero-panel-rings {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.hero-panel-rings::before,
.hero-panel-rings::after {
  content: '';
  position: absolute;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.hero-panel-rings::before {
  width: 260px;
  height: 260px;
  border: 1px solid rgba(45,28,28,.07);
}
.hero-panel-rings::after {
  width: 160px;
  height: 160px;
  border: 1px solid rgba(45,28,28,.11);
}
.hero-panel-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 28px;
}
.hero-panel-mark {
  width: 52px;
  height: 52px;
  object-fit: contain;
  opacity: 0.38;
}
.hero-panel-rule {
  width: 28px;
  height: 1.5px;
  background: var(--copper);
  border-radius: 1px;
  opacity: 0.55;
}
.hero-panel-tagline {
  font-family: var(--font-head);
  font-size: clamp(18px, 2vw, 21px);
  font-weight: 700;
  color: var(--espresso);
  line-height: 1.4;
  letter-spacing: -0.01em;
  opacity: 0.88;
}
.hero-panel-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-top: 10px;
  padding-top: 16px;
  border-top: 1px solid rgba(45,28,28,.10);
  width: 80%;
}
.hero-panel-stat-num {
  font-family: var(--font-accent);
  font-size: 32px;
  font-weight: 700;
  color: var(--copper);
  line-height: 1;
}
.hero-panel-stat-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--stone);
}

/* ── Stats Strip ── */
.stats-strip {
  background: var(--white);
  border-top: 1px solid var(--linen);
  border-bottom: 1px solid var(--linen);
  padding-block: 32px;
}
.stats-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  flex-wrap: wrap;
}
.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding-inline: clamp(24px, 4vw, 60px);
  text-align: center;
}
.stat-num {
  font-family: var(--font-accent);
  font-size: clamp(36px, 5vw, 52px);
  font-weight: 700;
  color: var(--copper);
  line-height: 1;
}
.stat-unit {
  font-size: .55em;
  font-weight: 700;
  color: var(--stone);
}
.stat-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--stone);
}
.stat-divider {
  width: 1px;
  height: 40px;
  background: var(--linen);
  flex-shrink: 0;
}

/* Category pills/section were removed from the homepage body (2026-06-18);
   categories now live only in the top navigation. This general page-head
   adjacency rule is retained — it applies to listing/category/search pages. */
.page-head + .section { padding-block-start: clamp(24px, 3vw, 36px); }


/* ── Bento Features ── */
.bento-section {
  padding-block: var(--section-v);
  background: var(--foam);
}
.bento-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 16px;
}
.bento-card {
  background: var(--white);
  border: 1.5px solid var(--linen);
  border-radius: var(--radius-xl);
  padding: clamp(24px, 3vw, 36px);
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform var(--t-base), box-shadow var(--t-base);
  cursor: default;
}
.bento-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
}

/* big main card spans 2 rows */
.bento-card--main { grid-row: span 2; }

/* dark espresso card */
.bento-card--dark {
  background: var(--espresso);
  border-color: var(--espresso);
}
.bento-card--dark h3 { color: var(--white); }
.bento-card--dark p  { color: rgba(255,255,255,.62); }

/* copper accent card */
.bento-card--copper {
  background: var(--copper);
  border-color: var(--copper);
}
.bento-card--copper h3 { color: var(--white); }
.bento-card--copper p  { color: rgba(255,255,255,.72); }

/* light foam card */
.bento-card--light {
  background: var(--foam);
  border-color: var(--foam-dark);
}

/* bento icon circle */
.bento-icon-wrap {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-bottom: 4px;
  background: rgba(255,255,255,.1);
}
.bento-card--light .bento-icon-wrap {
  background: var(--foam-mid);
}
.bento-icon-wrap svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--caramel);
}
.bento-card--dark  .bento-icon-wrap svg { color: var(--caramel); }
.bento-card--copper .bento-icon-wrap svg { color: var(--white); }
.bento-card--light  .bento-icon-wrap svg { color: var(--copper); }

/* big accent number inside bento */
.bento-main-num {
  font-family: var(--font-accent);
  font-size: clamp(44px, 5vw, 64px);
  font-weight: 700;
  color: var(--caramel);
  line-height: 1;
}
.bento-days-num {
  font-family: var(--font-accent);
  font-size: clamp(36px, 4vw, 52px);
  font-weight: 700;
  color: var(--copper);
  line-height: 1;
}

.bento-card h3 {
  font-size: clamp(17px, 2.2vw, 21px);
  margin: 0;
  line-height: 1.2;
  color: var(--espresso);
}
.bento-card p {
  font-size: 14px;
  line-height: 1.65;
  color: var(--stone);
  margin: 0;
}

/* ── Brand Story V2 ── */
.brand-story-v2 {
  background: var(--espresso);
  color: var(--white);
  padding-block: clamp(64px, 10vw, 120px);
  position: relative;
  overflow: hidden;
}
.brand-story-v2-inner {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(40px, 6vw, 80px);
  align-items: center;
}
.brand-story-v2-text .eyebrow { color: var(--caramel); }
.brand-story-v2-text h2 {
  color: var(--white);
  font-size: clamp(28px, 5vw, 54px);
  margin-block: 12px 20px;
  line-height: 1.1;
}
.brand-story-v2-text p {
  color: rgba(255,255,255,.68);
  font-size: 17px;
  line-height: 1.85;
  max-width: 52ch;
}
.brand-story-v2-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 32px;
}

/* decorative side */
.brand-story-v2-deco {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.bs-watermark {
  font-family: var(--font-accent);
  font-size: clamp(60px, 10vw, 140px);
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255,255,255,.07);
  letter-spacing: -.02em;
  user-select: none;
  pointer-events: none;
  white-space: nowrap;
}
.bs-logo {
  position: absolute;
  width: clamp(80px, 10vw, 130px);
  height: auto;
  opacity: .9;
}

/* ═══════════════════════════════════════════════
   HOME V2 — RESPONSIVE
   ═══════════════════════════════════════════════ */

/* Tablet 1024px */
@media (max-width: 1024px) {
  .hero-v2-inner { grid-template-columns: 1fr 1fr; gap: 32px; }
  .bento-grid { grid-template-columns: 1.2fr 1fr; grid-template-rows: auto auto auto; }
  .bento-card--main { grid-row: span 1; grid-column: span 2; }
  .brand-story-v2-inner { grid-template-columns: 1fr; }
  .brand-story-v2-deco { display: none; }
}

/* Tablet 768px */
@media (max-width: 768px) {
  .hero-v2-inner { grid-template-columns: 1fr; }
  .hero-v2-visual { display: none; }
  .hero-v2-copy { text-align: center; }
  .hero-v2-cta { justify-content: center; }
  .hero-v2-desc { margin-inline: auto; }

  .bento-grid { grid-template-columns: 1fr 1fr; }
  .bento-card--main { grid-column: span 2; }
  .stats-inner { gap: 0; }
  .stat-item { padding-inline: clamp(16px, 3vw, 32px); }
}

/* Mobile 640px */
@media (max-width: 640px) {
  .bento-grid { grid-template-columns: 1fr; }
  .bento-card--main { grid-column: span 1; }
  .stat-divider { display: none; }
  .stats-inner { gap: 12px 0; }
  .stat-item { padding-inline: 20px; flex-direction: row; gap: 12px; }
  .stat-num { font-size: 28px; }
}


/* Brand Strip: CSS removed 2026-06-23, source files (brand-strip.jinja/
   .schema.json) deleted 2026-07-01 (architecture audit, Tier 1 cleanup).
   Superseded entirely by the Featured Brands section. */

/* ════════════════════════════════════════════════════════════
   BRAND FILTER CHIPS — category & products pages toolbar
════════════════════════════════════════════════════════════ */

.search-heading-term {
  color: var(--copper);
  font-weight: 400;
}
/* ════════════════════════════════════════════════════════════
   SEARCH OVERLAY — full-viewport search experience
════════════════════════════════════════════════════════════ */

.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: rgba(26, 18, 8, 0.88);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-block-start: clamp(72px, 14vw, 130px);
  padding-inline: var(--gap);
  opacity: 0;
  pointer-events: none;
  /* Matches the nav drawer / sticky ATC bar's considered curve — the same
     overlay-reveal category, previously on a generic "ease" instead. */
  transition: opacity 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
.search-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.search-close-btn {
  position: fixed;
  top: 16px;
  right: 16px;
  background: rgba(255, 255, 255, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: white;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast), transform var(--t-fast);
}
.search-close-btn:hover { background: rgba(255, 255, 255, 0.22); }
.search-close-btn:active,
.search-close-btn.is-pressed { background: rgba(255, 255, 255, 0.3); transform: scale(0.9); transition-duration: 80ms; }

.search-inner { width: 100%; max-width: 620px; }

.search-label {
  display: block;
  font-family: var(--font-head);
  font-size: clamp(22px, 4vw, 32px);
  font-weight: 900;
  color: white;
  margin-block-end: 18px;
}

.search-input-wrap { position: relative; }

.search-input {
  width: 100%;
  background: white;
  border: 2px solid transparent;
  border-radius: 14px;
  padding: 16px 56px 16px 20px;
  font-size: 16px;
  font-family: var(--font-body);
  color: var(--ink);
  outline: none;
  transition: border-color var(--t-fast);
  box-sizing: border-box;
}
.search-input:focus { border-color: var(--copper); }
.search-input::placeholder { color: var(--stone); }

.search-submit {
  position: absolute;
  inset-block: 8px;
  inset-inline-end: 8px;
  background: var(--copper);
  border: none;
  border-radius: 10px;
  width: 40px;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast), transform var(--t-fast);
}
.search-submit:hover { background: var(--espresso); }
.search-submit:active,
.search-submit.is-pressed { background: var(--espresso); transform: scale(0.9); transition-duration: 80ms; }

.search-quick-links {
  margin-block-start: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.search-quick-label { font-size: 12px; color: rgba(255, 255, 255, 0.55); }

.search-quick-link {
  display: inline-block;
  padding: 4px 12px;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 100px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
  transition: background var(--t-fast), transform var(--t-fast);
}
.search-quick-link:hover { background: rgba(255, 255, 255, 0.2); color: white; }
.search-quick-link:active,
.search-quick-link.is-pressed { background: rgba(255, 255, 255, 0.3); color: white; transform: scale(0.92); transition-duration: 80ms; }

/* ── Search autocomplete dropdown ───────────────────────── */
.search-suggestions {
  position: absolute;
  inset-block-start: calc(100% + 4px);
  inset-inline-start: 0;
  inset-inline-end: 0;
  background: white;
  border-radius: 10px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.15);
  list-style: none;
  margin: 0;
  padding: 4px 0;
  z-index: 10;
  overflow: hidden;
}
.search-suggestions[hidden] { display: none; }

.sug-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 14px;
  font-size: 14px;
  color: var(--espresso);
  cursor: pointer;
  transition: background 0.1s;
  unicode-bidi: isolate;
}
.sug-item:hover,
.sug-item.is-active { background: var(--foam); }
.sug-item:active { background: var(--foam-mid); }

.sug-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  opacity: 0.38;
}

.sug-item--product {
  align-items: center;
  gap: 12px;
  padding: 7px 14px;
}
.sug-prod-img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
  background: var(--foam);
}
.sug-prod-img--placeholder {
  width: 44px;
  height: 44px;
  border-radius: 6px;
  flex-shrink: 0;
  background: var(--foam);
}
.sug-prod-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.sug-prod-name {
  font-size: 13px;
  color: var(--espresso);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sug-prod-price {
  font-family: var(--font-numeric);
  font-size: 12px;
  color: var(--copper);
  font-weight: 700;
}

.sug-item--all {
  border-block-start: 1px solid var(--foam);
  margin-block-start: 2px;
  padding-block-start: 10px;
  font-size: 13px;
  color: var(--copper);
}
.sug-item--all .sug-icon { opacity: 0.7; color: var(--copper); }
.sug-item--all strong { font-weight: 600; }

/* ════════════════════════════════════════════════════════════
   STAGGER GRID — parent-triggered child animations
════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: no-preference) {
  .stagger-grid.js-loaded > * {
    opacity: 0;
    transform: translateY(44px) scale(0.94);
    transition: opacity 0.6s ease, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: calc(var(--i, 0) * 110ms);
    will-change: opacity, transform;
  }
  .stagger-grid.stagger-visible > * {
    opacity: 1;
    transform: translateY(0) scale(1);
    will-change: auto;
  }
}

/* ════════════════════════════════════════════════════════════
   SORT SELECT — toolbar dropdown
════════════════════════════════════════════════════════════ */

.toolbar { flex-wrap: wrap; }

.sort-select {
  appearance: none;
  -webkit-appearance: none;
  padding: 7px 14px 7px 32px;
  border: 1px solid var(--linen);
  border-radius: 8px;
  background-color: white;
  font-size: 13px;
  font-family: var(--font-body);
  color: var(--ink);
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%238a7464' fill='none' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 10px center;
}
[dir=rtl] .sort-select {
  padding: 7px 32px 7px 14px;
  background-position: calc(100% - 10px) center;
}

/* ════════════════════════════════════════════════════════════
   STICKY ADD-TO-CART BAR — mobile product page
════════════════════════════════════════════════════════════ */

.sticky-atc {
  position: fixed;
  bottom: 0;
  inset-inline: 0;
  z-index: 90;
  background: white;
  border-block-start: 1px solid var(--linen);
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  transform: translateY(100%);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-shadow: 0 -4px 20px rgba(45, 28, 28, 0.1);
}
.sticky-atc.visible { transform: translateY(0); }

.sticky-atc-info { flex: 1; min-width: 0; }
.sticky-atc-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}
.sticky-atc-price {
  display: flex;
  align-items: baseline;
  gap: 7px;
  flex-wrap: wrap;
}
.sticky-price-sale {
  font-family: var(--font-numeric);
  font-size: 16px;
  font-weight: 700;
  color: var(--copper);
}
.sticky-price-orig {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 300;
  color: var(--stone-light);
  text-decoration: line-through;
  text-decoration-color: var(--stone-light);
}
@media (max-width: 380px) { .sticky-price-orig { display: none; } }
.sticky-atc-btn { flex-shrink: 0; padding: 10px 20px; font-size: 14px; white-space: nowrap; }

@media (min-width: 769px) { .sticky-atc { display: none !important; } }

/* ════════════════════════════════════════════════════════════
   RECENTLY VIEWED — product page section
════════════════════════════════════════════════════════════ */

.recently-viewed { padding-block: clamp(40px, 6vw, 72px); background: var(--foam); }

.rv-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  margin-block-start: 28px;
}

.rv-card {
  display: block;
  text-decoration: none;
  color: inherit;
  border-radius: 12px;
  overflow: hidden;
  background: white;
  border: 1px solid var(--linen);
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.42s ease, transform 0.42s ease, box-shadow var(--t-mid);
  transition-delay: calc(var(--i, 0) * 60ms);
}
.rv-card.visible { opacity: 1; transform: none; }
.rv-card:hover { box-shadow: var(--shadow-card); transform: translateY(-3px); }
.rv-card.visible:active,
.rv-card.visible.is-pressed { box-shadow: var(--shadow-sm); transform: scale(0.97); transition: transform 80ms ease, box-shadow 80ms ease; }

/* Square, not 3/2. A landscape frame was the worst crop on the page — it cut
   the product in half. Square matches both the photography and the card tile,
   so `cover` crops nothing. */
.rv-thumb { aspect-ratio: 1 / 1; overflow: hidden; background: var(--foam); }
.rv-thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.rv-card:hover .rv-thumb img { transform: scale(1.05); }

.rv-body { padding: 12px 14px; }
.rv-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  margin-block-end: 4px;
  line-height: 1.4;
}
.rv-price { font-family: var(--font-numeric); font-size: 15px; color: var(--copper); }

@media (max-width: 768px) { .rv-grid { grid-template-columns: repeat(2, 1fr); } }

/* Brewing Methods module CSS removed (2026-07-01) — orphaned, unused by
   any shipped section (offers-cta-section.jinja, formerly this file's
   namesake, uses the generic .section/.eyebrow classes instead), and
   contained a broken reference to an undefined --t-mid token. Predates
   the frozen editorial language established during the Brands work;
   the real Brewing Methods section will be designed fresh from that
   language, not from this. See docs/MOTION-LANGUAGE.md Part IV §IV.6
   for the full reasoning. */

/* ════════════════════════════════════════════════════════════
   RESPONSIVE: new sections on small screens
════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .search-overlay { padding-block-start: 56px; }
}

/* ════════════════════════════════════════════════════════════
   HERO ENTRANCE — page-load staggered reveal
   Plays once on first paint; spring easing for premium feel.
════════════════════════════════════════════════════════════ */

@keyframes droplet-rise {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: no-preference) {
  .hero-eyebrow {
    animation: droplet-rise 0.65s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: 0.08s;
  }
  .hero-v2-title {
    animation: droplet-rise 0.75s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: 0.22s;
  }
  .hero-v2-desc {
    animation: droplet-rise 0.65s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: 0.38s;
  }
  .hero-v2-cta {
    animation: droplet-rise 0.65s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: 0.50s;
  }
  .hero-v2-visual {
    animation: droplet-rise 0.8s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: 0.14s;
  }
}

/* ════════════════════════════════════════════════════════════
   PRODUCT CARD IMAGE — zoom-settle entrance inside stagger
   Image scales in from 1.07 → 1 while the card rises up,
   giving a rich "settling" feel without heavy animation.
════════════════════════════════════════════════════════════ */

@keyframes img-zoom-settle {
  from { transform: scale(1.1); }
  to   { transform: scale(1); }
}

@media (prefers-reduced-motion: no-preference) {
  .stagger-grid.stagger-visible > * .product-thumb img {
    animation: img-zoom-settle 1s cubic-bezier(0.16, 1, 0.3, 1) both;
    animation-delay: calc(var(--i, 0) * 110ms + 80ms);
  }
}

/* ════════════════════════════════════════════════════════════
   PAGE ENTRANCE — soft fade+rise for non-home pages
   Homepage hero has its own staggered entrance, so JS only
   adds .page-enter to .site-main when no hero is present.
════════════════════════════════════════════════════════════ */

@keyframes page-enter {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: no-preference) {
  .site-main.page-enter {
    animation: page-enter 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
  }
}

/* ════════════════════════════════════════════════════════════
   CURSOR POLISH — ensure all interactive surfaces feel clickable
════════════════════════════════════════════════════════════ */
.product-card,
.cat-pill,
.cat-card,
.rv-card { cursor: pointer; }

/* ── Announcement Bar ────────────────────────── */
.announcement-bar {
    background: var(--copper);
    color: #fff;
    text-align: center;
    padding: 10px 48px 10px 16px;
    font-size: 13px;
    font-weight: 500;
    position: relative;
    line-height: 1.4;
}
.announcement-bar-inner {
    max-width: var(--container);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
}
.announcement-bar-close {
    position: absolute;
    inset-inline-end: 12px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    padding: 4px;
    display: flex;
    align-items: center;
    transition: transform var(--t-fast);
}
.announcement-bar-close:active,
.announcement-bar-close.is-pressed { transform: translateY(-50%) scale(0.85); transition-duration: 80ms; }
.announcement-bar-close svg { width: 16px; height: 16px; }
.announcement-bar-text { flex: 1; min-width: 0; }
.announcement-bar-link { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.announcement-bar-link:hover { opacity: 0.85; }


/* ── Shared rail visual language (Products section, Horizontal Scroll mode) ──
   Originally built for the now-retired homepage SDK rail; kept here because
   sections/products-section.jinja reuses this exact head structure and scroll
   container so both experiences stay one family. Lives inside .container
   (centered, max-width var(--container)) so it never touches the viewport
   edges. Desktop shows a tidy 4-up row; narrower viewports show fewer with a
   partial-peek + horizontal swipe. */
.rail-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin-block-end: clamp(18px, 3vw, 28px);
}
.rail-head-start { text-align: start; }
.rail-title {
    font-family: var(--font-head);
    font-size: clamp(24px, 4vw, 34px);
    font-weight: 700;
    color: var(--espresso);
    margin-block-start: 6px;
}
.rail-browse-link {
    font-size: 13px;
    font-family: var(--font-body);
    color: var(--stone);
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    transition: color var(--t-fast);
}
.rail-browse-link:active { color: var(--copper); opacity: 0.7; }
@media (hover: hover) {
    .rail-browse-link:hover { color: var(--copper); }
}
/* Rail prev/next arrows — attached to the rail itself (one on each side,
   vertically centered on the cards, slightly overlapping the viewport
   edge), not to the section header — they control the cards, not the
   title. Same interactive vocabulary as .qty-btn (cart stepper):
   transparent, copper fill on hover/press, --stone-light when disabled.
   Hidden entirely (not just disabled) when the list doesn't overflow one
   viewport, or on touch-only devices where swipe already covers this and
   a non-functional-looking control would be clutter. */
.rail-viewport { position: relative; }
.rail-arrows { position: absolute; inset: 0; display: none; pointer-events: none; }
@media (hover: hover) {
    .rail-arrows.is-active { display: block; }
    .rail-arrow {
        position: absolute;
        top: 50%;
        --rail-arrow-x: 0px;
        --rail-arrow-scale: 1;
        transform: translateY(-50%) translateX(var(--rail-arrow-x)) scale(var(--rail-arrow-scale));
        opacity: 1;
        z-index: 2;
        pointer-events: auto;
        width: 30px; height: 30px;
        border: 1px solid var(--linen);
        border-radius: 50%;
        background: var(--white);
        color: var(--espresso);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        box-shadow: 0 0 0 rgba(45,28,28,0);
        transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
        outline: none;
    }
    /* Logical, not physical: in this RTL rail the first card sits at the
       physical right (inline-start), so "prev" (back toward it) anchors
       inline-start and "next" (toward later cards, physical left) anchors
       inline-end — matches the "←" = forward convention used elsewhere. */
    .rail-arrow--prev { inset-inline-start: -14px; }
    .rail-arrow--next { inset-inline-end: -14px; }
    .rail-arrow svg { width: 16px; height: 16px; }
    /* No shadow at rest — a permanently shadowed circle sitting on top of
       product photography reads as persistent UI chrome, not a quiet
       affordance. Weight is revealed on interaction only, same as every
       other restrained hover cue in this theme (rail-browse-link, product
       card cue, etc.) — the arrow should feel discovered, not installed. */
    .rail-arrow:hover:not(:disabled) { background: var(--copper); border-color: var(--copper); color: #fff; box-shadow: 0 2px 10px rgba(45,28,28,.08); }
    .rail-arrow:focus-visible {
        outline: 2px solid var(--copper);
        outline-offset: 2px;
    }
    .rail-arrow:active:not(:disabled),
    .rail-arrow.is-pressed:not(:disabled) { --rail-arrow-scale: 0.92; }
    /* Hidden at the extreme it points toward — quietly communicates where
       the visitor is in the rail rather than just disabling a click.
       Recedes outward (away from the cards, toward its own edge) rather
       than shrinking in place. Pointer-events off during the hidden state;
       :disabled already removes it from tab order. */
    .rail-arrow:disabled {
        opacity: 0;
        pointer-events: none;
        color: var(--stone-light);
        border-color: var(--linen);
        background: var(--white);
        cursor: default;
    }
    .rail-arrow--prev:disabled { --rail-arrow-x: 8px; --rail-arrow-scale: 0.9; }
    .rail-arrow--next:disabled { --rail-arrow-x: -8px; --rail-arrow-scale: 0.9; }
    @media (prefers-reduced-motion: no-preference) {
        .rail-arrow { transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast), opacity 200ms cubic-bezier(.4,0,.2,1), transform 200ms cubic-bezier(.4,0,.2,1); }
    }
}
.rail-scroll-wrap {
    overflow-x: auto;
    padding-block: 16px 24px;   /* breathing room so scale/lift never clips */
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* proximity, not mandatory: on reload the browser restores this element's
       saved scrollLeft, and a mandatory snap then drags the rail to whichever
       card is nearest that restored offset — landing the customer deep in the
       list instead of at its start. Intermittent by nature, since it only
       fires when a scroll position was saved. Proximity keeps the settle
       behaviour for deliberate swipes without seizing on restore. */
    scroll-snap-type: x proximity;
    /* Restore is refused outright — a product rail has no reading position
       worth preserving across a reload, unlike the page itself. */
    overflow-anchor: none;
}
.rail-scroll-wrap::-webkit-scrollbar { display: none; }
.rail-scroll {
    display: flex;
    gap: var(--gap);
}
/* Desktop: 4-up row, centered snap. Cards sized to fit N per view exactly. */
.rail-scroll .product-card {
    flex: 0 0 auto;
    width: calc((100% - 3 * var(--gap)) / 4);   /* 4 per view — desktop */
    scroll-snap-align: center;
}
@media (max-width: 1024px) {
    .rail-scroll .product-card { width: calc((100% - 2 * var(--gap)) / 3); }   /* 3 per view */
}
/* Mobile carousel — one centered card, ~19vw peek on each side, plus a
   fixed +14px frame so the first/last cards read as intentionally framed
   rather than flush against the viewport edge. Cards are 62vw.
   Framing space is a pair of empty ::before/::after flex items on
   .rail-scroll, not padding or margin. Verified in-browser that browsers
   exclude a scroll container's own trailing padding, and a last/first
   child's own margin, from scrollWidth at the far end of a horizontal
   scroll-snap container (RTL or not) — so both of those approaches collapse
   to a flush edge at one end while still working at the other. A real flex
   item (which a pseudo-element on a flex container counts as) is always
   included in scrollWidth, so it's the only reliable way to frame both ends.
   scroll-padding-inline is kept in sync so the first card still snaps to
   visual center at scrollLeft=0.
   The wrap breaks out of the container so cards can reach viewport edges. */
@media (max-width: 768px) {
    .rail-scroll-wrap {
        margin-inline: calc(-1 * clamp(16px, 4vw, 32px));
        scroll-padding-inline: calc(19vw + 14px);
    }
    .rail-scroll .product-card {
        width: 62vw;
        scroll-snap-align: center;
    }
    .rail-scroll::before,
    .rail-scroll::after {
        content: '';
        flex: 0 0 auto;
        width: calc(19vw + 14px);
        display: block;
    }
}

/* ── Rail active-card focus effect ──────────────────────────────
   The card whose center sits closest to the scroll container's center
   gets .rail-card-active (set by JS). Active card lifts subtly;
   neighbours step back slightly. Idle breathing plays on the active
   card after ~1.8s of no scrolling. Values kept deliberately understated
   so the cue reads as a quiet focus shift, not a pop.
   All motion is gated by prefers-reduced-motion so it degrades cleanly. */
@media (prefers-reduced-motion: no-preference) {
    .rail-scroll .product-card {
        opacity: 0.92;
        transform: scale(0.985);
        transition: transform .35s cubic-bezier(.4,0,.2,1), box-shadow .35s, opacity .35s;
    }
    .rail-scroll .product-card.rail-card-active {
        opacity: 1;
        transform: translateY(-1px) scale(1.008);
        box-shadow: 0 6px 24px rgba(45,28,28,.11);
    }
    @media (hover: hover) {
        .rail-scroll .product-card.rail-card-active:hover {
            transform: translateY(-2px) scale(1.008);
        }
    }
    @keyframes rail-breathe {
        0%, 100% { transform: translateY(-1px) scale(1.008); }
        50%       { transform: translateY(-1.5px) scale(1.01); }
    }
    .products-section.rail-idle .rail-scroll .product-card.rail-card-active {
        animation: rail-breathe 3.2s ease-in-out infinite;
    }
}

/* ===== MARKETING BANNER — premium, minimal campaign banner ===== */
.marketing-banner {
  position: relative;
  overflow: hidden;
  padding-block: clamp(64px, 10vw, 120px);
  display: flex;
  align-items: center;
}
.marketing-banner__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.marketing-banner__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: #000;
}
.marketing-banner__overlay--light  { opacity: .2; }
.marketing-banner__overlay--medium { opacity: .4; }
.marketing-banner__overlay--strong { opacity: .6; }

.marketing-banner__inner {
  position: relative;
  z-index: 2;
  width: 100%;
}
.marketing-banner__content {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 560px;
}
.marketing-banner--align-center .marketing-banner__content { margin-inline: auto; align-items: center; text-align: center; }
.marketing-banner--align-left   .marketing-banner__content { margin-inline-end: auto; align-items: flex-start; text-align: left; }
.marketing-banner--align-right  .marketing-banner__content { margin-inline-start: auto; align-items: flex-end; text-align: right; }

.marketing-banner__subtitle {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  opacity: .85;
  margin: 0;
}
.marketing-banner__title {
  font-family: var(--font-head);
  font-size: clamp(28px, 4.5vw, 48px);
  font-weight: 700;
  line-height: 1.2;
  color: inherit;
  margin: 0;
}
.marketing-banner__btn { margin-top: 10px; }

@media (max-width: 768px) {
  .marketing-banner { padding-block: clamp(48px, 12vw, 80px); }
  .marketing-banner__content { max-width: 100%; }
}

/* ===== BRANDS — navigation surface (docs/BRANDS-LANGUAGE.md) =====
   Equal-treatment logo grid, no captions (mark is the accessible
   name via alt, not visible text), restrained hover only, no JS.
   Compact utility-band footprint — deliberately lighter than any
   commerce section on this page. */
.fb-section {
  background: var(--foam);
  padding-block: clamp(32px, 5vw, 48px);
}
.fb-head {
  text-align: center;
  margin-block-end: 20px;
}
.fb-title {
  font-family: var(--font-head);
  font-size: clamp(18px, 2.2vw, 22px);
  font-weight: 600;
  color: var(--espresso);
  margin: 0;
}
.fb-subtitle {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--stone);
  margin: 5px 0 0;
}
/* Every brand visible at once — no horizontal scroll on any viewport. Brands
   are a navigation surface: a shopper has to be able to see the whole set to
   choose from it, and anything parked off-screen effectively doesn't exist.
   Four per row on desktop, three on mobile, with a short final row centring
   itself (7 brands read as 4 + 3, or 3 + 3 + 1). Flex basis rather than grid
   because grid would left-align that short row. */
.fb-track {
  --fb-gap: 12px;
  --fb-per-row: 4;
  display: flex;
  flex-wrap: wrap;
  gap: var(--fb-gap);
  justify-content: center;
  /* The 200px per-tile ceiling lives on the TRACK, not the tile: capping the
     tile instead leaves slack that a fifth logo slips into on a wide viewport,
     silently breaking the 4-up rhythm. 4 x 200 + 3 x 12. */
  max-width: 836px;
  margin-inline: auto;
}
.fb-surface {
  flex: 0 0 calc((100% - (var(--fb-per-row) - 1) * var(--fb-gap)) / var(--fb-per-row));
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: 10px 18px 10px 10px;
  text-decoration: none;
  transition: transform var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
}
.fb-surface:hover {
  transform: translateY(-2px);
  border-color: var(--copper);
  box-shadow: 0 6px 18px rgba(45,28,28,.10);
}
.fb-mark {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.fb-ctarow {
  text-align: center;
  margin-block-start: 16px;
}
.fb-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
@media (prefers-reduced-motion: reduce) {
  .fb-surface { transition: none; }
}
@media (max-width: 768px) {
  .fb-section { padding-block: 28px 36px; }
  .fb-head { margin-block-end: 16px; }
  .fb-track {
    --fb-gap: 10px;
    --fb-per-row: 3;
  }
  .fb-surface {
    padding: 12px;
  }
}

/* ===== Shipping & payment (shipping_payment.jinja) =====
   Shares the CMS page shell (.page-wrap / .page-title). Everything rendered
   here comes from the store's dashboard configuration, so the styling has to
   tolerate a variable number of sections and logos of inconsistent size. */
.sp-section + .sp-section { margin-top: clamp(32px, 5vw, 48px); }
.sp-heading {
  font-family: var(--font-head);
  font-size: 19px;
  font-weight: 600;
  color: var(--espresso);
  line-height: 1.5;
  margin: 0 0 16px;
}
.sp-list { list-style: none; margin: 0; padding: 0; }
.sp-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  background: var(--foam);
}
.sp-item + .sp-item { margin-top: 10px; }
.sp-bank { align-items: flex-start; }
/* Carrier and bank logos arrive at wildly different intrinsic sizes; box them
   so one oversized asset can't set the row height for the whole list. */
.sp-logo {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  object-fit: contain;
}
.sp-item-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.sp-item-name {
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  color: var(--espresso);
  line-height: 1.6;
}
.sp-note {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 400;
  color: var(--stone);
  line-height: 1.7;
}
/* IBANs and account numbers are Latin strings inside an RTL line. Only the
   value gets isolated — setting direction:ltr on the whole row would make
   `text-align: start` resolve to left and knock these lines out of alignment
   with every other row on the card. <bdi> keeps the number's own order
   without disturbing the Arabic label around it. */
.sp-num bdi {
  direction: ltr;
  unicode-bidi: isolate;
  font-family: var(--font-numeric);
  word-break: break-all;
}
.sp-icons {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.sp-icon {
  height: 30px;
  width: auto;
  object-fit: contain;
}
.sp-empty {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--stone);
  line-height: 1.9;
  margin: 0;
}

/* ===== Account area =====
   Shell shared by /account, /account/orders and /addresses. Rebuilt against
   the default theme's account page: a sidebar that says what each section is
   for, the profile as a readable summary, and editing raised into a dialog.

   Motion is the theme's existing vocabulary, not a new one — .js-press-ack for
   intent acknowledgment, .stagger-grid for entrance, and the same dialog
   behaviour the Quick Buy modal uses. */
.acct-shell {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
  padding-block: clamp(32px, 5vw, 56px) clamp(56px, 8vw, 88px);
}
@media (max-width: 900px) {
  .acct-shell { grid-template-columns: minmax(0, 1fr); }
}

/* -- Sidebar -- */
.acct-side { display: flex; flex-direction: column; gap: 10px; }
@media (max-width: 900px) {
  /* Horizontal rail on narrow screens: three stacked cards would push the
     actual content below the fold. */
  .acct-side {
    flex-direction: row;
    overflow-x: auto;
    scrollbar-width: none;
    margin-inline: calc(clamp(16px, 4vw, 32px) * -1);
    padding-inline: clamp(16px, 4vw, 32px);
    scroll-snap-type: x proximity;
  }
  .acct-side::-webkit-scrollbar { display: none; }
  .acct-card { flex: 0 0 auto; min-width: 210px; scroll-snap-align: start; }
  .acct-card-desc { display: none; }
}
.acct-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  background: var(--white);
  transition: border-color var(--t-base), background var(--t-base), transform var(--t-base);
}
.acct-card:hover { border-color: var(--stone-light); background: var(--foam); }
.acct-card:active,
.acct-card.is-pressed { transform: scale(0.985); transition-duration: 80ms; }
.acct-card.is-active {
  border-color: var(--espresso);
  background: var(--foam-mid);
}
.acct-card-ico {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--foam-mid);
  color: var(--espresso);
}
.acct-card.is-active .acct-card-ico { background: var(--white); color: var(--copper); }
.acct-card-ico svg { width: 19px; height: 19px; }
.acct-card-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.acct-card-title {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  color: var(--espresso);
}
.acct-card-desc {
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--stone);
  line-height: 1.6;
}

/* -- Content sections -- */
.acct-main { display: flex; flex-direction: column; gap: clamp(28px, 4vw, 44px); min-width: 0; }
.acct-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 12px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--linen);
}
.acct-section-title {
  font-family: var(--font-head);
  font-size: clamp(17px, 3vw, 20px);
  font-weight: 600;
  color: var(--espresso);
  margin: 0;
}
.acct-loading,
.acct-error {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--stone);
  line-height: 1.8;
  margin: 0;
}
.acct-error { color: var(--danger); }
.acct-blank {
  text-align: center;
  padding: 36px 20px;
  border: 1px dashed var(--linen);
  border-radius: var(--radius-md);
}
.acct-blank p {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--stone);
  margin: 0 0 16px;
}

/* -- Profile summary -- */
.acct-facts { margin: 0; display: flex; flex-direction: column; }
.acct-fact {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 16px;
  padding: 11px 0;
}
.acct-fact + .acct-fact { border-top: 1px solid var(--foam-mid); }
@media (max-width: 520px) {
  .acct-fact { grid-template-columns: minmax(0, 1fr); gap: 2px; }
}
.acct-fact dt {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--stone);
}
.acct-fact dd {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  color: var(--espresso);
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
/* Latin values (phone, email, date) inside an RTL row. direction:ltr keeps the
   digit order correct, but it also flips what `start` means — with text-align:
   start these lines aligned LEFT while every Arabic value aligned right. `end`
   resolves to the right in an LTR box, putting them back on the row's own
   edge. */
.acct-ltr { direction: ltr; unicode-bidi: isolate; text-align: end; font-family: var(--font-numeric); }

/* -- Buttons and icon controls -- */
.acct-ghost {
  appearance: none;
  background: none;
  border: 1px solid var(--linen);
  border-radius: 999px;
  padding: 7px 15px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--espresso);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--t-base), background var(--t-base), transform var(--t-base);
}
.acct-ghost:hover { border-color: var(--stone-light); background: var(--foam); }
.acct-ghost:active,
.acct-ghost.is-pressed { transform: scale(0.94); background: var(--foam-mid); transition-duration: 80ms; }
.acct-icon {
  appearance: none;
  border: 0;
  background: none;
  padding: 6px;
  border-radius: var(--radius-sm);
  color: var(--stone);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: color var(--t-base), background var(--t-base), transform var(--t-base);
}
.acct-icon svg { width: 17px; height: 17px; }
.acct-icon:hover { color: var(--espresso); background: var(--foam-mid); }
.acct-icon:active,
.acct-icon.is-pressed { transform: scale(0.88); transition-duration: 80ms; }
.acct-icon-danger:hover { color: var(--danger); }
.acct-icon[disabled] { opacity: .5; cursor: default; }
.acct-link {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--copper);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.acct-footer-row { display: flex; gap: 12px; flex-wrap: wrap; }

/* -- Address cards -- */
.acct-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
}
.acct-addr {
  border: 1px solid var(--linen);
  border-radius: var(--radius-md);
  background: var(--foam);
  padding: 14px 16px;
  transition: opacity 200ms ease, transform 200ms ease;
}
/* Removal is shown before the card goes, so the list visibly reconciles
   rather than snapping. */
.acct-addr.is-leaving { opacity: 0; transform: scale(0.97); }
.acct-addr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.acct-addr-title {
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 700;
  color: var(--espresso);
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.acct-addr-tools { display: flex; gap: 2px; flex: 0 0 auto; }
.acct-addr-line {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--stone);
  line-height: 1.75;
  margin: 6px 0 0;
  overflow-wrap: anywhere;
}

/* -- Orders table -- */
.acct-table { width: 100%; border-collapse: collapse; }
.acct-table th {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  color: var(--stone);
  text-align: start;
  padding: 10px 12px;
  background: var(--foam-mid);
  white-space: nowrap;
}
.acct-table th:first-child { border-start-start-radius: var(--radius-sm); }
.acct-table th:last-child { border-start-end-radius: var(--radius-sm); }
.acct-table td {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--espresso);
  padding: 14px 12px;
  border-bottom: 1px solid var(--linen);
  vertical-align: middle;
}
.acct-table tbody tr { transition: background var(--t-base); }
.acct-table tbody tr:hover { background: var(--foam); }
.acct-cell-id { font-family: var(--font-numeric); direction: ltr; unicode-bidi: isolate; text-align: start; }
.acct-cell-date { color: var(--stone); font-size: 13px; white-space: nowrap; }
.acct-cell-total { font-family: var(--font-numeric); font-weight: 700; direction: ltr; unicode-bidi: isolate; text-align: start; white-space: nowrap; }
.acct-cell-link { text-align: end; }
.acct-pill {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 12px;
  line-height: 1.6;
  padding: 3px 11px;
  border: 1px solid var(--linen);
  border-radius: 999px;
  color: var(--stone);
  white-space: nowrap;
}
/* Below 640px the table becomes stacked blocks with their labels attached --
   four columns on a phone forces horizontal scrolling to read a total. */
@media (max-width: 640px) {
  .acct-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .acct-table, .acct-table tbody, .acct-table tr, .acct-table td { display: block; width: 100%; }
  .acct-table tr {
    border: 1px solid var(--linen);
    border-radius: var(--radius-md);
    background: var(--foam);
    padding: 6px 14px 10px;
    margin-bottom: 10px;
  }
  .acct-table td { border: 0; padding: 6px 0; display: flex; justify-content: space-between; gap: 14px; align-items: center; }
  .acct-table td::before {
    content: attr(data-label);
    font-size: 12px;
    color: var(--stone);
    flex: 0 0 auto;
  }
  .acct-table td:empty { display: none; }
  .acct-cell-link { justify-content: flex-end; }
}

/* -- Edit dialog: same behaviour as the Quick Buy modal -- */
.acct-modal { display: none; position: fixed; inset: 0; z-index: 200; }
.acct-modal.open { display: block; }
.acct-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(45, 28, 28, .45);
  opacity: 0;
  transition: opacity 220ms ease;
}
.acct-modal.open .acct-backdrop { opacity: 1; }
.acct-sheet {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  margin-inline: auto;
  max-width: 560px;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--foam-mid);
  border-radius: 22px 22px 0 0;
  box-shadow: 0 -8px 30px rgba(45, 28, 28, .18);
  transform: translateY(100%);
  transition: transform var(--t-base);
}
.acct-modal.open .acct-sheet { transform: translateY(0); }
@media (min-width: 720px) {
  .acct-sheet {
    top: 50%;
    bottom: auto;
    transform: translateY(-42%);
    opacity: 0;
    border-radius: var(--radius-lg);
    transition: opacity 220ms ease, transform 220ms ease;
  }
  .acct-modal.open .acct-sheet { transform: translateY(-50%); opacity: 1; }
}
.acct-sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 20px 12px;
  border-bottom: 1px solid var(--linen);
}
.acct-sheet-title {
  font-family: var(--font-head);
  font-size: 17px;
  font-weight: 600;
  color: var(--espresso);
  margin: 0;
}

/* -- Form -- */
.acct-form { display: flex; flex-direction: column; gap: 16px; padding: 18px 20px 22px; }
.acct-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 520px) { .acct-field-row { grid-template-columns: 1fr; } }
.acct-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.acct-field label {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 700;
  color: var(--espresso);
}
.acct-field input,
.acct-field select {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--espresso);
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  width: 100%;
  transition: border-color var(--t-base);
}
.acct-field input:hover,
.acct-field select:hover { border-color: var(--stone-light); }
.acct-field input:focus-visible,
.acct-field select:focus-visible { outline: 2px solid var(--copper); outline-offset: 1px; border-color: var(--copper); }
.acct-field input[disabled] { background: var(--foam-mid); color: var(--stone); cursor: not-allowed; }
.acct-check {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--espresso);
  cursor: pointer;
}
.acct-check input { width: 17px; height: 17px; accent-color: var(--copper); flex: 0 0 auto; }
.acct-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.acct-msg { font-family: var(--font-body); font-size: 13px; color: var(--stone); }
.acct-msg.is-ok { color: var(--success); }
.acct-msg.is-error { color: var(--danger); }

/* Required-field marker in the address form. */
.acct-req { color: var(--danger); font-weight: 400; }

/* -- City combobox --
   115 cities is too many for a select, so the field is type-to-filter. The
   list is positioned against .acct-combo and scrolls internally rather than
   growing the dialog. */
.acct-combo { position: relative; }
.acct-combo-list {
  position: absolute;
  z-index: 5;
  inset-inline: 0;
  top: 100%;
  margin: 4px 0 0;
  padding: 4px;
  list-style: none;
  max-height: 220px;
  overflow-y: auto;
  background: var(--white);
  border: 1px solid var(--linen);
  border-radius: var(--radius-sm);
  box-shadow: 0 10px 24px rgba(45, 28, 28, .12);
}
.acct-combo-item {
  padding: 9px 11px;
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--espresso);
  cursor: pointer;
}
.acct-combo-item:hover,
.acct-combo-item.is-active { background: var(--foam-mid); }

/* -- In-store confirmation --
   Replaces window.confirm, which rendered Chrome's own slab with English
   buttons in the middle of an Arabic RTL store. Sits above the dialog that
   opened it, so its z-index clears .acct-modal. */
.acct-modal--confirm { z-index: 210; }
.acct-sheet--sm { max-width: 380px; }
.acct-confirm-body { padding: 22px 22px 6px; }
.acct-confirm-note {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 10px 0 0;
}
/* The address is stacked rather than run together on one line: the customer
   is checking it, and a wrapped comma-separated string is harder to scan than
   discrete lines. */
.acct-confirm-line {
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--stone);
  line-height: 1.75;
  overflow-wrap: anywhere;
}
.acct-confirm-line.is-lead {
  font-size: 14px;
  font-weight: 700;
  color: var(--espresso);
}
.acct-confirm-actions {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 16px 22px 22px;
}
/* Destructive confirmation carries the weight; cancel stays quiet, so the
   safe choice is the easy one to hit and the destructive one is deliberate. */
.btn-danger {
  background: var(--danger);
  color: var(--white);
  border: 0;
}
.btn-danger:hover { filter: brightness(0.94); }
.btn-danger:active,
.btn-danger.is-pressed { transform: scale(0.96); transition-duration: 80ms; }

/* Date input sizing. A date control carries an intrinsic width from its own
   rendered text, and Safari lets that win over width:100% — so the box grew
   past every other field in the form instead of lining up with them.
   Suppressing the native appearance drops the intrinsic sizing, and min-width
   lets it shrink inside its flex column. Only the box changes; the control is
   still the platform date picker. */
.acct-field input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}
/* Safari also inflates the inner text container; without this the value can
   still push the box wider than its parent. */
.acct-field input[type="date"]::-webkit-date-and-time-value {
  width: 100%;
  margin: 0;
  text-align: start;
}

/* ===== Page shell: footer sits at the bottom of short pages =====
   Without this the document simply ends where the content does, and on a
   phone — where an account or policy page is often shorter than the screen —
   the strip below the footer showed body's cream, reading as an unfinished
   page after the copyright line.

   .app wraps header + main + footer (layout.jinja), so making it a
   full-height column and letting .site-main take the slack pushes the footer
   to the bottom edge when content is short, and leaves it in normal flow when
   content is long. dvh accounts for mobile browser chrome; the vh line is the
   fallback for browsers without it. */
.app {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
.site-main { flex: 1 0 auto; }
.site-footer { flex-shrink: 0; }
