/* tokens.css */
/* ==========================================================================
   TOKENS — Silver Merchant
   Single source of truth for brand colors, fonts, spacing, timing.

   White and gold, on a light ground. Silver jewellery photographs against
   white and reads as clean rather than dim, so the shop is built light and
   the gold is used sparingly, for emphasis rather than decoration.

   The gold is deliberately deeper than a "luxury gold" swatch. Buttons paint
   white text straight onto --color-accent (.btn-primary sets color:
   var(--color-bg)), so a bright #C9A84C would put white on gold at about
   2.4:1 — unreadable, and the button labels here are 0.75rem letterspaced
   uppercase, which is small text needing the full 4.5:1. #8C6D1F clears it
   at 4.86:1 both ways: white on gold in a button, and gold on white as a
   link or heading.
   ========================================================================== */
:root {
  /* Colors */
  --color-bg: #FFFFFF;
  --color-bg-alt: #F8F5EF;
  --color-card: #FFFFFF;
  --color-card-hover: #FCFAF5;
  --color-border: #E6E0D4;
  --color-accent: #8C6D1F;
  --color-accent-hover: #6F5514;
  --color-accent-soft: rgba(140, 109, 31, 0.10);
  --color-text: #1A1713;
  --color-text-secondary: #5B5346;
  --color-text-muted: #8A8172;
  --color-success: #2E7D4F;
  --color-error: #B3261E;
  --color-white: #FFFFFF;
  /* Scrims over photography, where text stays light whatever the theme. */
  --color-overlay: rgba(26, 23, 19, 0.55);
  --color-on-media: #FFFFFF;

  /* Fonts */
  --font-display: 'Cormorant Garamond', serif;
  --font-body: 'DM Sans', sans-serif;
  --font-mono: 'DM Mono', monospace;

  /* Type scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;
  --text-3xl: 2.75rem;
  --text-4xl: 3.75rem;
  --text-5xl: 5rem;

  /* Spacing */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;
  --space-10: 4rem;
  --space-12: 6rem;
  --space-16: 8rem;

  /* Layout */
  --container-max: 1440px;
  --radius-sm: 2px;
  --radius-md: 6px;
  --radius-lg: 14px;
  --radius-full: 999px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 180ms;
  --dur-base: 320ms;
  --dur-slow: 600ms;

  /* Z-index */
  --z-nav: 100;
  --z-drawer: 200;
  --z-modal: 300;
  --z-toast: 400;

  /* Currency */
  --currency-symbol: '\20A8';
}

/* reset.css */
/* ==========================================================================
   RESET — modern normalization, brand-agnostic
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  min-height: 100vh;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, picture, video, canvas, svg {
  display: block;
  max-width: 100%;
}

input, button, textarea, select {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
}

button { cursor: pointer; }
button:disabled { cursor: not-allowed; }

a {
  color: inherit;
  text-decoration: none;
}

/* Focus rings are only ever visible for keyboard navigation (:focus-visible),
   never on mouse click — mouse users never see a ring, keyboard users always do. */
a:focus, button:focus, input:focus, select:focus, textarea:focus,
summary:focus, [tabindex]:focus { outline: none; }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

ul, ol { list-style: none; }

table { border-collapse: collapse; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* base.css */
/* ==========================================================================
   BASE — typography, body defaults
   ========================================================================== */
body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 400;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--color-text);
}

h1 { font-size: var(--text-5xl); }
h2 { font-size: var(--text-4xl); }
h3 { font-size: var(--text-3xl); }
h4 { font-size: var(--text-2xl); }
h5 { font-size: var(--text-xl); }

p { color: var(--color-text-secondary); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.price {
  font-family: var(--font-mono);
  font-weight: 500;
  color: var(--color-text);
}

.price--sale { color: var(--color-accent); }

.price--strike {
  color: var(--color-text-muted);
  text-decoration: line-through;
  font-size: 0.85em;
  margin-left: var(--space-2);
}

a.link-underline {
  position: relative;
  display: inline-block;
  color: var(--color-text);
}

a.link-underline::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur-base) var(--ease-out);
}

a.link-underline:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

::selection {
  background: var(--color-accent);
  color: var(--color-bg);
}

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--color-bg); }
::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: var(--radius-full);
}
::-webkit-scrollbar-thumb:hover { background: var(--color-accent); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.skip-link {
  position: fixed;
  top: -100px;
  left: var(--space-4);
  z-index: var(--z-modal);
  padding: var(--space-3) var(--space-5);
  background: var(--color-accent);
  color: var(--color-bg);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  border-radius: var(--radius-sm);
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus-visible {
  top: var(--space-4);
  outline: 2px solid var(--color-bg);
  outline-offset: 2px;
}

/* ---------------------------------------------------------------------------
   FOCUS
   One visible treatment for every keyboard-reachable control. Previously only
   a couple of elements carried a focus style, so tabbing through the header,
   filters or a modal could leave you with no idea where you were.

   :focus-visible rather than :focus — a mouse click should not draw a ring,
   but a Tab press must.
   --------------------------------------------------------------------------- */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Controls sitting on the accent colour need the inverse, or the ring
   disappears into the background it is drawn on. */
.btn-primary:focus-visible,
.countdown-bar :focus-visible {
  outline-color: var(--color-text);
}

/* The skip link is invisible until focused — it is the first thing a keyboard
   user meets, so it has to be unmistakable when it appears. */
.skip-link:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* ---- Page scroll lock (UI.lockScroll) ----
   Desktop: overflow alone, so the layout does not shift when the scrollbar
   goes. Touch devices: iOS Safari ignores overflow: hidden on body, so the
   body is pinned at the position UI.lockScroll captured (--locked-scroll-y)
   and restored on unlock. Without this the page scrolled under every open
   drawer and the filter sheet could not be dismissed after a scroll. */
body.is-scroll-locked { overflow: hidden; }

@media (hover: none) and (pointer: coarse) {
  body.is-scroll-locked {
    position: fixed;
    top: var(--locked-scroll-y, 0px);
    left: 0;
    right: 0;
    width: 100%;
  }
}

/* layout.css */
/* ==========================================================================
   LAYOUT — containers, grids, sections
   ========================================================================== */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--space-6);
}

.section {
  padding-block: var(--space-12);
}

.section--tight { padding-block: var(--space-8); }

.section-head {
  text-align: center;
  max-width: 640px;
  margin-inline: auto;
  margin-bottom: var(--space-8);
}

.section-head p { margin-top: var(--space-3); }

.grid {
  display: grid;
  gap: var(--space-6);
}

.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-10);
  align-items: center;
}

.flex { display: flex; }
.flex-center { display: flex; align-items: center; justify-content: center; }
.flex-between { display: flex; align-items: center; justify-content: space-between; }
.flex-col { display: flex; flex-direction: column; }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }
.gap-6 { gap: var(--space-6); }

.page-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.page-main { flex: 1; }

.page-hero {
  padding: var(--space-12) var(--space-8);
  border-bottom: 1px solid var(--color-border);
}

.cart-layout {
  display: grid;
  grid-template-columns: 1fr 380px;
  gap: var(--space-10);
  align-items: flex-start;
}
.cart-layout.is-empty { grid-template-columns: 1fr; }

.checkout-layout {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: var(--space-10);
  align-items: flex-start;
}

/* Base is mobile: single column. Breakpoints in responsive.css only ever
   change grid-template-columns — display:grid always stays declared here
   so no breakpoint can silently fall back to block layout. */
.shop-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
}

/* Always taken out of grid/document flow — it's a mobile-only backdrop.
   Without this base rule it becomes a real grid item outside the mobile
   breakpoint and steals a column from the sidebar/product-grid layout. */
.filter-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: var(--color-overlay);
  z-index: calc(var(--z-drawer) - 1);
}
.filter-overlay.is-open { display: block; }

.divider {
  height: 1px;
  background: var(--color-border);
  border: none;
  width: 100%;
}

/* --------------------------------------------------------------------------
   HOMEPAGE HERO — split layout.
   Copy on a cream panel, the admin's photo at full strength beside it.
   -------------------------------------------------------------------------- */
.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  min-height: min(86vh, 760px);
  background: var(--color-bg-alt);
  overflow: hidden;
}
.hero-split__copy {
  display: flex;
  align-items: center;
  padding: var(--space-12) var(--space-8) var(--space-12) max(var(--space-8), calc((100vw - var(--container-max)) / 2 + var(--space-6)));
  position: relative;
  z-index: 1;
}
.hero-split__inner { max-width: 560px; }
.hero-split__copy h1 { font-size: clamp(2.4rem, 1.4rem + 3.6vw, 4.6rem); }
.hero-split__media {
  position: relative;
  min-height: 420px;
  overflow: hidden;
}
.hero-split__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  /* Hidden until main.js has a real photo to show — never a broken icon. */
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.hero-split__media img[src] { opacity: 1; }
.hero-split__media canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0.35;
  mix-blend-mode: screen;
  pointer-events: none;
}
/* Feathers the seam so the panel and the photo read as one composition. */
.hero-split__media::before {
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  background:
    linear-gradient(90deg, var(--color-bg-alt) 0%, rgba(248,245,239,0) 18%),
    linear-gradient(180deg, rgba(26,23,19,0) 70%, rgba(26,23,19,0.18) 100%);
  pointer-events: none;
}

@media (max-width: 900px) {
  .hero-split {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    min-height: 0;
  }
  .hero-split__media { order: -1; min-height: 52vw; }
  .hero-split__media::before {
    background: linear-gradient(180deg, rgba(248,245,239,0) 60%, var(--color-bg-alt) 100%);
  }
  .hero-split__copy { padding: var(--space-8) var(--space-5) var(--space-10); text-align: center; }
  .hero-split__inner { margin-inline: auto; }
  .hero-split__copy #heroSubtitle { margin-inline: auto; }
  .hero-split__copy #heroCtas { justify-content: center; }
}

/* components.css */
/* ==========================================================================
   COMPONENTS — buttons, cards, badges, inputs, modals
   ========================================================================== */

.lightbox-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(26,23,19,0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}
.lightbox-overlay.is-open { opacity: 1; pointer-events: auto; }
.lightbox-overlay img {
  max-width: min(90vw, 900px);
  max-height: 86vh;
  object-fit: contain;
  border-radius: var(--radius-md);
  box-shadow: 0 30px 80px rgba(0,0,0,0.35);
}
.lightbox-close, .lightbox-prev, .lightbox-next {
  position: absolute;
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 46px;
  border-radius: var(--radius-full);
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--color-border);
  color: var(--color-text);
}
.lightbox-close:hover, .lightbox-prev:hover, .lightbox-next:hover { background: var(--color-accent-soft); color: var(--color-accent); }
.lightbox-close { top: var(--space-5); right: var(--space-5); }
.lightbox-prev { left: var(--space-5); top: 50%; transform: translateY(-50%); }
.lightbox-next { right: var(--space-5); top: 50%; transform: translateY(-50%); }
.lightbox-close svg, .lightbox-prev svg, .lightbox-next svg { width: 20px; height: 20px; stroke: currentColor; fill: none; }
.lightbox-counter {
  position: absolute;
  bottom: var(--space-5);
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  color: var(--color-text-secondary);
}
.zoom-on-hover { cursor: zoom-in; }

.back-to-top {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-nav);
  width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  color: var(--color-accent);
  box-shadow: 0 10px 24px rgba(26,23,19,0.14);
  opacity: 0;
  pointer-events: none;
  transform: translateY(12px);
  transition: opacity var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.back-to-top.is-visible { opacity: 1; pointer-events: auto; transform: translateY(0); }
.back-to-top:hover { background: var(--color-accent-soft); }
.back-to-top svg { width: 18px; height: 18px; stroke: currentColor; fill: none; }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.9rem 2rem;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  transition: all var(--dur-base) var(--ease-out);
  white-space: nowrap;
}

.btn-primary {
  background: var(--color-accent);
  color: var(--color-bg);
}
.btn-primary:hover:not(:disabled) {
  background: var(--color-accent-hover);
  transform: translateY(-1px);
}
.btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-outline {
  background: transparent;
  border-color: var(--color-accent);
  color: var(--color-accent);
}
.btn-outline:hover:not(:disabled) {
  background: var(--color-accent);
  color: var(--color-bg);
}

.btn-ghost {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-border);
}
.btn-ghost:hover:not(:disabled) {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.btn-block { width: 100%; }
.btn-sm { padding: 0.6rem 1.25rem; font-size: 0.65rem; }
.btn-icon {
  width: 44px; height: 44px;
  padding: 12px;
  border-radius: var(--radius-full);
  background: transparent;
}
.btn-icon:hover { background: var(--color-accent-soft); }
.btn-icon svg { width: 20px; height: 20px; stroke: currentColor; }

/* Cards */
.card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.card:hover { border-color: var(--color-accent); }

/* Product Card */
.product-card { position: relative; display: flex; flex-direction: column; }
/* The hover buttons and the wishlist heart are positioned against THIS box —
   the photo — not the whole card. Anchored to the card they landed over the
   name and price below the photo. */
.product-card__visual { position: relative; }
.product-card__media {
  /* An <a>: inline by default, which makes the aspect-ratio box and the
     hover outline apply to a line box rather than the photo. */
  display: block;
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--color-bg-alt);
  /* Transparent until hover, so the accent outline never shifts layout. */
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition: border-color var(--dur-base) var(--ease-out), box-shadow var(--dur-base) var(--ease-out);
}
.product-card:hover .product-card__media {
  border-color: var(--color-accent);
  box-shadow: 0 16px 36px rgba(26, 23, 19, 0.14);
}
.product-card__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.product-card:hover .product-card__media img { transform: scale(1.08); }

.product-card__actions {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  opacity: 0;
  transform: translateX(8px);
  transition: all var(--dur-base) var(--ease-out);
}
.product-card:hover .product-card__actions { opacity: 1; transform: translateX(0); }

.product-card__quickadd {
  position: absolute;
  left: var(--space-3);
  right: var(--space-3);
  bottom: var(--space-3);
  opacity: 0;
  transform: translateY(8px);
  transition: all var(--dur-base) var(--ease-out);

  /* Two stacked actions — Add to Cart and Buy Now — rather than one. The gap
     keeps them from reading as a single block, which matters when they sit on
     top of a photo. */
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.product-card:hover .product-card__quickadd { opacity: 1; transform: translateY(0); }

.product-card__body { padding: var(--space-4) var(--space-1) 0; }
.product-card__cat {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-1);
}
.product-card__name {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  margin-bottom: var(--space-2);
  transition: color var(--dur-fast);
}
.product-card:hover .product-card__name { color: var(--color-accent); }
.product-card__price { display: flex; align-items: center; }

/* Badges */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.7rem;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: var(--radius-full);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  color: var(--color-text-secondary);
}
.badge--accent { background: var(--color-accent); color: var(--color-bg); border-color: var(--color-accent); }
.badge--new { background: var(--color-accent-soft); color: var(--color-accent); border-color: var(--color-accent); }

/* Admin-set merchandising badges (Products → Badge). Bestseller reads as a
   gold seal; Hot is a warm ember tone — both stay in the luxury palette
   rather than loud alert colors. */
.badge--bestseller {
  background: var(--color-accent);
  color: var(--color-bg);
  border-color: var(--color-accent);
  box-shadow: 0 4px 14px rgba(140, 109, 31, 0.28);
}
.badge--hot {
  background: #8A3A2E;
  color: #F5E8E0;
  border-color: #A54A3A;
  box-shadow: 0 4px 12px rgba(165, 74, 58, 0.35);
}

/* Sale tag — shows the actual percentage off rather than a plain "Sale"
   pill, styled like a premium price tag instead of a generic alert red. */
.badge--sale {
  display: flex;
  flex-direction: column;
  align-items: center;
  line-height: 1;
  gap: 2px;
  padding: 0.4rem 0.65rem;
  border-radius: var(--radius-sm);
  background: var(--color-error);
  border: none;
  box-shadow: 0 4px 12px rgba(201, 88, 76, 0.35);
}
.badge--sale strong {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--color-white);
}
.badge--sale span {
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.85);
}

/* Inputs */
.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
.field label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.field input, .field select, .field textarea {
  padding: 0.85rem 1rem;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--color-accent); }
.field input.is-invalid, .field select.is-invalid, .field textarea.is-invalid { border-color: var(--color-error); }
.field-error { font-size: var(--text-xs); color: var(--color-error); min-height: 1em; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }

/* Interactive star-rating input — used by the review form */
.star-input { display: inline-flex; gap: 0.25rem; }
.star-input button {
  width: 28px; height: 28px;
  display: flex; align-items: center; justify-content: center;
  color: var(--color-text-muted);
  transition: color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.star-input button svg { width: 100%; height: 100%; fill: currentColor; }
.star-input button:hover { transform: scale(1.12); }
.star-input button.is-active { color: var(--color-accent); }

.review-card { padding: var(--space-5); position: relative; }
.review-card__actions { display: flex; gap: var(--space-3); }
.review-card__actions button {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
}
.review-card__actions button:hover { color: var(--color-accent); }
.review-card__mine {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-left: var(--space-2);
}
.review-form {
  padding: var(--space-6);
  margin-bottom: var(--space-6);
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
  margin-bottom: 0;
  transition: max-height var(--dur-slow) var(--ease-out), opacity var(--dur-base) var(--ease-out), padding var(--dur-base) var(--ease-out), margin var(--dur-base) var(--ease-out);
}
.review-form.is-open {
  max-height: 100%;
  opacity: 1;
  padding-top: var(--space-6);
  padding-bottom: var(--space-6);
  margin-bottom: var(--space-6);
}

.checkbox-row { display: flex; align-items: center; gap: var(--space-2); }
.checkbox-row input[type="checkbox"] {
  appearance: none;
  width: 18px; height: 18px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  position: relative;
  flex-shrink: 0;
}
.checkbox-row input[type="checkbox"]:checked { background: var(--color-accent); border-color: var(--color-accent); }
.checkbox-row input[type="checkbox"]:checked::after {
  content: '';
  position: absolute; left: 5px; top: 1px;
  width: 5px; height: 9px;
  border: solid var(--color-bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* Quantity stepper */
.qty-stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.qty-stepper button {
  width: 40px; height: 40px;
  font-size: var(--text-lg);
  color: var(--color-text-secondary);
}
.qty-stepper button:hover { color: var(--color-accent); }
.qty-stepper input {
  width: 44px;
  text-align: center;
  background: transparent;
  border: none;
  color: var(--color-text);
  font-family: var(--font-mono);
}

/* Modal */
.modal-overlay {
  position: fixed; inset: 0;
  background: var(--color-overlay);
  backdrop-filter: blur(4px);
  z-index: var(--z-modal);
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}
.modal-overlay.is-open { opacity: 1; pointer-events: auto; }
.modal {
  position: relative;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  max-width: 480px; width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--space-6);
  transform: scale(0.96) translateY(10px);
  transition: transform var(--dur-base) var(--ease-out);
}
.modal-overlay.is-open .modal { transform: scale(1) translateY(0); }
.modal-close {
  position: absolute; top: var(--space-4); right: var(--space-4);
}

/* Toast */
.toast-stack {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.toast {
  background: var(--color-card);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-5);
  font-size: var(--text-sm);
  box-shadow: 0 12px 32px rgba(26,23,19,0.16);
  animation: toastIn var(--dur-base) var(--ease-out);
}
.toast--error { border-color: var(--color-error); }

/* Skeleton */
.skeleton {
  background: linear-gradient(90deg, var(--color-card) 25%, var(--color-card-hover) 50%, var(--color-card) 75%);
  background-size: 200% 100%;
  animation: skeletonPulse 1.4s ease-in-out infinite;
  border-radius: var(--radius-md);
}
.skeleton-card { display: flex; flex-direction: column; gap: var(--space-3); }
.skeleton-card .skeleton-media { aspect-ratio: 3/4; width: 100%; }
.skeleton-card .skeleton-line { height: 14px; width: 70%; }
.skeleton-card .skeleton-line--sm { height: 12px; width: 40%; }

/* Empty state */
.empty-state {
  text-align: center;
  padding: var(--space-16) var(--space-4);
}
.empty-state svg { width: 56px; height: 56px; stroke: var(--color-text-muted); margin: 0 auto var(--space-4); }
.empty-state h3 { margin-bottom: var(--space-2); }
.empty-state p { margin-bottom: var(--space-6); }

/* Star rating */
.stars { display: inline-flex; gap: 2px; color: var(--color-accent); }
.stars svg { width: 14px; height: 14px; fill: currentColor; }

/* Accordion */
.accordion-item { border-bottom: 1px solid var(--color-border); }
.accordion-trigger {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-5) 0;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  text-align: left;
  background: none;
}
.accordion-trigger svg { transition: transform var(--dur-base) var(--ease-out); flex-shrink: 0; }
.accordion-item.is-open .accordion-trigger svg { transform: rotate(45deg); }
.accordion-panel {
  max-height: 0;
  overflow: hidden;
  transition: max-height var(--dur-base) var(--ease-out);
}
.accordion-panel__inner { padding-bottom: var(--space-5); }

/* --------------------------------------------------------------------------
   Rich text written by the shop (product descriptions, CMS page bodies)

   This content is authored HTML — <h3>, <ul>, <p> — and without scoping it
   inherited the page's display headings. A product's "The notes" subheading
   rendered at the same 1.85rem Cormorant as a section title, towering over the
   body text beside it and making the panel look broken rather than designed.

   Headings here are labels within a paragraph of text, not page furniture, so
   they are sized and spaced as labels.
   -------------------------------------------------------------------------- */
.accordion-panel__inner h2,
.accordion-panel__inner h3,
.accordion-panel__inner h4,
.accordion-panel__inner h5 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--color-accent);
  margin: var(--space-5) 0 var(--space-3);
}

.accordion-panel__inner > *:first-child { margin-top: 0; }

.accordion-panel__inner p {
  font-size: var(--text-sm);
  line-height: 1.75;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-3);
}

.accordion-panel__inner p:last-child { margin-bottom: 0; }

/* The notes read as a spec list, so each line gets its own row with the label
   holding a fixed column — much easier to scan than a wrapped sentence. */
.accordion-panel__inner ul {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.accordion-panel__inner li {
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-secondary);
  padding-left: var(--space-4);
  position: relative;
}

.accordion-panel__inner li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-accent);
  opacity: 0.55;
}

.accordion-panel__inner li strong {
  color: var(--color-text);
  font-weight: 500;
}

.accordion-panel__inner a { color: var(--color-accent); }

/* Tabs */
.tabs-head { display: flex; gap: var(--space-6); border-bottom: 1px solid var(--color-border); margin-bottom: var(--space-6); }
.tab-btn {
  padding: var(--space-3) 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab-btn.is-active { color: var(--color-accent); border-color: var(--color-accent); }
.tab-panel { display: none; }
.tab-panel.is-active { display: block; }

/* Variant swatches */
.variant-group { margin-bottom: var(--space-5); }
.variant-group__label { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text-secondary); margin-bottom: var(--space-3); }
.variant-options { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.variant-pill {
  padding: 0.5rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  transition: all var(--dur-fast) var(--ease-out);
}
.variant-pill:hover { border-color: var(--color-accent); }
.variant-pill.is-active { border-color: var(--color-accent); background: var(--color-accent-soft); color: var(--color-accent); }
.variant-pill:disabled { opacity: 0.3; cursor: not-allowed; }

/* Filter pill */
.filter-pill {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 0.4rem 0.8rem;
  background: var(--color-accent-soft);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-full);
  font-size: var(--text-xs);
  color: var(--color-accent);
}
.filter-pill button { color: var(--color-accent); font-size: 1rem; line-height: 1; }

/* Pagination */
.pagination { display: flex; align-items: center; justify-content: center; gap: var(--space-2); margin-top: var(--space-10); }
.page-btn {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.page-btn.is-active, .page-btn:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Trust bar */
.trust-bar { display: flex; justify-content: space-around; flex-wrap: wrap; gap: var(--space-6); padding: var(--space-8) 0; border-top: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); }
.trust-item { display: flex; align-items: center; gap: var(--space-3); }
.trust-item svg { width: 28px; height: 28px; stroke: var(--color-accent); flex-shrink: 0; }
.trust-item strong { display: block; font-size: var(--text-sm); }
.trust-item span { font-size: var(--text-xs); color: var(--color-text-secondary); }

/* Category image card */
.category-card {
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  border-radius: var(--radius-lg);
  overflow: hidden;
  /* Transparent, not --color-border: the accent border on hover then costs no
     layout shift. A later rule used to override this and left the two
     declarations disagreeing about what a category card looks like. */
  border: 1px solid transparent;
  transition: border-color var(--dur-base) var(--ease-out);
}
.category-card:hover { border-color: var(--color-accent); }
.category-card img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.category-card:hover img { transform: scale(1.08); }
.category-card::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(26,23,19,0.72) 0%, rgba(26,23,19,0.18) 42%, rgba(26,23,19,0) 68%);
}
.category-card__label {
  position: absolute;
  left: var(--space-5); right: var(--space-5); bottom: var(--space-5);
  z-index: 1;
}
.category-card__label h4 { color: var(--color-on-media); text-shadow: 0 1px 3px rgba(26,23,19,0.35); }
.category-card__label span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #E8D9A8; /* pale gold: the accent itself is too dark on the photo */
  opacity: 0;
  transform: translateX(-6px);
  transition: all var(--dur-base) var(--ease-out);
}
.category-card:hover .category-card__label span { opacity: 1; transform: translateX(0); }

/* Editorial / brand-story photo frame */
.photo-frame {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--color-border);
}
.photo-frame img {
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Social grid */
.social-tile {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
}
.social-tile img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
.social-tile:hover img { transform: scale(1.1); }
.social-tile::after {
  content: '';
  position: absolute; inset: 0;
  background: rgba(26,23,19,0);
  transition: background var(--dur-base) var(--ease-out);
}
.social-tile:hover::after { background: rgba(26,23,19,0.12); }

/* Newsletter section */
.newsletter-section {
  background: linear-gradient(135deg, rgba(140,109,31,0.08), transparent 60%), var(--color-bg-alt);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  text-align: center;
  padding-block: var(--space-12);
}
.newsletter-form {
  display: flex;
  gap: var(--space-3);
  max-width: 460px;
  margin: var(--space-6) auto 0;
}
.newsletter-form input {
  flex: 1;
  padding: 0.9rem 1.1rem;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}
.newsletter-form input:focus { border-color: var(--color-accent); }
.newsletter-success {
  margin-top: var(--space-4);
  color: var(--color-success);
  font-size: var(--text-sm);
}

/* Newsletter popup (reuses .modal-overlay / .modal from above) */
.newsletter-modal { max-width: 440px; text-align: center; }
.newsletter-modal .eyebrow { display: block; margin-bottom: var(--space-2); }
.newsletter-modal form { margin-top: var(--space-6); display: flex; flex-direction: column; gap: var(--space-3); }
.newsletter-modal input {
  padding: 0.9rem 1.1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  text-align: center;
}
.newsletter-modal input:focus { border-color: var(--color-accent); }
.newsletter-modal__dismiss {
  margin-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  text-decoration: underline;
}

/* Sale banner */
.sale-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: 0.7rem var(--space-6);
  background: var(--color-accent);
  color: var(--color-bg);
  text-align: center;
  position: relative;
}
.sale-banner p {
  color: var(--color-bg);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  letter-spacing: 0.04em;
  margin: 0;
}
.sale-banner a {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: underline;
  color: var(--color-bg);
  flex-shrink: 0;
}
.sale-banner__close {
  position: absolute;
  right: var(--space-4);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-bg);
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
}
.sale-banner__close svg { width: 14px; height: 14px; }

/* Filter sidebar */
.filter-sidebar { padding: var(--space-6); }
.filter-sidebar__head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-5);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}
.filter-sidebar__head h5 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text);
}

.filter-section { border-bottom: 1px solid var(--color-border); }
.filter-section:last-of-type { border-bottom: none; }
.filter-section__trigger {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
  background: none;
}
.filter-section__trigger svg { width: 14px; height: 14px; flex-shrink: 0; transition: transform var(--dur-base) var(--ease-out); }
.filter-section.is-open .filter-section__trigger svg { transform: rotate(90deg); }
.filter-section__panel { max-height: 0; overflow: hidden; transition: max-height var(--dur-base) var(--ease-out); }
.filter-section__inner { padding-bottom: var(--space-5); }

.filter-count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: var(--color-bg);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  margin-left: var(--space-2);
}

/* Dual-thumb price range slider */
.price-range-values {
  display: flex; justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text);
  margin-bottom: var(--space-4);
}
.price-range-slider { position: relative; height: 20px; margin-top: var(--space-2); }
.price-range-track {
  position: absolute; top: 8px; left: 0; right: 0; height: 4px;
  background: var(--color-border);
  border-radius: var(--radius-full);
}
.price-range-track__fill {
  position: absolute; height: 4px;
  background: var(--color-accent);
  border-radius: var(--radius-full);
}
.price-range-slider input[type="range"] {
  position: absolute;
  width: 100%;
  top: 5px;
  height: 10px;
  margin: 0;
  background: transparent;
  appearance: none;
  -webkit-appearance: none;
  pointer-events: none;
}
.price-range-slider input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  pointer-events: auto;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--color-accent);
  border: 2px solid var(--color-bg);
  box-shadow: 0 0 0 1px var(--color-accent);
  cursor: pointer;
}
.price-range-slider input[type="range"]::-moz-range-thumb {
  pointer-events: auto;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--color-accent);
  border: 2px solid var(--color-bg);
  box-shadow: 0 0 0 1px var(--color-accent);
  cursor: pointer;
}
.price-range-slider input[type="range"]::-webkit-slider-runnable-track { background: transparent; }
.price-range-slider input[type="range"]::-moz-range-track { background: transparent; }

/* Toggle switch */
.toggle-switch { display: flex; align-items: center; gap: var(--space-3); cursor: pointer; font-size: var(--text-sm); }
.toggle-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle-switch__track {
  position: relative;
  width: 40px; height: 22px; flex-shrink: 0;
  background: var(--color-border);
  border-radius: var(--radius-full);
  transition: background var(--dur-fast) var(--ease-out);
}
.toggle-switch__track::after {
  content: '';
  position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--color-text);
  transition: transform var(--dur-fast) var(--ease-out);
}
.toggle-switch input:checked + .toggle-switch__track { background: var(--color-accent); }
.toggle-switch input:checked + .toggle-switch__track::after {
  transform: translateX(18px);
  background: var(--color-bg);
}

/* Rating filter pills */
.rating-pill {
  display: flex; align-items: center; gap: var(--space-2);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  transition: all var(--dur-fast) var(--ease-out);
}
.rating-pill:hover { border-color: var(--color-accent); }
.rating-pill.is-active { border-color: var(--color-accent); background: var(--color-accent-soft); color: var(--color-accent); }
.rating-pill .stars { color: var(--color-accent); }
.rating-pill .stars svg { width: 13px; height: 13px; }

.sale-countdown {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: var(--space-3);
  padding: 0.4rem 0.8rem;
  border-radius: var(--radius-full);
  background: rgba(201, 88, 76, 0.12);
  border: 1px solid var(--color-error);
  color: var(--color-error);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
}

/* Bundle / frequently-bought-together */
.bundle-section {
  margin-top: var(--space-6);
  padding: var(--space-6);
}
.bundle-items { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.bundle-item { position: relative; display: flex; align-items: center; gap: var(--space-3); }
.bundle-item img {
  width: 64px; height: 80px;
  object-fit: cover;
  border-radius: var(--radius-sm);
}
.bundle-item__info { font-size: var(--text-sm); }
.bundle-item__info a { color: var(--color-text); }
.bundle-item__info .price { font-size: var(--text-sm); }
.bundle-plus {
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  color: var(--color-text-muted);
  flex-shrink: 0;
}
.bundle-footer {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}
.bundle-savings { color: var(--color-success); font-size: var(--text-sm); }
.bundle-total { font-family: var(--font-display); font-size: var(--text-2xl); }

/* Comparison table */
.compare-table-wrap { overflow-x: auto; }
.compare-table { width: 100%; border-collapse: collapse; min-width: 560px; }
.compare-table th, .compare-table td {
  padding: var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}
.compare-table th { width: 140px; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-text-secondary); }
.compare-table td.is-current { background: var(--color-accent-soft); }
.compare-table__product img { width: 72px; height: 90px; object-fit: cover; border-radius: var(--radius-sm); margin-bottom: var(--space-2); }
.compare-table__product a { font-family: var(--font-display); font-size: var(--text-lg); color: var(--color-text); }

/* ==========================================================================
   LUXURY POLISH — refined hover states and depth cues. Uses accent-soft /
   currentColor derivations so admin-set theme colors carry through.
   ========================================================================== */
/* Gold hairline under section eyebrows — a quiet luxury cue */
.section-head .eyebrow::after {
  content: '';
  display: block;
  width: 34px;
  height: 1px;
  margin: 10px auto 0;
  background: var(--color-accent);
  opacity: 0.65;
}

/* ==========================================================================
   WHATSAPP — floating chat button (site-wide) + product-page order button.
   Sits above back-to-top so both can coexist on mobile.
   ========================================================================== */
.whatsapp-fab {
  position: fixed;
  left: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-nav);
  width: 52px; height: 52px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  background: #25D366;
  color: #fff;
  box-shadow: 0 10px 26px rgba(37, 211, 102, 0.35);
  transition: transform var(--dur-base) var(--ease-out);
}
.whatsapp-fab:hover { transform: scale(1.07); }
.whatsapp-fab svg { width: 26px; height: 26px; }

.btn-whatsapp {
  background: #25D366;
  color: #06301A;
  border-color: #25D366;
}
.btn-whatsapp:hover:not(:disabled) { background: #1EBE5B; border-color: #1EBE5B; }
.btn-whatsapp svg { width: 18px; height: 18px; fill: currentColor; }

@media (max-width: 480px) {
  .whatsapp-fab { width: 46px; height: 46px; }
  .whatsapp-fab svg { width: 22px; height: 22px; }
}

/* ==========================================================================
   STICKY ADD TO CART — slides up on the product page once the real Add to
   Cart button scrolls out of view. Biggest win on mobile, where the button
   is far above the reviews and notes.
   ========================================================================== */
.sticky-atc {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  background: var(--color-card);
  border-top: 1px solid var(--color-border);
  box-shadow: 0 -8px 30px rgba(26, 23, 19, 0.12);
  transform: translateY(110%);
  transition: transform var(--dur-base) var(--ease-out);
}
.sticky-atc.is-visible { transform: translateY(0); }

.sticky-atc__img {
  width: 46px; height: 58px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}
.sticky-atc__info { flex: 1; min-width: 0; }
.sticky-atc__name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sticky-atc__price { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); }
.sticky-atc__btn { flex-shrink: 0; }

@media (max-width: 560px) {
  .sticky-atc { gap: var(--space-3); padding: var(--space-3) var(--space-4); }
  .sticky-atc__img { width: 38px; height: 48px; }
  .sticky-atc__name { font-size: var(--text-base); }
  .sticky-atc__btn { padding: 0.75rem 1.15rem; }
  /* Keep the floating buttons clear of the bar while it's up. */
  .sticky-atc.is-visible ~ .whatsapp-fab,
  .sticky-atc.is-visible ~ .back-to-top { bottom: calc(var(--space-5) + 74px); }
}

@media (prefers-reduced-motion: reduce) {
  .sticky-atc { transition: none; }
}

/* ==========================================================================
   PIECE PROFILE — metal/plating/stone spec, sparkle & presence bars, tags.
   Hidden entirely when the admin hasn't filled the fields in.
   ========================================================================== */
.piece-profile {
  margin-top: var(--space-8);
  padding-top: var(--space-6);
  border-top: 1px solid var(--color-border);
}

.note-pyramid { display: flex; flex-direction: column; gap: var(--space-4); margin-top: var(--space-4); }
.note-tier { display: grid; grid-template-columns: 92px 1fr; gap: var(--space-4); align-items: start; }
.note-tier__label {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  padding-top: 5px;
}
.note-tier__label span {
  display: block;
  color: var(--color-text-muted);
  letter-spacing: 0.04em;
  text-transform: none;
  font-size: 0.62rem;
  margin-top: 2px;
}
.note-tier__chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.note-chip {
  padding: 0.32rem 0.7rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-card);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.piece-bars { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); margin-top: var(--space-6); }
.piece-bar__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.piece-bar__value { color: var(--color-text-secondary); letter-spacing: 0.02em; text-transform: none; }
.piece-bar__track { display: flex; gap: 4px; }
.piece-bar__track span {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--color-border);
}
.piece-bar__track span.is-on { background: var(--color-accent); }

.piece-tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-6); }
.piece-tag {
  padding: 0.3rem 0.75rem;
  border-radius: var(--radius-full);
  background: var(--color-accent-soft);
  color: var(--color-accent);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (max-width: 560px) {
  .note-tier { grid-template-columns: 1fr; gap: var(--space-2); }
  .piece-bars { grid-template-columns: 1fr; gap: var(--space-4); }
}

/* ==========================================================================
   CONVERSION NUDGES — free-delivery progress, delivery estimate, low stock,
   rating distribution, checkout trust row. All render only when the data
   behind them is real; none of them invent urgency.
   ========================================================================== */
.ship-progress { margin: var(--space-4) 0 var(--space-2); }
.ship-progress__label {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-2);
  text-align: center;
}
.ship-progress.is-earned .ship-progress__label { color: var(--color-success); }
.ship-progress__track {
  height: 4px;
  border-radius: 2px;
  background: var(--color-border);
  overflow: hidden;
}
.ship-progress__track span {
  display: block;
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  transition: width var(--dur-base) var(--ease-out);
}

.delivery-estimate {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.delivery-estimate svg { width: 17px; height: 17px; flex-shrink: 0; color: var(--color-accent); }

.stock-urgency {
  margin-top: var(--space-2);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-error);
}

.rating-breakdown {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 320px;
  margin-bottom: var(--space-6);
}
.rating-row { display: grid; grid-template-columns: 30px 1fr 28px; gap: var(--space-3); align-items: center; }
.rating-row__star { font-size: var(--text-xs); color: var(--color-text-muted); white-space: nowrap; }
.rating-row__track { height: 5px; border-radius: 3px; background: var(--color-border); overflow: hidden; }
.rating-row__track span { display: block; height: 100%; background: var(--color-accent); border-radius: 3px; }
.rating-row__count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.checkout-trust {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: var(--space-4) 0 0;
  border-top: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.checkout-trust li {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
}
.checkout-trust svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--color-accent); }

/* Back-in-stock signup — replaces the buy area when a piece is sold out. */
.stock-notify {
  margin-top: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-card);
}
.stock-notify__title {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-3);
}
.stock-notify__form { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.stock-notify__form input {
  flex: 1;
  min-width: 180px;
  padding: 0.85rem 1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}
.stock-notify__form input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.stock-notify__msg:empty { display: none; }
.stock-notify__msg { margin-top: var(--space-3); font-size: var(--text-sm); }

/* Product Q&A — only answered questions are ever shown. */
.qa-item { padding: var(--space-5); }
.qa-item__q, .qa-item__a {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: var(--space-3);
  align-items: start;
  font-size: var(--text-sm);
  line-height: 1.7;
}
.qa-item__q { color: var(--color-text); }
.qa-item__a { color: var(--color-text-secondary); margin-top: var(--space-3); }
.qa-item__q > span, .qa-item__a > span {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
}
.qa-item__a > span { background: var(--color-accent-soft); color: var(--color-accent); border-color: var(--color-accent); }
.qa-item__meta {
  margin-top: var(--space-3);
  padding-left: calc(26px + var(--space-3));
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.qa-ask { padding: var(--space-5); margin-top: var(--space-5); }
.qa-ask__title {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  margin-bottom: var(--space-4);
}
.qa-ask__msg:empty { display: none; }
.qa-ask__msg { margin-top: var(--space-3); font-size: var(--text-sm); }

/* Blog cards — the Journal index. */
.blog-card {
  display: flex;
  flex-direction: column;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.blog-card:hover { border-color: var(--color-accent); transform: translateY(-2px); }
.blog-card__img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.blog-card__body { padding: var(--space-5); display: flex; flex-direction: column; gap: var(--space-2); flex: 1; }
.blog-card__date {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.blog-card__title { font-family: var(--font-display); font-size: var(--text-xl); color: var(--color-text); }
.blog-card__excerpt { font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.7; flex: 1; }
.blog-card__more {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-top: var(--space-2);
}

/* Order confirmation detail — the receipt the customer sees straight after
   placing a COD order, so there is no surprise at the door. */
.confirm-panel {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-6);
}
.confirm-panel__head {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-4);
}
.confirm-item {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
}
.confirm-item:last-child { border-bottom: none; }
.confirm-item img { border-radius: var(--radius-sm); object-fit: cover; flex-shrink: 0; }
.confirm-item__body { flex: 1; min-width: 0; }
.confirm-item__name { font-size: var(--text-sm); color: var(--color-text); }
.confirm-item__meta { font-size: var(--text-xs); color: var(--color-text-muted); margin-top: 2px; }
.confirm-item__price { font-size: var(--text-sm); color: var(--color-text); white-space: nowrap; }
.confirm-totals { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--color-border); }
.confirm-totals__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  padding: var(--space-1) 0;
}
.confirm-totals__row--grand {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-text);
}

/* Size guide — bottle-size explainer opened from the variant selector. */
.size-guide-link {
  margin-left: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 3px;
  background: none;
  border: none;
  cursor: pointer;
}
.size-guide__table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.size-guide__table th {
  text-align: left;
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--color-border);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  font-weight: 400;
}
.size-guide__table td {
  padding: var(--space-3) var(--space-3) var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  vertical-align: top;
}
.size-guide__table td strong { color: var(--color-text); }
.size-guide__note { margin-top: var(--space-4); font-size: var(--text-xs); color: var(--color-text-muted); line-height: 1.7; }

/* Perfect Pairs — admin-created product pairings on the shop page. */
.pair-card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out);
}
.pair-card:hover { border-color: var(--color-accent); }
.pair-card__images {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-5);
  background: var(--color-bg-alt);
}
.pair-card__images img { width: 42%; height: auto; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius-sm); }
.pair-card__plus { font-family: var(--font-display); font-size: var(--text-2xl); color: var(--color-accent); }
.pair-card__body { padding: var(--space-5); }
.pair-card__names { font-size: var(--text-sm); color: var(--color-text); line-height: 1.6; }
.pair-card__pricing { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-3); margin: var(--space-3) 0 var(--space-4); }
.pair-card__was { font-size: var(--text-sm); color: var(--color-text-muted); text-decoration: line-through; }
.pair-card__now { font-family: var(--font-display); font-size: var(--text-xl); color: var(--color-accent); }
.pair-card__save {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text);
  border: 1px solid var(--color-accent);
  border-radius: 100px;
  padding: 2px 8px;
}

/* Product video — "Watch" pill over the main gallery image. */
.video-play {
  position: absolute;
  bottom: var(--space-4);
  right: var(--space-4);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 100px;
  border: 1px solid var(--color-border);
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(6px);
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.video-play:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Discount code chip — shown after subscribing, click to copy. */
.coupon-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px 16px;
  border: 1px dashed var(--color-accent);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-accent);
  font-family: var(--font-mono);
  font-size: var(--text-base);
  letter-spacing: 0.16em;
  cursor: pointer;
  transition: background var(--dur-base) var(--ease-out);
}
.coupon-chip:hover { background: var(--color-accent-soft); }

/* Return request panel on the order-tracking page. */
.return-panel {
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-left: 2px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-bg-alt);
}
.return-panel__head {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2);
}
.return-panel__status { font-size: var(--text-sm); color: var(--color-text); line-height: 1.7; }
.return-panel__note {
  margin-top: var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  line-height: 1.7;
}

/* Tag filter chips (shop sidebar) and tag links (product page). */
.tag-filter-list { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tag-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border: 1px solid var(--color-border);
  border-radius: 100px;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.tag-chip span { color: var(--color-text-muted); font-family: var(--font-mono); font-size: 0.6rem; }
.tag-chip:hover { border-color: var(--color-accent); color: var(--color-accent); }
.tag-chip.is-active { border-color: var(--color-accent); color: var(--color-accent); background: var(--color-accent-soft); }
.piece-tag--link { transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out); }
.piece-tag--link:hover { border-color: var(--color-accent); color: var(--color-accent); }

/* Review card extras — verified badge, shop reply, helpful votes. */
.review-card__verified {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: var(--space-2);
  padding: 2px 8px;
  border-radius: 100px;
  background: var(--color-accent-soft);
  color: var(--color-accent);
  font-family: var(--font-mono);
  font-size: 0.55rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  vertical-align: middle;
}
.review-card__title {
  margin-top: var(--space-2);
  font-family: var(--font-display);
  font-size: var(--text-lg);
  color: var(--color-text);
}
.review-reply {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border-left: 2px solid var(--color-accent);
  background: var(--color-bg-alt);
  border-radius: var(--radius-sm);
}
.review-reply__head {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-2);
}
.review-reply__body { font-size: var(--text-sm); color: var(--color-text-secondary); line-height: 1.7; }
.review-card__foot {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}
.review-card__helpful-label { font-size: var(--text-xs); color: var(--color-text-muted); }
.review-vote {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border: 1px solid var(--color-border);
  border-radius: 100px;
  background: transparent;
  color: var(--color-text-secondary);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.review-vote:hover:not(:disabled) { border-color: var(--color-accent); color: var(--color-accent); }
.review-vote:disabled { opacity: 0.45; cursor: default; }

/* Account area — clickable order cards and saved-address cards. */
.order-card {
  display: block;
  border: 1px solid var(--color-border);
  background: var(--color-card);
  cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out);
}
.order-card:hover { border-color: var(--color-accent); transform: translateY(-2px); }
.order-card__more {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.address-card { border: 1px solid var(--color-border); }
/* The default address is the one checkout preselects, so it is marked. */
.address-card--default { border-color: var(--color-accent); }

/* Checkout: signed-in banner, saved-address picker, guest prompt. */
.signed-in-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-6);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  font-size: var(--text-sm);
  color: var(--color-text);
}
.signed-in-bar__link { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }

.guest-prompt {
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-6);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.guest-prompt a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }

.saved-address {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-card);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.saved-address:hover { border-color: var(--color-accent); }
.saved-address:has(input:checked) { border-color: var(--color-accent); background: var(--color-accent-soft); }
.saved-address input { width: 18px; height: 18px; accent-color: var(--color-accent); flex-shrink: 0; margin-top: 2px; }
.saved-address__detail { display: block; margin-top: 4px; font-size: var(--text-xs); color: var(--color-text-secondary); line-height: 1.6; }

/* Checkout stock warning — shown when a basket item is short at hold time. */
.stock-notice {
  grid-column: 1 / -1;
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-5);
  border: 1px solid var(--color-accent);
  border-left-width: 3px;
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  font-size: var(--text-sm);
}
.stock-notice ul { margin: var(--space-2) 0 var(--space-3) var(--space-5); list-style: disc; color: var(--color-text-secondary); }
.stock-notice a { color: var(--color-accent); text-decoration: underline; text-underline-offset: 3px; }

/* Configurable product options — "Sample 1…5" dropdowns with a live total. */
.option-group { margin-bottom: var(--space-4); }
.option-group__label {
  display: block;
  margin-bottom: var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}
.option-group__required { color: var(--color-accent); }
.option-group__select {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-card);
  color: var(--color-text);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.option-group__select:focus { outline: none; border-color: var(--color-accent); }
.option-group__select.is-invalid { border-color: var(--color-error, #F85149); }

.options-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-text);
}
.options-total__value { color: var(--color-accent); }

/* Coupon entry in the checkout summary. */
.coupon-box { margin-bottom: var(--space-4); }
.coupon-box__row { display: flex; gap: var(--space-2); }
.coupon-box__row input {
  flex: 1;
  min-width: 0;
  padding: 0.7rem 1rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.coupon-box__row input:focus { outline: none; border-color: var(--color-accent); }
.coupon-box__row input::placeholder { text-transform: none; letter-spacing: 0; color: var(--color-text-muted); }

.coupon-box__applied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: 0.7rem 1rem;
  border: 1px dashed var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-accent-soft);
  font-size: var(--text-sm);
  color: var(--color-text);
}
.coupon-box__applied strong { font-family: var(--font-mono); letter-spacing: 0.08em; color: var(--color-accent); }
.coupon-box__applied button {
  border: none;
  background: none;
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.coupon-box__applied button:hover { color: var(--color-text); }

.coupon-box__msg { min-height: 1.2em; margin-top: var(--space-2); font-size: var(--text-xs); color: var(--color-text-muted); }
.coupon-box__msg.is-ok { color: var(--color-accent); }
.coupon-box__msg.is-error { color: var(--color-error, #F85149); }

/* The applied code shown beside the discount line. */
.coupon-tag {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  color: var(--color-accent);
}

/* Product page conversion cues. */
.rating-summary {
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--color-border);
}
.rating-summary:hover { color: var(--color-accent); text-decoration-color: currentColor; }

.price-per-ml {
  margin-top: var(--space-1);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
}

/* Cash on Delivery stated where the buying decision happens. */
.cod-assurance {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin-top: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-card);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  line-height: 1.6;
}
.cod-assurance svg { width: 18px; height: 18px; flex-shrink: 0; margin-top: 2px; color: var(--color-accent); }
.cod-assurance strong { color: var(--color-text); }

/* Load-more button on the shop grid. */
.load-more__of {
  display: block;
  margin-top: 3px;
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Search dead-end recovery. */
.no-results { text-align: center; padding: var(--space-10) 0 var(--space-6); }
.no-results h2 { font-family: var(--font-display); font-size: var(--text-2xl); color: var(--color-text); }
.no-results p { margin-top: var(--space-3); color: var(--color-text-secondary); }
.no-results__actions {
  display: flex;
  gap: var(--space-3);
  justify-content: center;
  flex-wrap: wrap;
  margin-top: var(--space-6);
}

/* Live count while filtering — the sidebar shows what a filter will leave. */
.filter-count {
  font-family: var(--font-mono);
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  color: var(--color-text-muted);
}

/* ==========================================================================
   CONTACT FORM  (page.html, shown when a CMS page has the flag set)
   ========================================================================== */
.contact-form-block {
  max-width: 720px;
  margin: var(--space-12) auto 0;
  padding: var(--space-8);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  background: var(--color-surface);
}

.contact-form-block__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
}

.contact-form-block__sub {
  margin: var(--space-2) 0 var(--space-6);
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
}

.contact-form-block textarea {
  resize: vertical;
  min-height: 8rem;
  font-family: inherit;
}

.field-optional {
  color: var(--color-text-muted);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
}

/*
 * The honeypot.
 *
 * Deliberately NOT `display:none` or `hidden` — the better bots skip fields
 * a browser would never render. Parking it off-screen keeps it "real" to a
 * script while putting it out of sight, and aria-hidden + tabindex="-1" on
 * the markup keep keyboard and screen-reader users from ever reaching it.
 */
.contact-form-block__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-form-block__status {
  margin: var(--space-4) 0 0;
  font-size: var(--text-sm);
  min-height: 1.25em;
}

.contact-form-block__status.is-success { color: var(--color-success, #4CAF50); }
.contact-form-block__status.is-error { color: var(--color-error); }

@media (max-width: 640px) {
  .contact-form-block { padding: var(--space-5); margin-top: var(--space-8); }
  .contact-form-block .field-row { grid-template-columns: 1fr; gap: 0; }
}

/* --------------------------------------------------------------------------
   BUNDLE CONTENTS (product page)

   A bundle's price means nothing on its own — "₨ 4,500" only reads as a deal
   once the shopper can see the three pieces inside and what they would
   cost bought separately. Each row links to its own product page, because
   someone deciding on a set usually wants to read about one of its parts.
   -------------------------------------------------------------------------- */
.bundle-contents {
  margin-top: var(--space-7);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg-alt);
}

.bundle-contents__title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-4);
}

.bundle-contents__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.bundle-contents__row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.bundle-contents__link {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex: 1;
  min-width: 0;
  color: var(--color-text);
}

.bundle-contents__link:hover .bundle-contents__name { color: var(--color-accent); }

.bundle-contents__img {
  width: 48px;
  height: 60px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}

/* Long piece names must not push the quantity off the row. */
.bundle-contents__name {
  font-size: var(--text-sm);
  line-height: 1.4;
  min-width: 0;
  transition: color var(--dur-fast) var(--ease-out);
}

.bundle-contents__qty {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.bundle-contents__saving {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
}

.bundle-contents__saving strong { color: var(--color-accent); }

/* --------------------------------------------------------------------------
   SCENT WHEEL

   The ring and the legend are one object: hovering either half highlights the
   other, and the centre spells out the family in words so the chart still
   works for anyone who cannot separate the colours.

   Layout is side-by-side where there is room and stacked where there is not,
   driven by the container rather than a breakpoint, so it behaves the same
   wherever the section is placed.
   -------------------------------------------------------------------------- */
.style-wheel {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  flex-wrap: wrap;
}

.style-wheel__chart {
  position: relative;
  flex: 0 0 auto;
  width: min(240px, 72vw);
  aspect-ratio: 1;
}

.style-wheel__svg {
  width: 100%;
  height: 100%;
}

/* Segments lift slightly on hover. transform-box keeps the origin on the
   element's own box so the scale does not throw it across the canvas. */
.style-wheel__seg {
  cursor: pointer;
  transform-box: view-box;
  transform-origin: center;
  transition: opacity var(--dur-base) var(--ease-out), stroke-width var(--dur-base) var(--ease-out);
}

/* Dim the rest only while something is actually highlighted, so the default
   state is the full-strength chart rather than a permanently faded one. */
.style-wheel.is-focused .style-wheel__seg { opacity: 0.32; }
.style-wheel.is-focused .style-wheel__seg.is-active { opacity: 1; stroke-width: 42; }

.style-wheel__centre {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
  padding: 0 22%;
}

.style-wheel__centre-num {
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  line-height: 1;
  color: var(--color-text);
}

.style-wheel__centre-label {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-top: 6px;
  overflow-wrap: anywhere;
}

.style-wheel__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(140px, 1fr));
  gap: var(--space-2) var(--space-5);
  flex: 1 1 260px;
  max-width: 420px;
}

.style-wheel__key {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  font-size: var(--text-sm);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}

.style-wheel__key:hover,
.style-wheel__key.is-active {
  background: var(--color-bg-alt);
  color: var(--color-text);
}

.style-wheel__dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  flex-shrink: 0;
}

.style-wheel__name {
  flex: 1;
  min-width: 0;
}

.style-wheel__pct {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  flex-shrink: 0;
}

@media (max-width: 600px) {
  .style-wheel { gap: var(--space-5); }
  .style-wheel__legend { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px var(--space-3); }
  .style-wheel__key { padding: 6px 4px; font-size: var(--text-xs); }
}

/* One column below 380px: two legend columns at that width clip the longer
   family names ("Floral Oriental") rather than wrapping them usefully. */
@media (max-width: 380px) {
  .style-wheel__legend { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .style-wheel__seg { transition: none; }
}
   BANK TRANSFER — the account details shown at checkout when the method is
   picked, and again on the confirmation screen with the amount and reference.
   Plain rows of text on purpose: a shopper copies these into a banking app.
   -------------------------------------------------------------------------- */
.bank-panel {
  margin-top: var(--space-3);
  padding: var(--space-5);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
}
.confirm-panel.bank-panel { margin-top: var(--space-5); }
.bank-panel__head {
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-3);
}
.bank-panel__rows { display: flex; flex-direction: column; gap: var(--space-2); }
.bank-panel__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-sm);
  padding-bottom: var(--space-2);
  border-bottom: 1px dashed var(--color-border);
}
.bank-panel__row:last-child { border-bottom: 0; padding-bottom: 0; }
.bank-panel__key { color: var(--color-text-secondary); flex-shrink: 0; }
.bank-panel__val {
  font-family: var(--font-mono);
  color: var(--color-text);
  text-align: right;
  word-break: break-all;
  user-select: all;
}
.bank-panel__note {
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-secondary);
}

/* ---- Ring sizer (js/ring-sizer.js) ----
   Lives in the "Which size?" modal on ring product pages and inline on the
   Ring Size Guide page. */
.ring-sizer { color: var(--color-text-secondary); line-height: 1.6; }
.ring-sizer__tabs {
  display: flex; gap: var(--space-2); flex-wrap: wrap;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-5);
}
.ring-sizer__tab {
  padding: var(--space-3) var(--space-3);
  margin-bottom: -1px;
  background: none;
  border-bottom: 2px solid transparent;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  cursor: pointer;
}
.ring-sizer__tab.is-active { color: var(--color-text); border-bottom-color: var(--color-accent); }
.ring-sizer__panel { display: none; }
.ring-sizer__panel.is-active { display: block; }
.ring-sizer__lead { font-size: var(--text-sm); margin-bottom: var(--space-4); }
.ring-sizer__measure { display: grid; grid-template-columns: 1fr 1.4fr; gap: var(--space-3); margin-bottom: var(--space-4); }
.ring-sizer__field span {
  display: block; margin-bottom: var(--space-1);
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase;
}
.ring-sizer__field input, .ring-sizer__field select {
  width: 100%; height: 44px; padding: 0 var(--space-3);
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-bg); color: var(--color-text); font-size: var(--text-base);
}
.ring-sizer__result, .ring-sizer__readout {
  border: 1px solid var(--color-border); border-radius: var(--radius-md);
  background: var(--color-card); padding: var(--space-4); text-align: center;
}
.ring-sizer__size { font-family: var(--font-display); font-size: var(--text-xl); color: var(--color-text); margin: 0; }
.ring-sizer__size strong { font-size: var(--text-3xl); color: var(--color-accent); }
.ring-sizer__size span { font-size: var(--text-base); color: var(--color-text-secondary); }
.ring-sizer__meta { font-size: var(--text-sm); margin: var(--space-1) 0 0; }
.ring-sizer__miss { margin: 0; font-size: var(--text-sm); }

.ring-sizer__calibrate { margin-bottom: var(--space-5); }
.ring-sizer__card {
  height: 54px; max-width: 100%;
  border: 2px dashed var(--color-accent); border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 0.65rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-text-secondary); text-align: center; padding: 0 var(--space-2);
  margin-bottom: var(--space-2); box-sizing: border-box;
}
.ring-sizer__calibrate input[type="range"] { width: 100%; accent-color: var(--color-accent); }
.ring-sizer__hint { font-size: var(--text-xs); margin: var(--space-1) 0 0; }
.ring-sizer__stage { display: flex; align-items: center; justify-content: center; gap: var(--space-4); margin-bottom: var(--space-3); }
.ring-sizer__circle-wrap {
  width: 120px; height: 120px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.ring-sizer__circle {
  border-radius: 50%;
  border: 1.5px solid var(--color-accent);
  box-shadow: inset 0 0 0 1px var(--color-bg), 0 0 0 1px var(--color-bg);
  background: var(--color-card);
}
.ring-sizer__step {
  width: 44px; height: 44px; border-radius: 50%;
  border: 1px solid var(--color-border); background: var(--color-bg);
  font-size: var(--text-xl); color: var(--color-text); cursor: pointer;
}
.ring-sizer__step:hover { border-color: var(--color-accent); color: var(--color-accent); }
.ring-sizer__table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.ring-sizer__table th, .ring-sizer__table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border); text-align: center; }
.ring-sizer__table th { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-text); }
.ring-sizer__table tbody tr:nth-child(even) { background: var(--color-card); }
.ring-sizer__tip { font-size: var(--text-xs); margin: var(--space-3) 0 0; }

/* The "Ring size chart" link beside the option select on ring products. */
.ring-size-link {
  display: inline-block; margin-top: var(--space-2);
  font-size: var(--text-sm); color: var(--color-accent);
  background: none; padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
}

@media (max-width: 480px) {
  .ring-sizer__measure { grid-template-columns: 1fr; }
  .ring-sizer__tab { padding: var(--space-2); font-size: 0.62rem; letter-spacing: 0.06em; }
  .ring-sizer__table th, .ring-sizer__table td { padding: var(--space-2) var(--space-1); font-size: var(--text-xs); }
}

/* ==========================================================================
   HERO SLIDER (js/hero-slider.js)

   Full-bleed banner photographs with the copy laid over the empty side of
   each one. The client's banners are 1920x700 with the jewellery on one side,
   so every slide carries its own alignment and the text never covers a piece.

   On a phone the 1920x700 crop leaves no usable space beside the product, so
   the layout stacks instead: photo on top at its own aspect ratio, copy on
   the cream panel under it. Nothing is cropped away and nothing is unreadable.
   ========================================================================== */
.hero-slider {
  position: relative;
  overflow: hidden;
  background: var(--color-bg-alt);
  border-bottom: 1px solid var(--color-border);
}
.hero-slider__viewport { position: relative; }

.hero-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-slow) var(--ease-out), visibility var(--dur-slow);
}
.hero-slide.is-active { opacity: 1; visibility: visible; position: relative; }

/* Only the active slide is in flow, so the viewport is as tall as the tallest
   thing it must show without a fixed height guess. */
.hero-slide__media { display: block; }
.hero-slide__media img {
  display: block;
  width: 100%;
  height: clamp(340px, 34vw, 520px);
  object-fit: cover;
  object-position: center;
}

/* A soft wash from the copy side only: the banners are pale, and dark type on
   a busy pale photograph needs a little help without the photo looking greyed. */
.hero-slide__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.hero-slide--left .hero-slide__scrim {
  background: linear-gradient(90deg, rgba(255,255,255,0.86) 0%, rgba(255,255,255,0.58) 32%, rgba(255,255,255,0) 60%);
}
.hero-slide--right .hero-slide__scrim {
  background: linear-gradient(270deg, rgba(255,255,255,0.86) 0%, rgba(255,255,255,0.58) 32%, rgba(255,255,255,0) 60%);
}
.hero-slide--center .hero-slide__scrim {
  background: radial-gradient(ellipse at center, rgba(255,255,255,0.80) 0%, rgba(255,255,255,0.45) 45%, rgba(255,255,255,0) 75%);
}

.hero-slide__inner {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  pointer-events: none;
}
.hero-slide__inner--left { justify-content: flex-start; }
.hero-slide__inner--center { justify-content: center; text-align: center; }
.hero-slide__inner--right { justify-content: flex-end; }

.hero-slide__copy {
  /* Never wider than the empty half of the photograph: the banners put the
     jewellery on one side, and copy that spills past the midline sits on top
     of a product rather than beside it. */
  max-width: min(34rem, 45%);
  pointer-events: auto;
}
.hero-slide__inner--center .hero-slide__copy { max-width: min(40rem, 72%); }

.hero-slide__title {
  font-size: clamp(2rem, 1.1rem + 3.2vw, 4rem);
  line-height: 1.06;
  margin-top: var(--space-3);
  color: var(--color-text);
}
.hero-slide__sub {
  margin-top: var(--space-4);
  font-size: var(--text-lg);
  color: var(--color-text-secondary);
  max-width: 30rem;
}
.hero-slide__inner--center .hero-slide__sub { margin-inline: auto; }
.hero-slide__ctas {
  display: flex;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-top: var(--space-7);
}
.hero-slide__inner--center .hero-slide__ctas { justify-content: center; }

/* ---- Controls ---- */
.hero-slider__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  background: rgba(255,255,255,0.86);
  color: var(--color-text);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
  z-index: 2;
}
.hero-slider__arrow svg { width: 20px; height: 20px; }
.hero-slider:hover .hero-slider__arrow,
.hero-slider__arrow:focus-visible { opacity: 1; }
.hero-slider__arrow:hover { background: #fff; }
.hero-slider__arrow--prev { left: var(--space-5); }
.hero-slider__arrow--next { right: var(--space-5); }

.hero-slider__dots {
  position: absolute;
  left: 0; right: 0;
  bottom: var(--space-5);
  display: flex;
  justify-content: center;
  gap: var(--space-2);
  z-index: 2;
}
.hero-slider__dot {
  width: 9px; height: 9px;
  padding: 0;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-accent);
  background: rgba(255,255,255,0.65);
  cursor: pointer;
  transition: width var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out);
}
.hero-slider__dot.is-active { width: 26px; background: var(--color-accent); }

/* Touch devices have no hover, so the arrows would never appear. */
@media (hover: none) {
  .hero-slider__arrow { display: none; }
}

/* ---- Phones: stack the photo and the copy ---- */
@media (max-width: 768px) {
  .hero-slide { position: absolute; }
  .hero-slide.is-active { position: relative; }
  .hero-slide__media img {
    height: auto;
    aspect-ratio: 16 / 10;
  }
  .hero-slide__scrim { display: none; }
  .hero-slide__inner {
    position: static;
    display: block;
    padding-top: var(--space-6);
    padding-bottom: var(--space-10);
    text-align: center;
  }
  .hero-slide__copy { max-width: none; }
  .hero-slide__sub { margin-inline: auto; font-size: var(--text-base); }
  .hero-slide__ctas { justify-content: center; margin-top: var(--space-5); }
  .hero-slider__dots { bottom: var(--space-3); }
}

/* animations.css */
/* ==========================================================================
   ANIMATIONS — keyframes + transition utilities
   ========================================================================== */

@keyframes skeletonPulse {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@keyframes toastIn {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

@keyframes fadeSlideUp {
  from { opacity: 0; transform: translateY(40px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes pulseRing {
  0% { box-shadow: 0 0 0 0 var(--color-accent-soft); }
  70% { box-shadow: 0 0 0 10px rgba(140, 109, 31, 0); }
  100% { box-shadow: 0 0 0 0 rgba(140, 109, 31, 0); }
}

@keyframes cartPulse {
  0% { transform: scale(1); }
  30% { transform: scale(1.25); }
  60% { transform: scale(0.95); }
  100% { transform: scale(1); }
}

.is-cart-pulsing { animation: cartPulse 420ms var(--ease-out); }

.reveal {
  opacity: 0;
  transform: translateY(40px);
}
.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 800ms var(--ease-out), transform 800ms var(--ease-out);
}
.reveal[data-delay="1"] { transition-delay: 80ms; }
.reveal[data-delay="2"] { transition-delay: 160ms; }
.reveal[data-delay="3"] { transition-delay: 240ms; }
.reveal[data-delay="4"] { transition-delay: 320ms; }

.spinner {
  width: 20px; height: 20px;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-accent);
  border-radius: 50%;
  animation: spin 700ms linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
  .is-cart-pulsing, .spinner { animation: none; }
}

/* nav.css */
/* ==========================================================================
   NAV — navigation bar + mobile menu
   ========================================================================== */
.announcement-bar {
  position: relative;
  background: linear-gradient(90deg, var(--color-accent-hover), var(--color-accent) 55%, var(--color-accent-hover));
  color: var(--color-bg);
  overflow: hidden;
  white-space: nowrap;
  padding: 0.4rem var(--space-10) 0.4rem 0;
  max-height: 32px;
  transition: max-height var(--dur-base) var(--ease-out), padding var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.announcement-bar.is-dismissed {
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
}
.announcement-bar__track {
  display: inline-flex;
  animation: marquee 22s linear infinite;
}
.announcement-bar__track span {
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 0 var(--space-6);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
}
.announcement-bar__track span svg {
  width: 13px; height: 13px;
  stroke: currentColor;
  fill: none;
  flex-shrink: 0;
}
.announcement-bar__close {
  position: absolute;
  top: 50%; right: var(--space-4);
  transform: translateY(-50%);
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  color: var(--color-bg);
  opacity: 0.7;
  transition: opacity var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.announcement-bar__close:hover { opacity: 1; background: rgba(255,255,255,0.18); }
.announcement-bar__close svg { width: 11px; height: 11px; stroke: currentColor; stroke-width: 2.4; }

.navbar {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
  animation: navEnter 650ms var(--ease-out);
}
@keyframes navEnter {
  from { opacity: 0; transform: translateY(-14px); }
  to { opacity: 1; transform: translateY(0); }
}
.navbar.is-solid {
  /* Light theme: the compact bar stays white. The dark glass it inherited
     from the perfume theme sat on a cream page like a black band. */
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--color-border);
  box-shadow: 0 8px 28px rgba(26, 23, 19, 0.08);
}

/* Scrolling down past the fold slides the bar away; scrolling up any amount
   brings it straight back (see App.initStickyHeader). Transform rather than
   display, so it animates and never reflows the page. */
.navbar.is-hidden { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  /* Never hide the header for someone who asked for less motion — a bar that
     disappears and reappears is exactly the effect they opted out of. */
  .navbar.is-hidden { transform: none; }
  .navbar { animation: none; }
}

.navbar__progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  width: 0%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-accent-hover));
  box-shadow: 0 0 6px rgba(140, 109, 31, 0.35);
  transition: width 80ms linear;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   ROW 1 — search (left) · logo (centre) · account + cart (right)

   A three-column grid rather than flexbox with space-between: the logo has to
   sit in the true centre of the header regardless of how wide the left and
   right groups happen to be, and only a fixed centre column guarantees that.
   -------------------------------------------------------------------------- */
.navbar__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-6);
  padding-block: var(--space-5);
  transition: padding-block var(--dur-base) var(--ease-out);
}
.navbar.is-solid .navbar__inner { padding-block: var(--space-3); }

.navbar__left { display: flex; align-items: center; gap: var(--space-3); justify-self: start; }

/* Pill search, always visible on desktop. */
.navbar__searchbox {
  display: flex;
  align-items: center;
  width: clamp(200px, 22vw, 320px);
  height: 40px;
  padding: 0 4px 0 18px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: rgba(255, 255, 255, 0.04);
  transition: border-color var(--dur-fast) var(--ease-out), width var(--dur-base) var(--ease-out);
}
.navbar__searchbox:focus-within { border-color: var(--color-accent); }
.navbar__searchbox input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  color: var(--color-text);
  font-size: var(--text-sm);
}
.navbar__searchbox input::placeholder { color: var(--color-text-muted); }
.navbar__searchbox button {
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  border: none;
  border-radius: var(--radius-full);
  background: none;
  color: var(--color-text);
  cursor: pointer;
  flex-shrink: 0;
}
.navbar__searchbox button svg { width: 17px; height: 17px; }
.navbar__searchbox button:hover { color: var(--color-accent); }

/* The icon-only search button replaces the pill once space runs out. */
/* Hidden while the pill is shown. Scoped to .navbar__left so it outranks
   .navbar__icon-btn { display: flex }, which is written later in this
   file and would otherwise win on source order. */
.navbar__left .navbar__search-toggle { display: none; }

.navbar__logo {
  justify-self: center;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 0.8rem + 1.8vw, 1.85rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--color-text);
  white-space: nowrap;
  transition: font-size var(--dur-base) var(--ease-out), letter-spacing var(--dur-base) var(--ease-out);
}
.navbar__logo:hover { letter-spacing: 0.03em; }
.navbar__logo span { color: var(--color-accent); }
.navbar.is-solid .navbar__logo { font-size: clamp(0.95rem, 0.7rem + 1.3vw, 1.3rem); }
.navbar__logo-mark {
  display: inline-flex;
  width: 1.3em; height: 1.3em;
  flex-shrink: 0;
  color: var(--color-accent);
  transition: transform var(--dur-slow) var(--ease-out);
}
.navbar__logo-mark svg { width: 100%; height: 100%; stroke: currentColor; fill: none; }
.navbar__logo-text { white-space: nowrap; }

/* Brand image. Height-driven with width:auto so the 2048x531 source scales by
   its own ratio and never distorts; the explicit width/height attributes in
   the markup still reserve the right box before it loads. */
.navbar__logo-img {
  display: block;
  height: 52px;
  width: auto;
  /* Intrinsic ratio stated explicitly: an `auto` grid column sizing itself
     from an image that is itself sized by `max-width: 100%` of that column is
     circular, and resolves to zero width. */
  aspect-ratio: 2832 / 546;
  object-fit: contain;
  transition: height var(--dur-base) var(--ease-out);
}
.navbar.is-solid .navbar__logo-img { height: 38px; }
/* The footer mark was 40px in a column three times that wide, which read as
   an empty corner rather than a logo. */
.footer__brand .navbar__logo-img { height: 62px; }
.footer__brand .navbar__logo { display: inline-block; margin-bottom: var(--space-2); }

@media (max-width: 768px) {
  .footer__brand .navbar__logo-img { height: 54px; }
}
.navbar__logo:hover .navbar__logo-mark { transform: rotate(8deg) scale(1.08); }
.footer__brand .navbar__logo { font-size: var(--text-xl); justify-self: start; }

.navbar__actions { display: flex; align-items: center; gap: var(--space-5); justify-self: end; }

/* Labelled actions ("ACCOUNT", "CART") as in the reference — the word does the
   work the icon alone can't, especially for less confident shoppers. */
.navbar__action {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: color var(--dur-fast) var(--ease-out);
}
.navbar__action:hover { color: var(--color-accent); }
.navbar__action svg { width: 21px; height: 21px; stroke: currentColor; fill: none; flex-shrink: 0; }

.navbar__icon-btn {
  position: relative;
  width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  color: var(--color-text);
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.navbar__icon-btn:hover { background: var(--color-accent-soft); color: var(--color-accent); }
.navbar__icon-btn svg { width: 20px; height: 20px; stroke: currentColor; fill: none; }

.is-wishlist-pulsing { animation: cartPulse 420ms var(--ease-out); }

.navbar__badge {
  position: absolute;
  top: -6px; right: -10px;
  min-width: 16px; height: 16px;
  padding: 0 3px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: var(--color-bg);
  font-family: var(--font-mono);
  font-size: 0.6rem;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
}

/* --------------------------------------------------------------------------
   ROW 2 — the admin-managed menu.

   Collapses to zero height once the page scrolls, which is what makes the
   sticky header shrink to the compact bar in the reference. max-height rather
   than display so it animates.
   -------------------------------------------------------------------------- */
.navbar__menu-row {
  border-top: 1px solid var(--color-border);
  background: transparent;
  max-height: 56px;
  /* MUST be visible while the row is showing: the dropdown panels are
     absolutely positioned inside this row and hang below it, so `hidden`
     here clips them away entirely — the menu opens, and nothing appears.
     Clipping is only needed while the row is collapsing to zero, so it is
     applied in the collapsed state instead. */
  overflow: visible;
  transition: max-height var(--dur-base) var(--ease-out),
              opacity var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.navbar.is-solid .navbar__menu-row {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  border-top-color: transparent;
}
/* Opening the menu from the compact bar brings the row back. */
.navbar.is-menu-pinned .navbar__menu-row {
  max-height: 56px;
  overflow: visible;
  opacity: 1;
  border-top-color: var(--color-border);
}

/* The links row itself. `.navbar__links` also carries `.container`, whose
   `display: block` would otherwise win — this rule was lost in an earlier
   edit, which left every menu item stacked as a full-width block and the
   dropdowns stretched across the whole page. */
.navbar__links {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: nowrap;
  gap: var(--space-8);
  padding-block: 1.05rem;
  /* NOT a scroll container. Setting overflow on one axis makes the other
     compute to `auto` as well, which clipped the dropdown hanging below the
     row — the menu opened but was invisible. Below 1025px this whole row is
     replaced by the burger drawer, so it never needs to scroll. */
  overflow: visible;
}
.navbar__links > * { flex: 0 0 auto; }

/* --------------------------------------------------------------------------
   MENU LINKS + DROPDOWN

   A compact dropdown anchored under its own trigger, not a full-bleed panel.
   The menu is admin-managed, so a dropdown holds however many links the shop
   owner added — usually five or six. A full-width panel for six links leaves
   most of the screen empty, which is what the previous version did.
   -------------------------------------------------------------------------- */
.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  padding: 4px 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--color-text-secondary);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out);
}
.nav-link::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: center;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav-link:hover,
.nav-link.is-active { color: var(--color-text); }
.nav-link:hover::after,
.nav-link.is-active::after { transform: scaleX(1); }

.nav-link--highlight { color: var(--color-accent); }
.nav-link--highlight:hover { color: var(--color-accent-hover); }

.nav-mega { position: relative; }
.nav-mega__chevron {
  width: 10px; height: 10px;
  opacity: 0.7;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav-mega.is-open .nav-mega__trigger { color: var(--color-text); }
.nav-mega.is-open .nav-mega__chevron { transform: rotate(180deg); }

.nav-mega__panel {
  position: absolute;
  top: 100%;
  left: 50%;
  min-width: 220px;
  margin-top: 14px;
  padding: var(--space-3) 0;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 16px 40px rgba(26, 23, 19, 0.12);
  opacity: 0;
  visibility: hidden;
  transform: translate(-50%, -6px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility 0s linear var(--dur-base);
  z-index: 20;
}
/* `:hover` as well as the JS class, so the dropdown works on a pointer device
   even before the bundle has finished binding its listeners. The JS class is
   still what keyboard focus and Escape drive. */
.nav-mega:hover .nav-mega__panel,
.nav-mega.is-open .nav-mega__panel {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition-delay: 0s;
}
.nav-mega:hover .nav-mega__chevron { transform: rotate(180deg); }
.nav-mega:hover .nav-mega__trigger { color: var(--color-text); }
/* Bridges the gap between trigger and panel so the pointer can cross without
   the panel closing under it. */
.nav-mega__panel::before {
  content: '';
  position: absolute;
  top: -14px; left: 0; right: 0;
  height: 14px;
}

.nav-mega__inner { display: block; }
.nav-mega__panel h4 { display: none; }
.nav-mega__col ul { display: block; }
.nav-mega__col a {
  display: block;
  padding: 9px var(--space-5);
  font-size: var(--text-sm);
  color: var(--color-text-secondary);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out), background var(--dur-fast) var(--ease-out);
}
.nav-mega__col a:hover {
  color: var(--color-accent);
  background: var(--color-accent-soft);
}

/* --------------------------------------------------------------------------
   COUNTDOWN SALE BAR
   Sits above everything, colours set in Admin → Settings. Hidden entirely
   when switched off or once the end date passes.
   -------------------------------------------------------------------------- */
.countdown-bar {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: 0.7rem var(--space-10);
  background: var(--countdown-bg, #14562F);
  color: var(--countdown-fg, #FFFFFF);
  font-size: var(--text-sm);
  text-align: center;
}
.countdown-bar[hidden] { display: none; }
.countdown-bar__text { font-weight: 500; letter-spacing: 0.01em; }
.countdown-bar__suffix { opacity: 0.92; }

.countdown-clock { display: inline-flex; align-items: flex-start; gap: 6px; }
.countdown-unit { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.countdown-unit__label {
  font-family: var(--font-mono);
  font-size: 0.5rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.85;
  line-height: 1;
}
.countdown-unit__digits { display: flex; gap: 2px; }
/* Each digit on its own tile, as in the reference. */
.countdown-digit {
  min-width: 17px;
  padding: 3px 2px;
  border-radius: 3px;
  background: #FFFFFF;
  color: #111111;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 700;
  line-height: 1;
  text-align: center;
}
.countdown-bar__close {
  position: absolute;
  top: 50%; right: var(--space-4);
  transform: translateY(-50%);
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  border: none;
  background: none;
  color: currentColor;
  opacity: 0.75;
  cursor: pointer;
}
.countdown-bar__close:hover { opacity: 1; }
.countdown-bar__close svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 2.2; }


/* --------------------------------------------------------------------------
   EXPANDING SEARCH PANEL
   Opened by the search icon on narrow screens. Closed height MUST be 0 —
   without this rule the panel sits open at full height and pushes the whole
   header down the page.
   -------------------------------------------------------------------------- */
.navbar__search-panel {
  max-height: 0;
  overflow: hidden;
  border-top: 1px solid transparent;
  transition: max-height var(--dur-base) var(--ease-out), border-color var(--dur-base) var(--ease-out);
}
.navbar__search-panel.is-open {
  max-height: 560px;
  border-top-color: var(--color-border);
}
.navbar__search-form {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5) 0;
}
.navbar__search-form svg { width: 20px; height: 20px; stroke: var(--color-text-secondary); flex-shrink: 0; }
.navbar__search-form input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  font-family: var(--font-display);
  font-size: var(--text-xl);
  color: var(--color-text);
}
.navbar__search-form input::placeholder { color: var(--color-text-muted); }
.navbar__search-close {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border: none;
  background: none;
  border-radius: var(--radius-full);
  color: var(--color-text-secondary);
  cursor: pointer;
  flex-shrink: 0;
}
.navbar__search-close:hover { background: var(--color-accent-soft); color: var(--color-accent); }
.navbar__search-close svg { width: 16px; height: 16px; }

.navbar__search-suggestions {
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height var(--dur-base) var(--ease-out), opacity var(--dur-fast) var(--ease-out);
}
.navbar__search-suggestions.is-open { max-height: 420px; opacity: 1; padding-bottom: var(--space-5); }
.navbar__search-suggestion {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-top: 1px solid var(--color-border);
}
.navbar__search-suggestion img {
  width: 44px; height: 56px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  flex-shrink: 0;
}
.navbar__search-suggestion > div { display: flex; flex-direction: column; gap: 2px; }
.navbar__search-suggestion__name {
  font-size: var(--text-sm);
  color: var(--color-text);
  transition: color var(--dur-fast) var(--ease-out);
}
.navbar__search-suggestion:hover .navbar__search-suggestion__name { color: var(--color-accent); }
.navbar__search-suggestion__price { font-size: var(--text-xs); color: var(--color-text-secondary); }
.navbar__search-suggestion--all {
  justify-content: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.navbar__search-empty {
  padding: var(--space-4) 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* --------------------------------------------------------------------------
   BURGER + MOBILE DRAWER
   -------------------------------------------------------------------------- */
.navbar__burger {
  display: none;
  width: 42px; height: 42px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  border: none;
  background: none;
  cursor: pointer;
  transition: width var(--dur-base) var(--ease-out), height var(--dur-base) var(--ease-out);
}
.navbar.is-solid .navbar__burger { width: 36px; height: 36px; }
.navbar__burger span {
  width: 22px; height: 1.5px;
  background: var(--color-text);
  transition: transform var(--dur-base) var(--ease-out), opacity var(--dur-base) var(--ease-out);
}
.navbar__burger.is-open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.navbar__burger.is-open span:nth-child(2) { opacity: 0; }
.navbar__burger.is-open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.mobile-menu {
  position: fixed;
  inset: 0;
  overflow: hidden;
  /* Was near-black with dark link text on top — unreadable on this theme. */
  background: rgba(255,255,255,0.98);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  z-index: calc(var(--z-nav) + 1);
  display: flex;
  flex-direction: column;
  padding: calc(var(--space-16) + var(--space-2)) var(--space-6) var(--space-8);
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.mobile-menu.is-open { transform: translateX(0); }

.mobile-menu__close {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  width: 42px; height: 42px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  background: transparent;
  cursor: pointer;
  z-index: 2;
}
.mobile-menu__close:hover { border-color: var(--color-accent); color: var(--color-accent); }
.mobile-menu__close svg { width: 16px; height: 16px; stroke: currentColor; }

.mobile-menu__links {
  display: flex;
  flex-direction: column;
  gap: var(--space-7);
  overflow-y: auto;
  flex: 1;
  padding-bottom: var(--space-6);
  -webkit-overflow-scrolling: touch;
}
.mobile-menu__group { display: flex; flex-direction: column; }
.mobile-menu__heading {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-2);
}
.mobile-menu__links a {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border);
  opacity: 1;
  transform: translateX(0);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}
.mobile-menu__links a:active { color: var(--color-accent); }
.mobile-menu:not(.is-open) .mobile-menu__links a {
  opacity: 0;
  transform: translateX(24px);
  transition-delay: 0ms;
}
/* Stagger by group, since the links sit one level deeper than a flat list. */
.mobile-menu.is-open .mobile-menu__group:nth-child(1) a { transition-delay: 60ms; }
.mobile-menu.is-open .mobile-menu__group:nth-child(2) a { transition-delay: 120ms; }
.mobile-menu.is-open .mobile-menu__group:nth-child(3) a { transition-delay: 180ms; }

.mobile-menu__footer {
  padding-top: var(--space-6);
  display: flex;
  align-items: center;
  justify-content: space-between;
  opacity: 1;
  transition: opacity var(--dur-base) var(--ease-out);
  transition-delay: 380ms;
}
.mobile-menu:not(.is-open) .mobile-menu__footer { opacity: 0; transition-delay: 0ms; }
.mobile-menu__footer p {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  letter-spacing: 0.04em;
}
.mobile-menu__footer .footer__social { margin-top: 0; }

/* --------------------------------------------------------------------------
   FOOTER
   -------------------------------------------------------------------------- */
.footer {
  background: var(--color-bg-alt);
  border-top: 1px solid var(--color-border);
  padding-top: var(--space-12);
  margin-top: auto;
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: var(--space-8);
  padding-bottom: var(--space-10);
}
.footer__brand p { margin-top: var(--space-3); max-width: 320px; }
.footer h5 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text);
  margin-bottom: var(--space-4);
}
.footer ul { display: flex; flex-direction: column; gap: var(--space-3); }
.footer ul a { color: var(--color-text-secondary); font-size: var(--text-sm); }
.footer ul a:hover { color: var(--color-accent); }

.footer__social { display: flex; gap: var(--space-3); margin-top: var(--space-5); }
.footer__social a {
  width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
}
.footer__social a:hover { border-color: var(--color-accent); color: var(--color-accent); }
.footer__social svg { width: 16px; height: 16px; stroke: currentColor; fill: none; }

.footer__bottom {
  border-top: 1px solid var(--color-border);
  padding: var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: var(--text-xs);
  color: var(--color-text-muted);
}
.footer__payments { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.footer__payments span {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

/* ---- Checkout header ----
   Logo, "Secure Checkout", back-to-cart — no burger, no search, no menu row.
   The generic three-column grid put the logo in a stretched first column and
   the cart icon at the start of the third, so on a phone the wordmark sat
   flush against the left edge and the icon floated mid-header. */
.navbar--checkout .navbar__inner {
  grid-template-columns: auto 1fr auto;
}
.navbar--checkout .navbar__inner > .eyebrow { text-align: center; }
.navbar--checkout .navbar__icon-btn { justify-self: end; }

@media (max-width: 480px) {
  .navbar--checkout .navbar__inner { padding-inline: var(--space-3); }
  .navbar--checkout .navbar__logo-img { max-width: 150px; }
}

/* cart-drawer.css */
/* ==========================================================================
   CART DRAWER — slide-in cart panel
   ========================================================================== */
.cart-drawer-overlay {
  position: fixed;
  inset: 0;
  background: var(--color-overlay);
  z-index: var(--z-drawer);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}
.cart-drawer-overlay.is-open { opacity: 1; pointer-events: auto; }

.cart-drawer {
  position: fixed;
  top: 0; right: 0;
  bottom: 0;
  width: 420px;
  max-width: 100vw;
  background: var(--color-bg);
  border-left: 1px solid var(--color-border);
  z-index: calc(var(--z-drawer) + 1);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-out);
}
.cart-drawer.is-open { transform: translateX(0); }

.cart-drawer__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-5) var(--space-6);
  border-bottom: 1px solid var(--color-border);
}
.cart-drawer__head h4 { font-size: var(--text-xl); }

.cart-drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-5) var(--space-6);
}

.cart-line {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4) 0;
  border-bottom: 1px solid var(--color-border);
}
.cart-line__img {
  width: 84px; height: 100px;
  object-fit: cover;
  border-radius: var(--radius-md);
  background: var(--color-card);
  flex-shrink: 0;
}
.cart-line__info { flex: 1; display: flex; flex-direction: column; gap: var(--space-1); }
.cart-line__name { font-family: var(--font-display); font-size: var(--text-lg); }
.cart-line__attrs { font-size: var(--text-xs); color: var(--color-text-muted); }
.cart-line__foot { display: flex; align-items: center; justify-content: space-between; margin-top: auto; }
.cart-line__remove { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-text-muted); text-decoration: underline; }
.cart-line__remove:hover { color: var(--color-error); }

.cart-drawer__foot {
  padding: var(--space-5) var(--space-6);
  border-top: 1px solid var(--color-border);
}
.cart-drawer__subtotal {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-xl);
}
.cart-drawer__note { font-size: var(--text-xs); color: var(--color-text-secondary); text-align: center; margin-top: var(--space-3); }

/* responsive.css */
/* ==========================================================================
   RESPONSIVE — mobile-first breakpoints (always loaded last)
   xs: 0-480 · sm: 481-768 · md: 769-1024 · lg: 1025-1280 · xl: 1281+
   ========================================================================== */

/* ---- Base mobile rules (apply up to 1025px) ---- */
@media (max-width: 1025px) {
  :root {
    --text-5xl: 2.75rem;
    --text-4xl: 2.25rem;
    --text-3xl: 1.85rem;
    --text-2xl: 1.4rem;
  }

  .container { padding-inline: var(--space-4); }
  .section { padding-block: var(--space-8); }

  /* Row 2 (the menu) is replaced by the burger drawer below 1025px. */
  .navbar__menu-row { display: none; }
  .navbar__burger { display: flex; }
  .nav-mega__panel { display: none; }

  /* The pill needs more room than a phone header has — swap it for the icon
     that opens the full-width search panel. */
  .navbar__searchbox { display: none; }
  .navbar__left .navbar__search-toggle { display: flex; }

  /* Icons only; the words would wrap and break the three-column grid. */
  .navbar__action span:not(.navbar__badge) { display: none; }
  .navbar__actions { gap: var(--space-3); }

  /* The whole burger-menu range (up to 768px) gets the compact header —
     previously this only applied below 480px, so large phones and small
     tablets (481-768px) got squeezed into the burger layout while still
     carrying full desktop padding, making the header feel oversized. */
  .navbar__inner { padding-block: var(--space-3); }

  /* The header now carries search on the left and account/cart on the right
     as icons. The old rule here hid [aria-label="Search"] outright, which —
     combined with the pill also being hidden — left phones with no way to
     search at all. */
  .navbar__icon-btn { width: 38px; height: 38px; }

  /* Checkout's minimal 3-up header: drop the middle label first */
  .navbar__inner > .eyebrow { display: none; }

  .grid--2, .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); gap: var(--space-4); }
  .split { grid-template-columns: 1fr; gap: var(--space-6); }

  .cart-drawer { width: 100%; }

  .footer__grid { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
  .footer__bottom { flex-direction: column; gap: var(--space-3); text-align: center; }

  .trust-bar { justify-content: flex-start; overflow-x: auto; }

  .field-row { grid-template-columns: 1fr; gap: 0; }

  .cart-layout, .checkout-layout { grid-template-columns: 1fr; }
  #cartSummary, .checkout-layout aside { position: static !important; }

  .newsletter-form { flex-direction: column; }
  .sale-banner { padding-right: calc(var(--space-6) + 30px); font-size: var(--text-sm); }
  .sale-banner p { font-size: var(--text-xs); }

  .modal { max-width: 100%; }

  .tabs-head { gap: var(--space-4); overflow-x: auto; }

}

/* ---- Filter sidebar becomes a bottom sheet ----
   Only below 769px, which is where shop.html's own script decides to show the
   "Filters" and close buttons (`innerWidth <= 768`). These rules used to sit
   in the 1025px block, so from 769px to 1024px the sidebar was position:fixed
   and translated a full height off-screen while the button that opens it was
   still hidden — the filters were simply unreachable on a tablet, next to a
   220px column of empty space the grid had reserved for them. Above 768px the
   sidebar is now left alone to sit in that column, which is what the
   .shop-layout rules below have always assumed. */
@media (max-width: 768px) {
  .shop-layout { grid-template-columns: 1fr; }

  .filter-sidebar {
    position: fixed;
    left: 0; right: 0;
    bottom: 0;
    top: auto;
    /* dvh follows Safari's collapsing toolbar; vh is the fallback for
       browsers without it. With plain vh the sheet's bottom edge — and the
       "Show N pieces" button — sat behind the toolbar on iPhone. */
    max-height: 85vh;
    max-height: 85dvh;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    transform: translateY(100%);
    transition: transform var(--dur-base) var(--ease-out);
    z-index: var(--z-drawer);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    /* The sticky head owns the top padding (see below) so that rows scrolled
       past it are hidden rather than peeking out above it. */
    padding-top: 0;
    /* Clears the phone's home indicator so the last filter is not sitting
       under it. */
    padding-bottom: calc(var(--space-6) + env(safe-area-inset-bottom));
  }

  /* An off-screen sheet must not be reachable — iOS VoiceOver and a stray
     tab press could otherwise land on a hidden checkbox. */
  .filter-sidebar:not(.is-open) { visibility: hidden; }
  .filter-sidebar.is-open { visibility: visible; }

  /* The backdrop swallows the gesture instead of scrolling the grid behind
     it. On iOS a swipe that scrolls the page also cancels the tap, so the
     sheet could never be dismissed once the shopper had moved. */
  .filter-overlay {
    touch-action: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  /* A bottom sheet is anchored to the bottom, and only to the bottom. The
     open state also set `top: 0`, which stretched the box to the full
     viewport and then clipped it back to max-height from the TOP — so it
     covered the navbar, its rounded corners sat off-screen, and the
     Filters/close header scrolled up out of reach. */
  .filter-sidebar.is-open { transform: translateY(0); }

  /* The way out of the sheet has to stay on screen while its contents
     scroll. */
  .filter-sidebar__head {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--color-card);
    /* Full-bleed: pulled out to the sheet's edges and given the sheet's
       padding back, so it paints over the whole strip it occupies. Before,
       the sheet's own top padding was a transparent gap above the sticky
       head, and every row scrolled through it was visible — "Chains (0)"
       floating above the Filters title. */
    margin: 0 calc(var(--space-6) * -1) var(--space-5);
    padding: var(--space-5) var(--space-6) var(--space-4);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  }

  /* The grab-handle shoppers expect on a bottom sheet. */
  .filter-sidebar__head::before {
    content: "";
    position: absolute;
    top: 8px; left: 50%;
    width: 40px; height: 4px;
    margin-left: -20px;
    border-radius: var(--radius-full);
    background: var(--color-border);
  }
}

/* ---- Extra small phones ---- */
@media (max-width: 480px) {
  /* Product grids stay TWO across on phones.
     They used to collapse to a single full-width column here, which made each
     card ~343x606px — barely one product per screen and a homepage seventeen
     screens tall. Browsing the shop meant scrolling past one jewellery at a time.
     Two-up is what every phone storefront does, and it halves the page.

     .grid--2 is the account address list, where a single column is right, and
     blog cards need the width for their titles — both keep collapsing. */
  .grid--3, .grid--4 { grid-template-columns: repeat(2, 1fr); gap: var(--space-3); }
  .grid--2, #blogGrid { grid-template-columns: 1fr; }

  /* Two-up cards are half as wide, so the padding inside them has to come
     down or the text has nowhere to sit. */
  .product-card__body { padding: var(--space-3); }

  /* The 24px display size needs a full-width card. In a 142px column any
     two-word name ("Midnight Passion") wrapped onto a second line, which also
     left the cards in a row at different heights. */
  .product-card__name { font-size: var(--text-lg); line-height: 1.25; }

  /* Vertical rhythm: 48px above AND below every section is generous on a
     desktop and simply dead space on a 375px screen. */
  .section { padding-block: var(--space-6); }
  .section--tight { padding-block: var(--space-5); }
  .section-head { margin-bottom: var(--space-6); }
  .footer { padding-top: var(--space-8); }

  /* Stacked into one column the four footer blocks ran to 1,100px — more than
     a full phone screen of nothing but links. The three link lists sit two
     across instead; the brand block keeps the full width because its logo and
     paragraph need it. No links are removed, the footer just stops being a
     scroll of its own. */
  .footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-5);
    padding-bottom: var(--space-6);
  }
  .footer__brand { grid-column: 1 / -1; }

  .btn { padding: 0.8rem 1.5rem; }
  .product-card__actions { opacity: 1; transform: none; }
  .product-card__quickadd { opacity: 1; transform: none; position: static; margin-top: var(--space-3); }

  /* ---- Write-a-review form ----
     "Submit Review" and "Cancel" sat in a nowrap flex row: 168px + 12px + 104px
     is 284px of buttons, which does not fit inside a card on a 320px phone, so
     Cancel hung past the card edge. They wrap and share the width instead. */
  #reviewForm .flex,
  .review-form .flex {
    flex-wrap: wrap;
  }

  #reviewForm .flex > .btn,
  .review-form .flex > .btn {
    flex: 1 1 130px;
  }

  /* Star pickers and the rating bars are the other things in this section that
     assume room to spare. Let them shrink rather than push the page sideways. */
  .rating-row { grid-template-columns: 26px 1fr 24px; gap: var(--space-2); }
  .review-card__head { flex-wrap: wrap; gap: var(--space-2); }
}

/* ---- Smallest phones still in real use (320px) ----
   Not a redesign, just the few places where a fixed width or a side-by-side
   pair stops fitting. Anything that only needed to wrap is handled above. */
@media (max-width: 360px) {
  .container { padding-inline: var(--space-3); }

  /* Two product cards plus the gap need every pixel at this width. */
  .grid--3, .grid--4 { gap: var(--space-2); }
  .product-card__body { padding: var(--space-2); }
  .product-card__name { font-size: var(--text-base); }

  /* A 40px control is the smallest that is still comfortably tappable. */
  .qty-stepper { flex-shrink: 0; }
  .btn { padding: 0.75rem 1rem; font-size: var(--text-xs); }
}

/* ---- Tablet ---- */
@media (min-width: 769px) and (max-width: 1024px) {
  .grid--4 { grid-template-columns: repeat(3, 1fr); }
  .shop-layout { grid-template-columns: 220px 1fr; }
}

/* ---- Desktop / large ---- */
@media (min-width: 1025px) {
  .shop-layout { grid-template-columns: 280px 1fr; }
  .filter-sidebar { position: sticky; top: calc(var(--space-6) + 70px); }

  /* The centred-logo layout is now the base layout for every width (a
     three-column grid in nav.css), so this breakpoint no longer needs to
     re-declare it — and must not, because `display: flex` here silently
     overrode the grid and pushed the logo left of centre. */
}

/* ---- Extra large: give the product grid room to breathe instead of
   stretching 3 columns across the full width ---- */
@media (min-width: 1440px) {
  #productGrid.grid--3 { grid-template-columns: repeat(4, 1fr); }
}

/* Prevent horizontal scroll globally.
   `clip` rather than `hidden`: overflow-x:hidden makes <body> a scroll
   container, and a scroll container ancestor stops `position: sticky` working
   at all — which is exactly why the header was not sticking. `clip` crops the
   same way without creating one. */
html, body { overflow-x: clip; }

/* ---- Mega menu: fewer columns before the panel gets cramped ---- */
@media (max-width: 1200px) and (min-width: 1026px) {
  /* Drop the promo tile first — it is the least useful of the four columns
     when space is tight, and the quiz is still linked in the text column. */
  .nav-mega__inner { grid-template-columns: 2fr 1fr 1fr; }
  .nav-mega__promo { display: none; }
}

/* ---- Tablet: keep the pill but shrink it before it crowds the logo ---- */
@media (max-width: 1180px) and (min-width: 1026px) {
  .navbar__searchbox { width: 180px; }
  .navbar__links { gap: var(--space-5); }
}

/* ---- Countdown bar on small screens ---- */
@media (max-width: 640px) {
  .countdown-bar {
    gap: var(--space-2);
    padding: 0.55rem var(--space-8) 0.55rem var(--space-3);
    font-size: var(--text-xs);
  }
  .countdown-digit { min-width: 15px; font-size: 0.72rem; }
  /* The sale name is the first thing to go — the discount and the clock are
     what actually drive urgency. */
  .countdown-bar__suffix { display: none; }
}

/* ---- Narrow phones: make the three header columns actually fit ----
   The wordmark at its desktop size is ~193px, which with the burger/search
   on one side and account/cart on the other overflowed a 375px screen and
   clipped the cart icon off the edge. */
@media (max-width: 480px) {
  .navbar__logo { font-size: 0.98rem; letter-spacing: 0; }
  .navbar__inner { gap: var(--space-2); padding-inline: 0; }
  .navbar__left { gap: 0; }
  .navbar__actions { gap: var(--space-1); }
  .navbar__action svg { width: 19px; height: 19px; }
  .navbar__icon-btn, .navbar__burger { width: 34px; height: 34px; }
  .navbar__action { padding: 4px; }
  /* The badge hangs outside its button, so the last action needs room or the
     count is clipped by the screen edge. */
  .navbar__actions { padding-right: 10px; }
  .navbar__badge { right: -4px; top: -4px; }
}

/* The drawer's "Show N pieces" button is mobile-only — on desktop the
   grid is visible beside the filters, so a count there would be noise. */
.filter-sidebar__apply { display: none; }

/* 768px, not 1025px: this is the sheet's own "close" affordance, and above
   768px there is no sheet to close — the sidebar sits in the layout beside a
   grid the shopper can already see. */
@media (max-width: 768px) {
  .filter-sidebar__apply {
    display: block;
    position: sticky;
    bottom: 0;
    margin-top: var(--space-5);
  }
}

/* Pop-up dialogs use nearly the whole phone width: the ring sizer's
   calibration bar must fit a card's short side (54 mm ≈ 300px) on screen. */
@media (max-width: 480px) {
  .modal { max-width: calc(100vw - 16px); padding: var(--space-5) var(--space-4); }
}

