/* ============================================================
   Handmade Jewelry Shop — Frontend Styles
   ============================================================ */

/* Fonts are not imported here: every storefront page links them through fontLinks() (includes/fonts.php),
   which serves them from this site when their files are present. */

/* ── Variables ─────────────────────────────────────────────── */
:root {
  --gold:         #C9963A;
  --gold-light:   #E8C97A;
  --gold-pale:    #F5E9CC;
  --gold-deep:    #A07828;
  /* The gold as small words and control outlines: a shade of --gold that reads at 4.5:1 on the theme's surfaces and pale tint,
     set per theme by includes/theme.php (themeReadableAccents). --gold itself stays for fills and ornament. */
  --gold-ink:     var(--gold);
  --rose:         #C17B7B;
  --cream:        #FDF8F2;
  --warm-white:   #FFFCF7;
  --dark:         #2A1F1A;
  --medium:       #6B4F3A;
  --text:         #3D2B1F;
  --text-light:   #7A6054;
  --border:       #E8D5B7;
  --shadow-sm:    rgba(42,31,26,0.08);
  --shadow:       rgba(42,31,26,0.14);
  --shadow-lg:    rgba(42,31,26,0.24);

  --ff-head:   'Playfair Display', Georgia, serif;
  --ff-body:   'Nunito', system-ui, sans-serif;
  --ff-script: 'Dancing Script', cursive;

  --ease:      cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --dur:       0.3s;
  --dur-slow:  0.6s;
  /* Height of the fixed nav. Pages that start their content directly beneath
     it need this much clearance or their first line is hidden -- which is what
     happened to the title of every custom content page. main.js measures the
     real nav and overwrites this; the value here is the fallback. */
  --nav-h:     92px;
  /* How much of the page the header covers (pass 4, phase 7). A floating
     header is fixed over the page, so content clears its height; a solid or
     centred header is sticky, part of the page, and covers nothing -- the
     theme sets 0 for those. .below-nav and .page-banner read this, never
     --nav-h, which is why the first line of a page is the same distance
     under the header whichever header a shop has. */
  --nav-overlap:    var(--nav-h);
  /* The one gap between the header and the first thing under it. */
  --below-nav-gap:  clamp(1.25rem, 3vw, 2rem);

  --radius:    14px;
  --radius-sm: 7px;

  /* ── The header's solid state ──
     These three are read as `var(--nav-bg, …)` further down, but a theme
     OPTION also sets `--nav-bg-top: var(--nav-bg)`. A var() with no fallback
     pointing at a property nothing declares makes the whole declaration
     invalid at computed-value time -- silently -- so every family that chose
     a solid or centred header still got a transparent one. Declaring them
     here is what makes those options work; the fallbacks downstream stay as
     documentation of the same values. */
  --nav-bg:    rgba(253,248,242,0.96);
  --nav-ink:   var(--dark);
  --nav-link:  var(--text);
}

/* ── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; font-size: 16px; height: 100%; }
body {
  font-family: var(--ff-body);
  color: var(--text);
  background: var(--warm-white);
  line-height: 1.7;
  overflow-x: hidden;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
main { flex: 1; }
img { max-width: 100%; height: auto; display: block; }
a   { color: inherit; text-decoration: none; }
ul  { list-style: none; }
button { font-family: var(--ff-body); }

/* ── Typography ─────────────────────────────────────────────── */
h1, h2, h3, h4, h5 {
  font-family: var(--ff-head);
  line-height: 1.2;
  color: var(--heading-ink, var(--dark));
}
.script { font-family: var(--ff-script); color: var(--gold); }

/* ── Theme tokens ──
   The small captions ("eyebrows"), the shop name and the hero headline read
   personality tokens that includes/theme.php emits into :root. Every token
   has a fallback equal to the classic look, so a shop that has chosen nothing
   renders exactly as before. The full list is themeTokenDefaults() there and
   docs/STOREFRONT-THEMES.md. */
.eyebrow, .hero-eyebrow, .logo-tag, .footer-tagline {
  text-transform: var(--eyebrow-transform, none);
  letter-spacing: var(--eyebrow-tracking, 0);
  font-weight: var(--eyebrow-weight, 400);
}
/* A hero with a photograph or video behind it keeps light ink whatever the
   theme says: the picture is dark by the overlay hero.php paints on it. */
.hero--has-image, .hero--has-video {
  --hero-ink: #fff;
  --hero-sub-ink: rgba(255,255,255,0.78);
  --hero-accent: var(--gold-light);
  --hero-shadow: 0 4px 40px rgba(0,0,0,0.5);
}
/* And a floating header over that picture is light too. index.php adds the
   class only when the header floats and the theme would otherwise ink it
   dark, so the classic look never sees it. */
.site-nav.nav-over-media:not(.scrolled) {
  --nav-ink-top: #fff;
  --nav-link-top: rgba(255,255,255,0.85);
  --nav-tag-top: rgba(255,255,255,0.7);
}
/* The shop name as a picture (Themes → Logo). Text stays the default. */
.nav-logo-img {
  display: block;
  height: var(--logo-h, 44px);
  width: auto;
  max-width: min(60vw, 260px);
  object-fit: contain;
  transition: height var(--dur) var(--ease);
}
.site-nav.scrolled .nav-logo-img { height: calc(var(--logo-h, 44px) * 0.82); }

/* ── Layout ─────────────────────────────────────────────────── */
.container {
  max-width: var(--container-max, 1180px);
  margin: 0 auto;
  padding: 0 2rem;
}

/* ── Section Header ─────────────────────────────────────────── */
.section-header {
  text-align: center;
  margin-bottom: 3.5rem;
}
.section-header .eyebrow {
  display: inline-block;
  font-family: var(--ff-script);
  font-size: calc(1.35rem * var(--eyebrow-scale, 1));
  /* The accent, or the shade of it that reads on the band (queue 74). */
  color: var(--eyebrow-ink, var(--gold));
  margin-bottom: 0.4rem;
}
.section-header h2 {
  font-size: clamp(calc(2rem * var(--h-scale, 1)), calc(4vw * var(--h-scale, 1)), calc(3rem * var(--h-scale, 1)));
  margin-bottom: 0.8rem;
}
.section-header p {
  color: var(--text-light);
  max-width: 580px;
  margin: 0 auto;
  font-size: 1.05rem;
}
.divider {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  max-width: 160px;
  margin: 1.2rem auto 0;
}
.divider::before, .divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--gold-light);
}
.divider .gem { color: var(--gold); font-size: 0.75rem; }

/* ── Buttons ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.85rem 2rem;
  border-radius: var(--btn-radius, 50px);
  font-size: 0.93rem;
  font-weight: 700;
  letter-spacing: var(--btn-tracking, 0.4px);
  text-transform: var(--btn-transform, none);
  cursor: pointer;
  border: 2px solid transparent;
  transition: all var(--dur) var(--ease);
  text-align: center;
  white-space: nowrap;
}
.btn-gold {
  background: var(--gold);
  /* Derived in includes/theme.php from whatever --gold actually is, because
     white on the default gold is 2.66:1 -- on the buy button of every shop.
     The fallback is the old value, for the seconds before the theme tag
     loads and for anything rendering without it. */
  color: var(--on-gold, #fff);
  border-color: var(--gold);
}
.btn-gold:hover {
  background: var(--gold-deep);
  border-color: var(--gold-deep);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(201,150,58,0.35);
}
.btn-outline-light {
  background: transparent;
  color: rgba(255,255,255,0.92);
  border-color: rgba(255,255,255,0.55);
}
.btn-outline-light:hover {
  background: rgba(255,255,255,0.12);
  border-color: #fff;
  transform: translateY(-2px);
}
/* In the hero -- its only home -- it takes the hero's own ink: white on the
   dark banner and on a photograph, exactly as above, and dark on the Light
   banner, where white was about 1:1 and the button could not be seen
   (2026-09-25). */
.hero .btn-outline-light {
  color: color-mix(in srgb, var(--hero-ink, #fff) 92%, transparent);
  border-color: color-mix(in srgb, var(--hero-ink, #fff) 55%, transparent);
}
.hero .btn-outline-light:hover {
  background: color-mix(in srgb, var(--hero-ink, #fff) 12%, transparent);
  border-color: var(--hero-ink, #fff);
}
.btn-dark {
  background: var(--dark);
  color: var(--btn-dark-ink, var(--gold-light));
  border-color: var(--dark);
}
.btn-dark:hover {
  background: var(--medium);
  border-color: var(--medium);
  transform: translateY(-2px);
}
.btn-outline-gold {
  background: transparent;
  color: var(--gold-ink);
  border-color: var(--gold-ink);
}
.btn-outline-gold:hover {
  background: var(--gold);
  color: var(--on-gold, #fff);
  transform: translateY(-2px);
}

/* ── Scroll Reveal ───────────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(36px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.reveal.visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.visible { opacity: 1; transform: none; transition: none; }
}
.reveal-d1 { transition-delay: 0.1s; }
.reveal-d2 { transition-delay: 0.2s; }
.reveal-d3 { transition-delay: 0.3s; }
.reveal-d4 { transition-delay: 0.4s; }

/* ── Navigation ──────────────────────────────────────────────── */
.site-nav {
  position: var(--nav-position, fixed);
  inset: var(--nav-inset, 0 0 auto);
  z-index: 900;
  padding: 1.3rem 0;
  background: var(--nav-bg-top, transparent);
  transition: background var(--dur-slow) var(--ease),
              box-shadow  var(--dur-slow) var(--ease),
              padding     var(--dur-slow) var(--ease),
              top         var(--dur-slow) var(--ease);
}
/* ── Short pages ──
   With most homepage sections switched off the page can be shorter than the
   window, and the footer sat wherever the content stopped with dead ground
   below it. Nothing is broken by that, but it reads as a page that failed to
   load rather than a page with little on it. */
body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > .site-footer { margin-top: auto; }

/* ── No hero to float over ──
   The nav is fixed so it can sit transparently on the hero image. With the
   hero switched off there is nothing to float over and nothing holding the
   page down, so the first section rendered underneath it.

   Sticky pins on scroll exactly as fixed does, and it takes up room in the
   flow -- which is the part that matters here. A padding offset would have to
   guess a height that is 68px at desktop, 96px on a phone and 130px at tablet
   where the links wrap. */
body.no-hero .site-nav {
  position: sticky;
  inset: auto;
  top: 0;
}

.site-nav.scrolled {
  background: var(--nav-bg, rgba(253,248,242,0.96));
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 2px 24px var(--shadow);
  border-bottom: 1px solid rgba(0,0,0,0.07);
  padding: 0.7rem 0;
}

/* Fixed navigation must not sit on top of the section somebody just asked to
   see. main.js replaces --nav-h with the measured height after load; the
   generous fallback is what protects the very first hash jump before that
   script has run. */
:where(#home, #collections, #custom-orders, #about, #newsletter, #contact) {
  /* --closed-bar-h: the owner's "closed to the public" bar, which sits above
     the header on a closed shop (public_nav.php); 0 for everyone else. */
  scroll-margin-top: calc(var(--nav-h, 8rem) + var(--closed-bar-h, 0px) + 1rem);
}
.nav-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-direction: var(--nav-direction, row);
  row-gap: 0.55rem;
  column-gap: 2rem;
}
.nav-logo { display: flex; flex-direction: column; line-height: 1.1; }
.nav-logo .logo-name {
  font-family: var(--ff-head);
  font-size: 1.45rem;
  font-weight: 700;
  font-style: var(--brand-style, italic);
  color: var(--nav-ink-top, #fff);
  transition: color var(--dur);
}
.site-nav.scrolled .nav-logo .logo-name { color: var(--nav-ink, var(--dark)); }
.nav-logo .logo-tag {
  font-family: var(--ff-script);
  font-size: calc(0.78rem * var(--eyebrow-scale, 1));
  color: var(--nav-tag-top, var(--gold-light));
  transition: color var(--dur);
}
.site-nav.scrolled .nav-logo .logo-tag { color: var(--nav-tag, var(--gold)); }

.nav-links {
  display: flex;
  gap: 2rem;
  align-items: center;
}
.nav-links a {
  font-size: var(--nav-size, 0.88rem);
  font-weight: var(--nav-weight, 700);
  letter-spacing: var(--nav-tracking, 0.5px);
  text-transform: var(--nav-transform, none);
  color: var(--nav-link-top, rgba(232, 201, 122, 0.82));
  position: relative;
  transition: color var(--dur);
}
.site-nav.scrolled .nav-links a { color: var(--nav-link, var(--text)); }
.nav-links a::after {
  content: '';
  position: absolute;
  bottom: -3px; left: 0; right: 0;
  height: 2px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav-links a:hover::after { transform: scaleX(1); }
/* Touch. The hamburger takes over below 768px, so on a tablet in portrait --
   a touch device -- these are the real navigation and they were 23px tall.
   The underline animation is drawn on ::after at a fixed offset, so growing
   the box would drag it away from the text; the extra height goes on as
   padding with the line pinned back to where the text ends. */
@media (pointer: coarse) {
  .nav-links a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .nav-links a::after { bottom: 8px; }
}
.nav-links a:hover { color: var(--gold-light); }
.site-nav.scrolled .nav-links a:hover { color: var(--gold); }

.nav-toggle {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.4rem;
  color: var(--nav-ink-top, #fff);
  transition: color var(--dur);
  line-height: 0;
}
.site-nav.scrolled .nav-toggle { color: var(--nav-ink, var(--dark)); }

/* ── Hero ────────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: var(--hero-min-h, 100vh);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--hero-bg, linear-gradient(155deg, #180d08 0%, #2d1810 35%, #3e2519 65%, #271509 100%));
  background-size: cover;
  background-position: center top;
}
/* A photograph or video is laid on a dark base, so its transparent pixels
   show dark rather than the page -- and only a photograph or video. The base
   used to be on every hero, after the shorthand above, where it replaced a
   welcome banner whose colour is a plain one: the Light banner, which is
   Boutique's, Minimal's and Artist's own, drew its dark words on #180d08 at
   about 1.1:1, while the Themes page showed it light (2026-09-25). */
.hero.hero--has-image, .hero.hero--has-video { background-color: #180d08; }
.hero-orbs {
  display: var(--hero-orbs, block);
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.hero-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  opacity: 0.18;
  animation: orb-drift 12s ease-in-out infinite alternate;
}
.hero-orb:nth-child(1) {
  width: 500px; height: 500px;
  background: var(--gold);
  top: -100px; left: -100px;
  animation-duration: 14s;
}
.hero-orb:nth-child(2) {
  width: 400px; height: 400px;
  background: var(--rose);
  bottom: -80px; right: -60px;
  animation-duration: 10s;
  animation-delay: -4s;
}
.hero-orb:nth-child(3) {
  width: 300px; height: 300px;
  background: var(--gold-light);
  top: 40%; left: 55%;
  animation-duration: 16s;
  animation-delay: -7s;
}
@keyframes orb-drift {
  from { transform: translate(0, 0) scale(1); }
  to   { transform: translate(40px, 30px) scale(1.1); }
}

/* Sparkles */
.sparkles { display: var(--hero-orbs, block); position: absolute; inset: 0; pointer-events: none; }
.sparkle {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, var(--gold-light), transparent 70%);
  opacity: 0;
  animation: sparkle-anim linear infinite;
}
@keyframes sparkle-anim {
  0%   { opacity: 0;   transform: translateY(0)    scale(0);   }
  15%  { opacity: 0.9; transform: translateY(-15px) scale(1);   }
  85%  { opacity: 0.3; transform: translateY(-70px) scale(0.6); }
  100% { opacity: 0;   transform: translateY(-90px) scale(0);   }
}

.hero-content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 820px;
  padding: 2rem;
  /* Centred in the room above the scroll cue (below). */
  margin-block: auto;
}
.hero-eyebrow {
  font-family: var(--ff-script);
  font-size: calc(1.5rem * var(--eyebrow-scale, 1));
  color: var(--hero-accent, var(--gold-light));
  margin-bottom: 1rem;
  opacity: 0;
  animation: fade-up 0.9s var(--ease) 0.3s forwards;
}
.hero h1 {
  font-size: clamp(calc(2.8rem * var(--h-scale, 1)), calc(8vw * var(--h-scale, 1)), calc(5.5rem * var(--h-scale, 1)));
  color: var(--hero-ink, #fff);
  font-style: var(--brand-style, italic);
  line-height: 1.1;
  margin-bottom: 1.5rem;
  opacity: 0;
  animation: fade-up 0.9s var(--ease) 0.55s forwards;
  text-shadow: var(--hero-shadow, 0 4px 40px rgba(0,0,0,0.5));
}
.hero h1 .gold { color: var(--hero-accent, var(--gold-light)); }
.hero-subtext {
  font-size: 1.1rem;
  color: var(--hero-sub-ink, rgba(255,255,255,0.78));
  max-width: 560px;
  margin: 0 auto 2.5rem;
  line-height: 1.85;
  opacity: 0;
  animation: fade-up 0.9s var(--ease) 0.8s forwards;
}
.hero-ctas {
  display: flex;
  gap: 1rem;
  justify-content: center;
  flex-wrap: wrap;
  opacity: 0;
  animation: fade-up 0.9s var(--ease) 1.05s forwards;
}
/* The scroll cue is in the hero's flow, under the buttons, not laid over
   the bottom of it (pass 3, 6.9). Pinned 2.2rem from the bottom of a
   centred hero, it sat on "Browse the marketplace" whenever the words were
   tall for the hero -- a phone (60px over at 320x568), a phone on its side,
   or a theme's shorter hero (47px over at 1280x720 on "Dark, shorter").
   Now the content is centred in the room above it, the cue always has at
   least the content's own padding and its margin between it and the
   buttons, and a hero with more to say simply grows. */
.hero-scroll {
  position: relative;
  z-index: 2;
  flex: none;
  margin: 1.25rem 0 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  /* The hero's own ink, as the outline button above does: white on the dark
     banner and on a photograph, exactly as before, and dark on the Light
     banner, where fixed white could not be seen (pass 3, phase 12). */
  color: color-mix(in srgb, var(--hero-ink, #fff) 40%, transparent);
  font-size: 0.68rem;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  animation: scroll-bounce 2.5s ease-in-out infinite;
}
/* A screen this short -- a phone on its side -- has room for the words and
   the buttons or for the cue, not both. The buttons are the point: the cue
   goes, and the hero tightens and starts at its top rather than its middle
   (a full-height hero begins under the header, so centred, its buttons fell
   off the first screen), so they are on it. */
@media (max-height: 500px) {
  .hero-scroll { display: none; }
  .hero-content { padding-block: 1rem; margin-block: 0 auto; }
  .hero-eyebrow { margin-bottom: .35rem; }
  .hero h1 { font-size: calc(clamp(1.8rem, 9vh, 2.6rem) * var(--h-scale, 1)); margin-bottom: .6rem; }
  .hero-subtext { margin-bottom: 1.1rem; line-height: 1.55; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-scroll { animation: none; }
  /* The welcome words arrive in place, not rising in one after another
     (pass 4, phase 23 QA matrix: they still animated under this setting). */
  .hero-eyebrow, .hero h1, .hero-subtext, .hero-ctas { animation: none; opacity: 1; transform: none; }
  /* And the light itself holds still: the drifting orbs and the twinkling
     sparkles stay where they are (production convergence, phase 22: still
     moving under this setting on the live shops and on pass 4's canary). */
  .hero-orb, .sparkle { animation: none; }
}
.hero-scroll::after {
  content: '';
  width: 1px;
  height: 36px;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--hero-ink, #fff) 40%, transparent), transparent);
}
@keyframes scroll-bounce {
  0%, 100% { transform: translateY(0); }
  50%       { transform: translateY(7px); }
}
@keyframes fade-up {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── Product Card ─────────────────────────────────────────────── */
.product-card {
  background: var(--card-bg, var(--warm-white));
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--card-shadow, 0 4px 22px var(--shadow-sm));
  border: var(--card-border, 0px) solid var(--border);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
  cursor: pointer;
  position: relative;
}
.product-card:hover {
  transform: translateY(var(--card-lift, -7px));
  box-shadow: var(--card-shadow-hover, 0 14px 44px var(--shadow));
}
.product-card-img {
  position: relative;
  aspect-ratio: var(--card-img-ratio, 4/3);
  overflow: hidden;
  border-radius: var(--card-img-radius, 0);
  background: var(--cream);
}
.product-card-img img {
  width: 100%; height: 100%;
  object-fit: var(--card-img-fit, cover);
  transition: transform 0.55s var(--ease);
}
.product-card:hover .product-card-img img { transform: scale(var(--card-img-zoom, 1.08)); }
.product-placeholder {
  width: 100%; height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--gold-pale) 0%, var(--cream) 100%);
  font-size: 3rem;
  color: var(--gold);
}
.product-badge {
  position: absolute;
  top: 0.9rem; left: 0.9rem;
  background: var(--gold);
  color: var(--on-gold, #fff);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  padding: 0.25rem 0.75rem;
  border-radius: 50px;
}
.product-card-body { padding: var(--card-pad, 1.4rem); }
.product-cat {
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 0.4rem;
}
.product-card-body h3 {
  font-size: 1.15rem;
  margin-bottom: 0.5rem;
}
.product-desc-short {
  font-size: 0.88rem;
  color: var(--text-light);
  line-height: 1.6;
  margin-bottom: 1.1rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.product-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.product-price {
  font-family: var(--ff-head);
  font-size: 1.3rem;
  color: var(--gold-ink);
  font-weight: 600;
  line-height: 1.1;
}
.product-price .bulk-tag {
  display: block;
  font-family: var(--ff-body);
  font-size: 0.68rem;
  color: var(--text-light);
  font-weight: 500;
  margin-top: 0.15rem;
}
/* The product title and "View Details" are links now, not text and a button,
   so a card can be shared, bookmarked and crawled. They should look exactly as
   they did before. */
.product-card-body h3 .product-link {
  color: inherit;
  text-decoration: none;
}
.product-card-body h3 .product-link:hover { color: var(--gold); }

.btn-view-detail {
  display: inline-block;
  text-decoration: none;
  background: none;
  border: 2px solid var(--gold-ink);
  color: var(--gold-ink);
  padding: 0.45rem 1.1rem;
  border-radius: var(--btn-radius, 50px);
  text-transform: var(--btn-transform, none);
  letter-spacing: var(--btn-tracking, 0);
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  transition: all var(--dur) var(--ease);
  white-space: nowrap;
}
.btn-view-detail:hover {
  background: var(--gold);
  color: var(--on-gold, #fff);
}
/* The primary action on every card in the grid, and it was 37px tall. Grown
   only on touch: the desktop grid is denser on purpose. */
@media (pointer: coarse) {
  .btn-view-detail {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
}

/* ── Featured Section ─────────────────────────────────────────── */
/* Section bands ------------------------------------------------
   Assigned in PHP from a section's position among the ones actually
   visible, not from its own identity, so switching a section off (or
   simply having no featured products) cannot leave two identical bands
   touching. Hero, custom orders and contact keep their own treatment. */
.band-tint  { background: var(--band-tint, var(--cream)); }
.band-light { background: var(--band-light, var(--warm-white)); }

.section-featured {
  padding: calc(6rem * var(--space, 1)) 0;
}
.featured-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 340px));
  justify-content: center;
  gap: 2rem;
}

/* ── Collections Section ──────────────────────────────────────── */
.section-collections {
  padding: 1rem 0;
}
.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 2rem;
}
.products-grid .product-card {
  display: none;
}
.products-grid .product-card.visible {
  display: block;
  animation: card-appear 0.4s var(--ease) both;
}
@keyframes card-appear {
  from { opacity: 0; transform: scale(0.94) translateY(12px); }
  to   { opacity: 1; transform: scale(1)    translateY(0);    }
}
/* Under reduced motion a product card is simply there. After the rule above,
   so it wins at the same specificity (production convergence, phase 22). */
@media (prefers-reduced-motion: reduce) {
  .products-grid .product-card.visible { animation: none; }
}
.no-products-msg {
  grid-column: 1/-1;
  text-align: center;
  padding: 4rem 2rem;
  color: var(--text-light);
  font-size: 1.05rem;
}

/* ── Custom Orders Section ────────────────────────────────────── */
.section-custom-orders {
  padding: calc(6rem * var(--space, 1)) 0;
  background: var(--co-bg, linear-gradient(155deg, #1c0f09 0%, #2e1a0f 40%, #3e2216 100%));
  position: relative;
  overflow: hidden;
}
.section-custom-orders::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: radial-gradient(ellipse at 10% 80%, rgba(201,150,58,0.12) 0%, transparent 55%),
                    radial-gradient(ellipse at 90% 20%, rgba(193,123,123,0.1) 0%, transparent 50%);
}
.co-inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4.5rem;
  align-items: center;
}
.co-text .eyebrow {
  font-family: var(--ff-script);
  font-size: calc(1.35rem * var(--eyebrow-scale, 1));
  color: var(--co-eyebrow, var(--gold-light));
  display: block;
  margin-bottom: 0.4rem;
}
.co-text h2 {
  font-size: clamp(1.8rem, 3.5vw, 2.6rem);
  color: #fff;
  margin-bottom: 1.2rem;
}
.co-text p {
  color: rgba(255,255,255,0.72);
  margin-bottom: 1.8rem;
  font-size: 1.05rem;
  line-height: 1.85;
}
.event-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2rem;
}
.event-tag {
  background: rgba(201,150,58,0.18);
  border: 1px solid rgba(201,150,58,0.38);
  color: var(--gold-light);
  padding: 0.3rem 0.85rem;
  border-radius: 50px;
  font-size: 0.8rem;
  font-weight: 600;
}
/* Quick form inside custom orders */
.quick-form {
  background: rgba(255,255,255,0.07);
  border: 1px solid rgba(255,255,255,0.13);
  border-radius: var(--radius);
  padding: 2.2rem;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.quick-form h3 {
  color: #fff;
  font-size: 1.25rem;
  margin-bottom: 1.4rem;
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-group { margin-bottom: 1.1rem; }
.form-group label {
  display: block;
  font-size: 0.82rem;
  font-weight: 700;
  color: rgba(255,255,255,0.7);
  margin-bottom: 0.35rem;
  letter-spacing: 0.3px;
}
.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 0.7rem 1rem;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,0.07);
  color: #fff;
  font-family: var(--ff-body);
  font-size: 0.9rem;
  transition: border-color var(--dur);
  -webkit-appearance: none;
}
/* Follows the field's own ink rather than assuming one.
   The block above was written for the custom-orders panel, which is dark, so
   the placeholder was hard white -- and `.form-group` is a generic class that
   the gift-card and account forms also use on a LIGHT panel, where a white
   placeholder is invisible. currentColor is whatever that field's text is,
   so one rule is right on both, in every family. */
.form-group input::placeholder,
.form-group textarea::placeholder { color: currentColor; opacity: 0.55; }
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--gold-light);
  background: rgba(255,255,255,0.1);
}
.form-group select option { color: #2A1F1A; background: #fff; }

/* ── About Section ────────────────────────────────────────────── */
.section-about {
  padding: calc(6.5rem * var(--space, 1)) 0;
}
.about-inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5rem;
  align-items: center;
}
.about-visual { position: relative; }
.about-img-wrap {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 3/4;
  box-shadow: 0 24px 64px var(--shadow-lg);
  background: linear-gradient(135deg, var(--gold-pale), var(--cream));
  display: flex;
  align-items: center;
  justify-content: center;
}
.about-img-wrap img { width: 100%; height: 100%; object-fit: cover; }
.about-img-placeholder {
  font-size: 5rem;
  color: var(--gold);
  opacity: 0.4;
}
.about-accent-circle {
  position: absolute;
  top: -1.8rem; right: -1.8rem;
  width: 110px; height: 110px;
  border-radius: 50%;
  background: var(--gold-pale);
  border: 3px solid var(--gold-light);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: var(--ff-script);
  font-size: 0.92rem;
  color: var(--gold-deep);
  line-height: 1.3;
  padding: 0.5rem;
  box-shadow: 0 8px 28px var(--shadow);
}
/* A longer flash (over 26 letters, includes/sections/about.php): a larger
   circle, smaller words and more room at the edge, so a line near the top or
   the bottom stays inside the curve. It grows inward from the same corner. */
.about-accent-circle--long {
  width: 142px; height: 142px;
  font-size: 0.8rem;
  line-height: 1.22;
  padding: 1.1rem;
  overflow-wrap: anywhere;
}
.about-text .eyebrow {
  font-family: var(--ff-script);
  color: var(--eyebrow-ink, var(--gold));
  font-size: calc(1.3rem * var(--eyebrow-scale, 1));
  display: block;
  margin-bottom: 0.4rem;
}
.about-text h2 { font-size: clamp(1.8rem, 3vw, 2.5rem); margin-bottom: 1.4rem; }
.about-text p {
  color: var(--text-light);
  margin-bottom: 1.4rem;
  font-size: 1.04rem;
  line-height: 1.9;
}
.about-pillars {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 1.8rem;
}
.pillar {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
}
.pillar-icon { font-size: 1.3rem; flex-shrink: 0; margin-top: 0.1rem; }
.pillar h4 { font-size: 0.92rem; margin-bottom: 0.15rem; }
.pillar p  { font-size: 0.8rem; color: var(--text-light); margin: 0; }

/* ── Wholesale Banner ─────────────────────────────────────────── */
.section-wholesale {
  padding: calc(4.5rem * var(--space, 1)) 0;
}
.wholesale-card {
  background: var(--wholesale-bg, linear-gradient(135deg, var(--gold-pale) 0%, #fff8ed 100%));
  border: 1px solid var(--gold-light);
  border-radius: var(--radius);
  padding: 2.8rem 3rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 2rem;
}
.wholesale-icon { font-size: 1.6rem; vertical-align: middle; margin-right: 0.45rem; }
.wholesale-text h3 { font-size: 1.55rem; margin-bottom: 0.7rem; }
.wholesale-text p  { color: var(--text-light); margin-bottom: 1.4rem; font-size: 1rem; }

/* ── Contact Section ──────────────────────────────────────────── */
.section-contact {
  padding: calc(5.5rem * var(--space, 1)) 0;
  background: linear-gradient(160deg, var(--gold-pale) 0%, var(--cream) 100%);
}
.contact-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1.8rem;
  max-width: 900px;
  margin: 0 auto;
}
.contact-card {
  background: var(--warm-white);
  border-radius: var(--radius);
  padding: 2.2rem 1.5rem;
  text-align: center;
  box-shadow: 0 4px 20px var(--shadow-sm);
  transition: transform var(--dur) var(--ease);
}
.contact-card:hover { transform: translateY(-4px); }
.contact-card-icon  { font-size: 2.2rem; margin-bottom: 0.9rem; }
.contact-card h4    { font-size: 1.05rem; margin-bottom: 0.4rem; }
.contact-card p, .contact-card a {
  color: var(--text-light);
  font-size: 0.93rem;
  line-height: 1.6;
  transition: color var(--dur);
}
.contact-card a:hover { color: var(--gold); }

.social-row {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 0.9rem;
}
.social-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--cream);
  border: 2px solid var(--gold-light);
  color: var(--gold);
  font-size: 1rem;
  transition: all var(--dur) var(--ease);
}
.social-btn:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-gold, #fff);
  transform: translateY(-2px);
}
.social-btn:hover svg { fill: var(--on-gold, #fff); }

/* ── Footer ───────────────────────────────────────────────────── */
.site-footer {
  background: var(--footer-bg, var(--dark));
  color: var(--footer-ink, rgba(255,255,255,0.65));
  padding: 3.5rem 0 1.5rem;
  text-align: center;
}
.footer-logo {
  font-family: var(--ff-head);
  font-size: 1.65rem;
  color: var(--footer-brand, #fff);
  font-style: var(--brand-style, italic);
  margin-bottom: 0.2rem;
}
.footer-tagline {
  font-family: var(--ff-script);
  color: var(--footer-tag, var(--gold-light));
  font-size: calc(1rem * var(--eyebrow-scale, 1));
  display: block;
  margin-bottom: 1.6rem;
}
.footer-nav {
  display: flex;
  justify-content: center;
  gap: 2rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.footer-nav a {
  font-size: 0.85rem;
  color: var(--footer-link, rgba(255,255,255,0.55));
  transition: color var(--dur);
}
.footer-nav a:hover { color: var(--gold-light); }
/* Footer links were 21-22px tall. Keyed to the pointer rather than to a
   width: a tablet in portrait is 768px wide and is still a finger. */
@media (pointer: coarse) {
  .footer-nav a,
  .footer-page-nav a,
  .footer-policy-nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* The product page's breadcrumbs and a page banner's back link were 22px
     tall under a finger; the same 44px (pass 3, phase 15). */
  .pdp-crumbs a,
  .page-banner .back-link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
.footer-page-nav,
.footer-policy-nav {
  display: flex;
  justify-content: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
}
/* A page the owner wrote is content; a policy is small print. Same row shape,
   one step apart in weight, so the two groups read as two groups. */
.footer-page-nav a {
  font-size: 0.85rem;
  color: var(--footer-link, rgba(255,255,255,0.62));
  transition: color var(--dur);
}
.footer-page-nav a:hover { color: var(--gold-light); }
.footer-policy-nav a {
  font-size: 0.78rem;
  color: var(--footer-ink-dim, rgba(255,255,255,0.55));
  transition: color var(--dur);
  white-space: nowrap;
}
.footer-policy-nav a:hover { color: var(--gold-light); }
.footer-bottom {
  border-top: 1px solid var(--footer-rule, rgba(255,255,255,0.08));
  padding-top: 1.5rem;
  font-size: 0.8rem;
  /* Small print, but it still has to be readable: 0.3 alpha came to 2.3:1 on
     the classic footer and 2.5:1 on a dark one. */
  color: var(--footer-ink-dim, rgba(255,255,255,0.55));
}

/* ── Product quick view ───────────────────────────────────────
   docs/QUICK-VIEW.md is the contract, shared with the Marketplace's quick
   look. Two columns from 761px -- the picture about half the panel, drawn
   whole (contain) so a portrait photograph is never cut to a strip -- one
   centred column from 641px, and a bottom sheet below that (sheet.js). One
   scroll surface at every size: the words column on a desktop, the panel
   below it. The pale price panel is gone: the price sits on one line with
   its status. */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30,18,12,0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  opacity: 0;
  pointer-events: none;
  /* A closed overlay is transparent and click-through, but its buttons and
     inputs were still in the tab order -- a keyboard user tabbing down the
     page fell into an invisible dialog. That is fixed in main.js with `inert`
     rather than here with visibility:hidden, because hiding it in CSS has to
     wait for the fade to finish and transitions do not run in a background
     tab, which is exactly when the element would stay focusable. */
  transition: opacity var(--dur) var(--ease);
}
.modal-overlay.open {
  opacity: 1;
  pointer-events: all;
}
.modal {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  width: 100%;
  max-width: 920px;
  /* One size for every product, so moving from one to the next does not
     make the panel jump. */
  height: min(86vh, 620px);
  overflow: hidden;
  background: var(--warm-white);
  border-radius: var(--radius);
  box-shadow: 0 24px 70px rgba(30,18,12,.35);
  transform: translateY(12px) scale(.985);
  transition: transform .3s var(--ease);
}
.modal-overlay.open .modal {
  transform: none;
}
.modal-img-pane {
  position: relative;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--cream);
}
.modal-img-pane img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.modal-img-pane img[hidden], .modal-img-placeholder[hidden] { display: none; }
.modal-img-placeholder { display: flex; color: var(--text-light); opacity: .45; }

/* ── The pictures, when there is more than one ─────────────── */
.modal-gallery-strip {
  position: absolute;
  bottom: 0; left: 0; right: 0;
  display: flex;
  gap: 6px;
  margin: 0;
  padding: 8px 10px;
  list-style: none;
  background: linear-gradient(to top, rgba(0,0,0,.45) 0%, transparent 100%);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.modal-gallery-strip[hidden] { display: none; }
.modal-gallery-strip::-webkit-scrollbar { display: none; }
.modal-gallery-strip li { flex: 0 0 auto; }
.gallery-thumb {
  display: block;
  width: 52px;
  height: 52px;
  padding: 0;
  border-radius: 6px;
  border: 2px solid rgba(255,255,255,.55);
  background-color: var(--cream);
  background-size: cover;
  background-position: center;
  cursor: pointer;
  scroll-snap-align: start;
  transition: border-color .15s, opacity .15s;
  opacity: .75;
}
.gallery-thumb:hover  { opacity: 1; border-color: rgba(255,255,255,.9); }
.gallery-thumb.active { opacity: 1; border-color: #fff; box-shadow: 0 0 0 2px rgba(0,0,0,.35); }
.gallery-thumb:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.modal-close {
  position: absolute;
  top: 0.9rem; right: 0.9rem;
  background: rgba(255,255,255,0.92);
  border: none;
  border-radius: 50%;
  width: 36px; height: 36px;
  font-size: 1.15rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Fixed ink on purpose: the background above is a near-white circle drawn
     over a photograph, so this one does NOT follow the family the way other
     headings do. A themed ink here is near-white on near-white in Dark
     Modern. The design guide names this button as the allowed exception. */
  color: #2A1F1A;
  box-shadow: 0 1px 6px rgba(0,0,0,.18);
  transition: background var(--dur), transform var(--dur);
  z-index: 4;
  line-height: 1;
}
.modal-close:hover { background: #fff; }
.modal-close:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* 44px on any touch device, not only on a phone: a tablet is also a finger. */
@media (pointer: coarse) {
  .modal-close { width: 44px; height: 44px; }
}
.modal-body {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 2.1rem 2rem 1.6rem;
  display: flex;
  flex-direction: column;
}
.modal-cat {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text-light);
  margin: 0 3rem 0.5rem 0;
}
.modal-cat[hidden] { display: none; }
/* overflow-wrap: anywhere because product names are entered by shop owners,
   not by typographers. A single unbroken run -- a long SKU, a hashtag, a
   run-together name -- was pushing past the right edge of the modal and
   being clipped by it. Breaking mid-word is ugly; losing the text is worse. */
.modal-name {
  font-size: 1.55rem;
  line-height: 1.2;
  margin: 0 3rem 0.6rem 0;
  overflow-wrap: anywhere;
  hyphens: auto;
}
/* Price and status, one line, no panel. */
.qv-price-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .4rem .8rem;
  margin: 0 0 1rem;
}
.modal-msrp {
  font-family: var(--ff-head);
  font-size: 1.45rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--heading-ink, var(--dark));
}
.qv-was {
  margin-left: .5rem;
  font-family: var(--ff-body);
  font-size: .95rem;
  font-weight: 400;
  color: var(--text-light);
}
/* A status is a fact about what can be bought, in the ink of the text and not
   a colour a family could make invisible. */
.qv-status {
  display: inline-flex;
  align-items: center;
  padding: .18rem .6rem;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  color: var(--text);
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.qv-status[hidden] { display: none; }
.qv-cond { font-size: .82rem; font-weight: 600; color: var(--text-light); }
.modal-bulk {
  margin: -.5rem 0 1rem;
  font-size: 0.84rem;
  color: var(--text-light);
}
.modal-bulk[hidden] { display: none; }
/* The first lines of the description, then More. */
.qv-desc { margin: 0 0 1.2rem; }
.qv-desc[hidden] { display: none; }
.modal-description {
  color: var(--text-light);
  font-size: 0.93rem;
  line-height: 1.7;
  overflow-wrap: anywhere;
}
.modal-description p { margin: 0 0 .65em; }
.modal-description p:last-child { margin-bottom: 0; }
.qv-desc:not(.is-open) .modal-description { max-height: 6.8em; overflow: hidden; }
.qv-desc.has-more:not(.is-open) .modal-description {
  -webkit-mask-image: linear-gradient(to bottom, #000 65%, transparent);
  mask-image: linear-gradient(to bottom, #000 65%, transparent);
}
.qv-more {
  margin-top: .2rem;
  padding: .3rem 0;
  background: none;
  border: 0;
  font: inherit;
  font-size: .86rem;
  font-weight: 700;
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.qv-more[hidden] { display: none; }
.qv-more:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* The choices and the main action: one block, the button right under what
   it depends on. */
.modal-actions { display: flex; flex-direction: column; gap: 0.7rem; }
.qv-choices { display: grid; gap: 1rem; }
.qv-choices[hidden] { display: none; }
.qv-group-label {
  margin: 0 0 .45rem;
  font-size: .76rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-light);
}
.qv-picked {
  margin-left: .5rem;
  font-size: .86rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
}
.qv-group.is-missing .qv-group-label { color: var(--text); }
.qv-group.is-missing .qv-group-choices { border-radius: 8px; box-shadow: 0 0 0 2px var(--rose, #b3261e); }
.qv-group-choices { display: flex; flex-wrap: wrap; gap: .45rem; }
.qv-choice {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  min-height: 40px;
  padding: .4rem .9rem;
  border: 1.5px solid var(--border);
  border-radius: var(--btn-radius-sm, 6px);
  background: var(--warm-white);
  color: var(--text);
  font: inherit;
  font-size: .88rem;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
.qv-choice:hover:not(:disabled) { border-color: var(--text-light); }
.qv-choice[aria-pressed="true"] {
  border-color: var(--heading-ink, var(--dark));
  box-shadow: inset 0 0 0 1px var(--heading-ink, var(--dark));
  background: color-mix(in srgb, var(--heading-ink, var(--dark)) 10%, var(--warm-white));
  font-weight: 700;
}
.qv-choice:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.qv-choice.is-out,
.qv-choice:disabled {
  color: var(--text-light);
  text-decoration: line-through;
  opacity: .55;
  cursor: not-allowed;
}
.qv-swatch {
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid rgba(0,0,0,.2);
}
@media (pointer: coarse) {
  .qv-choice { min-height: 44px; }
  .qv-more { min-height: 44px; }
}
.qv-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.qv-need { margin: 0; font-size: .86rem; font-weight: 600; color: var(--text); }
.qv-need:not(.is-on) { display: none; }
.qv-need.is-on::before { content: '! '; color: var(--rose, #b3261e); font-weight: 800; }
/* Inside the quick view, hidden means hidden. Several rules here set a
   display, and each one of them beat the hidden attribute: a sold-out
   product showed "Add to cart" (2026-09-25). */
.modal-overlay [hidden] { display: none !important; }
/* The one main action. */
.qv-cta { display: flex; flex-direction: column; gap: .6rem; margin-top: 1rem; }
.modal-add-cart.btn-gold,
.qv-alt.btn-gold {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  font-size: 1rem;
}
.modal-add-cart[hidden], .qv-alt[hidden] { display: none; }
/* Sold out's next step, or "View full details" when there is no cart: a real
   button, not the gold one, because it is not buying. */
.qv-alt:not(.btn-gold) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  padding: .7rem 1.2rem;
  border: 1.5px solid var(--border);
  border-radius: var(--btn-radius-sm, 6px);
  color: var(--text);
  font-weight: 700;
  text-decoration: none;
  text-align: center;
}
.qv-alt:not(.btn-gold):hover { border-color: var(--text-light); }
.qv-alt:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.btn-paypal {
  width: 100%;
  background: #003087;
  color: #fff;
  border: none;
  padding: 0.85rem 1.5rem;
  border-radius: 50px;
  font-size: 0.92rem;
  font-weight: 700;
  cursor: pointer;
  transition: all var(--dur) var(--ease);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  letter-spacing: 0.2px;
}
.btn-paypal:hover {
  background: #002060;
  transform: translateY(-2px);
  box-shadow: 0 6px 22px rgba(0,48,135,0.38);
}
.btn-paypal svg { flex-shrink: 0; }
.btn-custom-link {
  width: 100%;
  background: none;
  border: 2px solid var(--gold-ink);
  color: var(--gold-ink);
  padding: 0.75rem 1.5rem;
  border-radius: 50px;
  font-size: 0.88rem;
  font-weight: 700;
  cursor: pointer;
  transition: all var(--dur) var(--ease);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  text-decoration: none;
}
.btn-custom-link:hover {
  background: var(--gold);
  color: var(--on-gold, #fff);
}
.paypal-not-configured {
  background: var(--cream);
  border-radius: var(--radius-sm);
  padding: 1rem;
  text-align: center;
  font-size: 0.85rem;
  color: var(--text-light);
}
.paypal-not-configured a { color: var(--gold-ink); text-decoration: underline; }

/* ── Toast ────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 2rem;
  left: 50%;
  transform: translateX(-50%) translateY(120px);
  background: var(--dark);
  color: #fff;
  padding: 0.9rem 2rem;
  border-radius: 50px;
  font-size: 0.9rem;
  font-weight: 600;
  z-index: 9999;
  transition: transform 0.4s var(--ease);
  border-left: 4px solid var(--gold);
  white-space: nowrap;
  box-shadow: 0 8px 30px var(--shadow-lg);
}
.toast.show { transform: translateX(-50%) translateY(0); }

/* ── Responsive ───────────────────────────────────────────────── */
@media (max-width: 960px) {
  .co-inner, .about-inner { grid-template-columns: 1fr; gap: 3rem; }
  .about-visual { max-width: 380px; margin: 0 auto; }
  .wholesale-card { gap: 1.5rem; }
  /* Our Story + Custom & Event Orders — center text when stacked */
  .about-text, .co-text { text-align: center; }
  .about-pillars { justify-items: center; }
  .pillar { justify-content: center; }
  .event-tags { justify-content: center; }
}
@media (max-width: 768px) {
  /* The header's phone layout is under "The header on a phone". */
  .form-row { grid-template-columns: 1fr; }
  .about-pillars { grid-template-columns: 1fr; }
  .wholesale-card { padding: 2rem 1.5rem; }
}
@media (max-width: 480px) {
  .container { padding: 0 1.25rem; }
  /* The About badge overhangs its photo's corner by 1.8rem; on a phone that ran
     10-13px past the screen (Leslie's home page at 320-430px), and Chromium then
     shrank the whole page to fit. Half a rem keeps the overhang inside the
     container's 1.25rem (production convergence, phase 22). */
  .about-accent-circle { right: -0.5rem; }
  .hero-ctas { flex-direction: column; align-items: center; }
  .hero-ctas .btn { width: 100%; justify-content: center; max-width: 300px; }
  .featured-grid, .products-grid { grid-template-columns: 1fr; }
  .modal-body { padding: 1.5rem; }
}

/* ── Collections section — mobile spacing & sizing ──────────── */
@media (max-width: 640px) {
  /* Reduce the section's generous desktop padding */
  .section-collections { padding: 3.25rem 0 3.75rem; }

  /* Tighten the gap between the heading block and the first button row */
  .section-collections .section-header { margin-bottom: 1.75rem; }

  /* Reduced padding on the About section on mobile */
  .section-about { padding: 2.5rem 0; }

  /* Force "All rights reserved." onto its own line */
  .footer-rights { display: block; }

  /* Footer nav — 2-column grid: even rows, no orphaned links */
  .footer-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .85rem 1.5rem;
    max-width: 260px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 1.25rem;
  }

  /* Policy nav — 2-column grid: pairs up cleanly */
  .footer-policy-nav {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .65rem 1rem;
    max-width: 300px;
    margin-left: auto;
    margin-right: auto;
    margin-bottom: 1.25rem;
  }
}

/* ============================================================
   v2 — Cart, Checkout, Sale Badges, Scroll-to-top, Modals
   ============================================================ */

/* ── Cart nav link — underline on word only, not the badge ── */
.nav-cart-link::after { display: none; }
.nav-cart-text { position: relative; }
.nav-cart-text::after {
  content: '';
  position: absolute;
  bottom: -3px; left: 0; right: 0;
  height: 2px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease);
}
.nav-cart-link:hover .nav-cart-text::after { transform: scaleX(1); }

/* ── Admin and account nav links ─────────────────────────── */
.nav-admin-link,
.nav-account-link {
  font-size: .78rem !important;
  font-weight: 600 !important;
  letter-spacing: .4px;
  padding: .3rem .75rem !important;
  border-radius: 20px;
  border: 1.5px solid currentColor;
  opacity: .7;
  transition: opacity .2s, background .2s, color .2s;
  white-space: nowrap;
}
.nav-admin-link::after,
.nav-account-link::after { display: none !important; }
.nav-auth-group { display: flex; align-items: center; gap: 0.5rem; }
.nav-admin-link:hover,
.nav-account-link:hover {
  opacity: 1;
  background: var(--gold);
  border-color: var(--gold);
  color: var(--on-gold, #fff) !important;
}

/* ── Nav cart badge ───────────────────────────────────────── */
.nav-cart-link { position: relative; }
.cart-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--gold);
  color: var(--on-gold, #fff);
  font-size: .68rem;
  font-weight: 700;
  min-width: 18px;
  height: 18px;
  border-radius: 9px;
  padding: 0 5px;
  margin-left: 4px;
  vertical-align: middle;
}

/* ── Sale badge on product cards ─────────────────────────── */
.sale-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  /* White words at .72rem need 4.5:1: #e05555 gave 3.75. The same red,
     a few points darker (queue 74); every badge fill below likewise. */
  background: #DB3939;
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  padding: .2rem .6rem;
  border-radius: 4px;
  letter-spacing: .5px;
  text-transform: uppercase;
  z-index: 2;
}
/* Product badge type colors */
.badge-new       { background: #1E6FF5; }
.badge-best_seller { background: var(--gold); color: var(--on-gold, #fff); }
.badge-limited   { background: #EB1515; }
.badge-seasonal  { background: #178841; }
.badge-exclusive { background: #8655F6; }
/* A running seasonal theme's badge, in the season's own colours. */
.sale-badge.badge-season { background: var(--gold); color: var(--on-gold, #fff); }

/* Out of stock badge */
.out-of-stock-badge {
  position: absolute;
  top: 12px;
  left: 12px;
  background: rgba(50,50,50,0.82);
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  padding: .2rem .6rem;
  border-radius: 4px;
  letter-spacing: .5px;
  text-transform: uppercase;
  z-index: 2;
}
.product-card.out-of-stock .product-card-img img,
.product-card.out-of-stock .product-placeholder { opacity: 0.55; }
.product-card.out-of-stock .product-card-body { opacity: 0.7; }

.price-original {
  text-decoration: line-through;
  color: var(--text-light);
  font-size: .9rem;
}
.price-sale { color: var(--gold-deep); font-weight: 700; }

/* ── Buttons ─────────────────────────────────────────────── */
/* Scoped to :not(.btn) so cart/checkout standalone buttons get display:inline-block
   while the original hero .btn.btn-gold keeps display:inline-flex;align-items:center */
/* Higher specificity than .btn-gold, so this is the rule that actually paints
   Add to Cart on a product page -- and it was still white on gold. */
.btn-gold:not(.btn) {
  display: inline-block;
  background: var(--gold);
  color: var(--on-gold, #fff);
  padding: .7rem 1.6rem;
  border-radius: var(--btn-radius-sm, 6px);
  text-transform: var(--btn-transform, none);
  letter-spacing: var(--btn-tracking, 0);
  font-weight: 700;
  font-family: var(--ff-body);
  border: none;
  cursor: pointer;
  transition: background var(--dur) var(--ease);
  text-decoration: none;
}
.btn-gold:not(.btn):hover { background: var(--gold-deep); }
.btn-gold.btn-full { display: block; width: 100%; text-align: center; }
.btn-outline {
  display: inline-block;
  background: transparent;
  color: var(--gold-ink);
  border: 2px solid var(--gold-ink);
  padding: .6rem 1.4rem;
  border-radius: var(--btn-radius-sm, 6px);
  text-transform: var(--btn-transform, none);
  letter-spacing: var(--btn-tracking, 0);
  font-weight: 700;
  font-family: var(--ff-body);
  cursor: pointer;
  transition: all var(--dur) var(--ease);
}
.btn-outline:hover { background: var(--gold); color: var(--on-gold, #fff); }
.btn-link-gold {
  display: block;
  text-align: center;
  color: var(--gold-ink);
  margin-top: .75rem;
  font-weight: 600;
}
.btn-paypal-checkout {
  display: block;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  margin-top: 1rem;
}
.btn-paypal-checkout img { margin: 0 auto; max-height: 50px; }

/* ── Page title ─────────────────────────────────────────── */
.page-title {
  font-family: var(--ff-head);
  font-size: 2rem;
  color: var(--heading-ink, var(--dark));
  margin: 2.5rem 0 1.5rem;
}

/* ── Inner-page dark banner (gives transparent nav a real backdrop) ── */
.page-banner {
  background: var(--banner-bg, linear-gradient(135deg, var(--dark) 0%, #3a2518 60%, #2a1a0e 100%));
  /* Under a floating header the banner runs up behind it, so it clears the
     overlap first; under a solid one it starts below it (pass 4, phase 7).
     It was a fixed 7.5rem, which doubled under a solid header. */
  padding: calc(var(--nav-overlap, var(--nav-h)) + var(--banner-gap, 2.75rem)) 0 2.5rem;
  text-align: center;
}
.page-banner h1 {
  font-family: var(--ff-head);
  font-size: clamp(calc(1.8rem * var(--h-scale, 1)), calc(4vw * var(--h-scale, 1)), calc(2.6rem * var(--h-scale, 1)));
  color: var(--banner-ink, var(--cream));
  margin: 0 0 0.3rem;
}
.page-banner .eyebrow {
  font-family: var(--ff-script);
  color: var(--banner-eyebrow, var(--gold));
  font-size: calc(1.2rem * var(--eyebrow-scale, 1));
  display: block;
  margin-bottom: 0.5rem;
}
.page-banner p {
  color: var(--banner-sub, rgba(253,248,242,0.75));
  max-width: 540px;
  margin: 0.5rem auto 0;
  font-size: 0.95rem;
}
.page-banner .back-link {
  font-size: 0.82rem;
  color: var(--banner-sub, rgba(253,248,242,0.6));
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-bottom: 1rem;
  transition: color var(--dur);
}
.page-banner .back-link:hover { color: var(--gold); }

/* ── Main nav ────────────────────────────────────────────── */
/* The old header. Nothing renders .main-nav any more, but these rules were
   written unscoped, so `.nav-inner` reached the live header: .9rem of padding
   above and below made it about 29px taller on desktop than its own rules
   say, and a fixed 1200px width meant it ignored the shop's Narrow or Wide
   layout. Scoped to the header they were written for (pass 3, phase 12). */
.main-nav {
  background: var(--warm-white);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
}
.main-nav .nav-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: .9rem 2rem;
  display: flex;
  align-items: center;
  gap: 2rem;
}
.main-nav .nav-brand {
  font-family: var(--ff-head);
  font-size: 1.25rem;
  font-style: italic;
  color: var(--heading-ink, var(--dark));
  font-weight: 600;
}
/* ── Selected size tag (cart + checkout) ────────────────── */
.item-size-tag {
  display: inline-flex;
  align-items: center;
  gap: .28rem;
  margin-top: .3rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .4px;
  text-transform: uppercase;
  color: var(--heading-ink, var(--dark));
  background: var(--gold-pale, #fdf4e3);
  border: 1.5px solid var(--gold);
  border-radius: 4px;
  padding: .18rem .5rem;
  white-space: nowrap;
}
.item-size-tag::before {
  content: '✦';
  font-size: .6rem;
  color: var(--gold);
}
/* ── Cart page ───────────────────────────────────────────── */
.cart-page { padding-top: 2.5rem; padding-bottom: 4rem; }
.cart-layout {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 2rem;
  align-items: start;
}
.cart-row {
  display: grid;
  grid-template-columns: 72px 1fr auto auto auto;
  gap: 1rem;
  align-items: center;
  padding: 1rem 0;
  border-bottom: 1px solid var(--border);
}
.cart-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 6px;
}
.cart-row-name  { font-weight: 600; font-size: .95rem; margin-bottom: .2rem; overflow-wrap: anywhere; }
/* A grid track of 1fr will not shrink below its longest word, so one long
   product name used to widen the cart and checkout past a phone's edge (pass
   4, phase 23 QA matrix). Their columns may shrink; the names wrap. */
.cart-layout > *, .checkout-layout > *, .cart-row > * { min-width: 0; }
.cart-row-price { font-size: .88rem; color: var(--text-light); }
.cart-row-qty   { display: flex; align-items: center; gap: .4rem; }
.qty-btn {
  width: 28px; height: 28px;
  border: 1px solid var(--border);
  background: var(--cream);
  border-radius: 4px;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.qty-input {
  width: 48px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: .25rem;
  font-family: var(--ff-body);
  font-size: .9rem;
}
.cart-row-total { font-weight: 700; min-width: 60px; text-align: right; }
.cart-remove {
  background: none; border: none; cursor: pointer;
  color: var(--text-light); font-size: 1.3rem;
  line-height: 1; padding: 0 .25rem;
  transition: color var(--dur);
}
.cart-remove:hover { color: #e05555; }

.cart-empty-state {
  text-align: center;
  padding: 4rem 0;
  color: var(--text-light);
}
.cart-empty-state p  { font-size: 1.1rem; margin-bottom: 1.5rem; }
.cart-empty          { color: var(--text-light); padding: 2rem 0; }

/* ── Cart / Checkout summary sidebar ────────────────────── */
.cart-summary, .checkout-right {
  background: var(--cream);
  border-radius: 12px;
  padding: 1.5rem;
  border: 1px solid var(--border);
  position: sticky;
  top: 80px;
}
.cart-summary h2, .checkout-right h2 {
  font-size: 1.1rem;
  margin-bottom: 1rem;
  padding-bottom: .75rem;
  border-bottom: 1px solid var(--border);
}
.summary-table {
  width: 100%;
  border-collapse: collapse;
  font-size: .92rem;
  margin-bottom: 1rem;
}
.summary-table td { padding: .35rem 0; }
.summary-table td:last-child { text-align: right; font-weight: 600; }
.sum-total td { border-top: 1px solid var(--border); padding-top: .75rem; font-size: 1.05rem; }
.shipping-note { font-size: .8rem; color: var(--text-light); margin-bottom: 1rem; }

/* ── Coupon row ─────────────────────────────────────────── */
.coupon-row {
  display: flex;
  gap: .5rem;
  margin-bottom: .5rem;
}
.coupon-row input {
  flex: 1;
  min-width: 0;          /* a text field's own width kept the row wider than a 320px phone */
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: .5rem .75rem;
  font-family: var(--ff-body);
  font-size: .9rem;
  text-transform: uppercase;
}
.coupon-row > button { flex: none; }
.coupon-msg      { font-size: .85rem; min-height: 1.2em; }
.coupon-msg.ok   { color: #4a8a5a; }
.coupon-msg.err  { color: #c05050; }

/* ── Checkout page ───────────────────────────────────────── */
.checkout-page { padding-bottom: 4rem; }   /* the top is .below-nav's */
.checkout-layout {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 2rem;
  align-items: start;
}
.section-heading {
  font-family: var(--ff-head);
  font-size: 1.1rem;
  color: var(--heading-ink, var(--dark));
  margin-bottom: .75rem;
}
.checkout-items { margin-bottom: 1rem; }
.checkout-item {
  display: flex;
  gap: 1rem;
  align-items: center;
  padding: .65rem 0;
  border-bottom: 1px solid var(--border);
}
.checkout-item img {
  width: 56px; height: 56px;
  object-fit: cover; border-radius: 6px;
}
.ci-name  { font-weight: 600; font-size: .92rem; overflow-wrap: anywhere; }
.ci-qty   { font-weight: 400; color: var(--text-light); }
.ci-price { font-size: .9rem; color: var(--gold-ink); font-weight: 700; }

/* ── Checkout: contact and ship-to (post-r5) ──────────────
   One rhythm: sections 2rem apart, a label .35rem above its field, fields .9rem apart. */
.co-section { margin-top: 2rem; }
.co-subhead { margin-top: 1.75rem; }
.co-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .9rem 1rem; }
.co-span-2 { grid-column: 1 / -1; }
.co-field { display: flex; flex-direction: column; gap: .35rem; min-width: 0; }
.co-field label { font-size: .85rem; font-weight: 600; color: var(--heading-ink, var(--dark)); }
.co-field input, .co-field select {
  width: 100%; min-width: 0; min-height: 2.6rem;
  border: 1px solid var(--border); border-radius: 6px;
  padding: .55rem .75rem; font-family: var(--ff-body); font-size: .95rem;
  /* The theme's own field colours: on a dark theme a browser-white field with the theme's light ink hid what was typed. */
  background: var(--warm-white); color: var(--text);
}
.co-field input:focus-visible, .co-field select:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; border-color: var(--gold); }
.co-field [aria-invalid="true"] { border-color: #b03a3a; box-shadow: 0 0 0 1px #b03a3a; }
.co-zip-row { margin-top: .9rem; }
.co-zip-row .coupon-row { margin-bottom: 0; }
.co-zip-row .coupon-row input { text-transform: none; min-height: 2.6rem; }
.co-hint { font-size: .8rem; color: var(--text-light); margin: 0; line-height: 1.45; }
/* An error is its own box, readable on any theme (the .auth-error colours). */
.co-err  { font-size: .82rem; margin: 0; line-height: 1.4; background: #fef2f2; border: 1px solid #fca5a5; color: #991b1b; border-radius: 5px; padding: .3rem .55rem; }
.co-opt  { font-weight: 400; color: var(--text-light); font-size: .78rem; }
.co-account { font-size: .88rem; color: var(--text-light); margin: .75rem 0 0; line-height: 1.55; }
.co-account a { color: var(--heading-ink, var(--dark)); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; display: inline-block; padding: .2rem 0; }
.co-signed-in { font-size: .9rem; margin: 0; overflow-wrap: anywhere; }
.co-check { display: flex; gap: .55rem; align-items: flex-start; font-size: .88rem; margin-top: .9rem; cursor: pointer; line-height: 1.45; min-height: 24px; padding: .15rem 0; }
.co-check input { margin-top: .2rem; flex: none; width: 1.05rem; height: 1.05rem; accent-color: var(--gold); }
.co-muted { opacity: .55; }
.co-pickup-note { margin-bottom: .6rem; }
.co-card-min { margin-top: .5rem; text-align: center; background: #fff7e6; border: 1px solid #f0c36d; color: #6b4300; border-radius: 6px; padding: .45rem .7rem; font-size: .85rem; }
@media (max-width: 560px) { .co-grid { grid-template-columns: 1fr; } }

/* ── Shipping options ───────────────────────────────────── */
.shipping-options { display: flex; flex-direction: column; gap: .6rem; }
.shipping-option {
  display: flex;
  align-items: center;
  gap: .75rem;
  border: 2px solid var(--border);
  border-radius: 8px;
  padding: .75rem 1rem;
  cursor: pointer;
  transition: border-color var(--dur);
}
.shipping-option.selected, .shipping-option:has(input:checked) {
  border-color: var(--gold);
  background: var(--gold-pale);
}
.shipping-option input { display: none; }
.so-name  { font-weight: 600; flex: 1; }
.so-price { font-weight: 700; color: var(--gold-ink); transition: opacity .2s; }
.so-desc  { font-size: .8rem; color: var(--text-light); margin-left: auto; }
.so-free-badge { display: none; font-weight: 700; color: var(--gold-deep); font-size: .85rem; }

/* Free shipping active — strike prices, show Free badge */
.shipping-options.free-active .so-price {
  text-decoration: line-through;
  opacity: .45;
}
.shipping-options.free-active .so-free-badge { display: inline; }

/* ── Consent / Marketing opt-in ─────────────────────────── */
.consent-row {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: .6rem;
  font-size: .87rem;
  color: var(--text-light);
  margin-bottom: 1.25rem;
  line-height: 1.5;
}
.consent-row input { margin-top: 3px; flex-shrink: 0; }
.consent-row a { color: var(--gold-ink); text-decoration: underline; }

/* ── Checkout secure note ───────────────────────────────── */
.checkout-secure {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-size: .8rem;
  color: var(--text-light);
  justify-content: center;
  margin-top: .75rem;
}
.policy-links {
  text-align: center;
  font-size: .8rem;
  color: var(--text-light);
  margin-top: .5rem;
}
.policy-links a, .policy-link { color: var(--gold-ink); text-decoration: underline; cursor: pointer; }

/* ── Policy modal ───────────────────────────────────────── */
/* Uses the shared .modal-overlay / .open pattern — no duplicate base rule needed */
.modal-box {
  /* The panel, not a fixed white sheet: a dark family paints its own text
     colour on this and #fff left it unreadable. */
  background: var(--warm-white);
  border-radius: 12px;
  padding: 2rem;
  max-width: 620px;
  width: 100%;
  max-height: 82vh;
  overflow-y: auto;
  position: relative;
  transform: translateY(20px);
  transition: transform 0.3s var(--ease);
}
#policyModal.open .modal-box {
  transform: translateY(0);
}
#policyModal .modal-close {
  position: absolute;
  top: 1rem; right: 1rem;
  background: none; border: none;
  font-size: 1.5rem; cursor: pointer;
  color: var(--text-light);
  line-height: 1;
  /* The product modal's close button grows to 44px below 600px; this one
     never did, and it is the only way out of a full-screen policy on a
     phone. 39x39 is a miss you cannot recover from without the back
     button. */
  width: 44px; height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
#policyModal .modal-close:hover { color: var(--text); }
.policy-content { font-size: .92rem; line-height: 1.8; }
/* A content page's pictures, provider embeds and sealed trusted code (pass 3, 9B/9C). */
.page-content img { max-width: 100%; height: auto; }
.page-content .content-embed { display: block; width: 100%; aspect-ratio: 16 / 9; border: 0; margin: 0 0 1.2em; }
.page-content .content-embed--map { aspect-ratio: 4 / 3; }
.page-content iframe.trusted-code { display: block; width: 100%; border: 0; margin: 0 0 1.2em; }
.policy-content h1, .policy-content h2, .policy-content h3 {
  font-family: 'Playfair Display', serif;
  margin: 1.25rem 0 .5rem;
}
.policy-content p { margin-bottom: .75rem; }
.policy-content ul, .policy-content ol { padding-left: 1.5rem; margin-bottom: .75rem; }
@media (max-width: 500px) {
  .modal-box { padding: 1.25rem 1rem; max-height: 90vh; }
}

/* ── Scroll to top button ───────────────────────────────── */
/* After RaccoonKit's BackToTop: a frosted circle over the page, a ring that
   fills with the reader's progress down it, and a chevron that lifts a little
   on hover. In the shop's own colours: the ring is the primary, the circle
   the light surface, the chevron the body text -- so it reads in every family,
   light or dark. */
.scroll-top {
  position: fixed;
  right: calc(1.25rem + env(safe-area-inset-right, 0px));
  bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  z-index: 500;
  width: 46px; height: 46px;
  padding: 0;
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(255,255,255,.72);
  background: color-mix(in srgb, var(--warm-white) 74%, transparent);
  border: 1px solid color-mix(in srgb, var(--border) 85%, transparent);
  box-shadow: 0 6px 20px var(--shadow-sm);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--text);
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px) scale(.96);
  transition: opacity .2s ease, transform .2s ease, background-color .15s ease, border-color .15s ease;
  pointer-events: none;
}
.scroll-top.visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  visibility: visible;
}
.scroll-top:hover { background: color-mix(in srgb, var(--warm-white) 96%, transparent); border-color: color-mix(in srgb, var(--gold) 35%, var(--border)); }
.scroll-top:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.scroll-top-ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; transform: rotate(-90deg); }
.scroll-top-track, .scroll-top-progress { fill: none; stroke-width: 3; }
.scroll-top-track { stroke: color-mix(in srgb, var(--border) 70%, transparent); }
.scroll-top-progress {
  stroke: var(--gold);
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset .15s linear;
}
.scroll-top-icon {
  position: relative;
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round;
  transform: translateY(-1px);
  transition: transform .15s ease;
}
.scroll-top:hover .scroll-top-icon { transform: translateY(-3px); }
@media (max-width: 900px) {
  .scroll-top { width: 48px; height: 48px; right: calc(.75rem + env(safe-area-inset-right, 0px)); bottom: calc(.75rem + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-top, .scroll-top-icon, .scroll-top-progress { transition: none; }
}
/* Hidden means hidden to the keyboard too: at opacity 0 it still took a Tab
   stop, focus landed on nothing visible (pass 4, phase 23 QA matrix).
   Visibility waits for the fade before it goes. */
.scroll-top:not(.visible) { visibility: hidden; transition: opacity .2s, transform .2s, visibility 0s linear .2s; }

/* ── Site footer ─────────────────────────────────────────── */
.site-footer {
  background: var(--footer-bg, var(--dark));
  color: var(--footer-ink, rgba(255,255,255,.6));
  text-align: center;
  padding: 1.5rem;
  font-size: .85rem;
}
.site-footer a { color: var(--footer-tag, var(--gold-light)); }
/* The footer's links had no focus of their own, and Firefox drew none
   ("Part of ..." and the policy links; pass 4, phase 23 QA matrix). */
.site-footer a:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; border-radius: 2px; }

/* ── Responsive tweaks for cart/checkout ────────────────── */
@media (max-width: 768px) {
  .cart-layout, .checkout-layout {
    grid-template-columns: 1fr;
  }
  .cart-summary, .checkout-right { position: static; }
  .cart-row {
    grid-template-columns: 56px 1fr;
    grid-template-rows: auto auto;
  }
  .cart-row-qty, .cart-row-total, .cart-remove { grid-column: 2; }
}

/* ═══════════════════════════════════════════════════════════
   v4.1 — Mobile UX Polish Pass
   ═══════════════════════════════════════════════════════════ */

/* ── 1. Global mobile typography & spacing ───────────────────
   Clamp hero h1 more aggressively, ensure body text ≥ 16px,
   tighten paragraph line-height on very small screens.        */
@media (max-width: 480px) {
  html { font-size: 16px; }            /* prevent iOS auto-zoom */

  body { line-height: 1.65; }

  p { line-height: 1.7; }

  .section-header h2 {
    font-size: clamp(1.55rem, 7vw, 2rem);
  }

  .hero h1 {
    font-size: clamp(2rem, 10vw, 3rem);
  }

  .hero-subtext {
    font-size: 0.97rem;
    line-height: 1.7;
  }
}

@media (max-width: 320px) {
  .container { padding: 0 1rem; }

  .hero h1 { font-size: clamp(1.7rem, 11vw, 2.4rem); }

  .hero-subtext { font-size: 0.9rem; }
}


/* ── 2. Navigation on a phone ──
   Touch targets, padding and the 320px sizes now live in one place: "The
   header on a phone", further down. */


/* ── 3. Hero section ─────────────────────────────────────────
   Reduce height on portrait mobile, full-width CTAs ≤ 400 px,
   prevent text overflow at 320 px.                            */
@media (max-width: 480px) {
  .hero {
    min-height: min(85vh, 600px);
  }

  .hero-content {
    padding: 1.25rem;
    max-width: 100%;
  }
}

@media (max-width: 400px) {
  .hero-ctas .btn {
    width: 100%;
    justify-content: center;
    max-width: 100%;
  }
}

@media (max-width: 320px) {
  .hero h1 { overflow-wrap: break-word; word-break: break-word; }
  .hero-subtext { font-size: 0.88rem; }
  .hero-eyebrow { font-size: 1.1rem; }
}


/* ── 4. Product cards grid ───────────────────────────────────
   Single-column ≤ 480 px, locked aspect ratio, full-card tap,
   overflow-safe product names.                                */
@media (max-width: 480px) {
  .featured-grid,
  .products-grid {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  /* Lock image aspect ratio to prevent layout shift */
  .product-card-img {
    aspect-ratio: 4 / 3;
  }

  /* Make the entire card a tappable flex column */
  .product-card {
    display: flex;
    flex-direction: column;
  }

  /* Prevent long product names from overflowing */
  .product-card-body h3 {
    overflow-wrap: break-word;
    word-break: break-word;
  }
}


/* ── 5. Product quick view: one column below 761px ─────────────
   Centred to 641px; below that sheet.js makes it a bottom sheet (the rules
   near the end of this file). Without script, the same one column. The
   picture on top is capped so the name and price are on the first screen. */
@media (max-width: 760px) {
  .modal {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    height: auto;
    max-height: 90vh;
    max-width: 560px;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .modal-img-pane { height: min(46vh, 380px); }
  .modal-body { overflow: visible; padding: 1.4rem 1.4rem 1.5rem; }
  .modal-cat, .modal-name { margin-right: 0; }
  /* The main action stays in reach at the foot of the panel while the rest
     scrolls, and settles into place when you reach it. Measured before it
     was added: with two choices, or personalisation, it sat 20-240px below
     the first screen on a phone. */
  .qv-cta {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 1rem -1.4rem 0;
    padding: .7rem 1.4rem calc(.7rem + env(safe-area-inset-bottom, 0px));
    background: var(--warm-white);
    border-top: 1px solid var(--border);
  }
}
@media (max-width: 640px) {
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal { max-width: none; border-radius: var(--radius) var(--radius) 0 0; }
  .modal-img-pane { height: min(40vh, 340px); }
  .modal-close { width: 44px; height: 44px; font-size: 1.25rem; top: .6rem; right: .6rem; }
}

/* Size picker / option buttons — ensure 44 px touch targets */
.size-btn,
.color-btn,
[data-size],
[data-color] {
  min-height: 44px;
  min-width: 44px;
}


/* ── 6. Cart page ────────────────────────────────────────────
   Larger qty controls (≥ 36 px), sticky total at bottom on mobile */
@media (max-width: 768px) {
  .qty-btn {
    width: 36px;
    height: 36px;
    font-size: 1.05rem;
  }

  .qty-input {
    height: 36px;
    font-size: 1rem;
  }

  /* Sticky cart summary at bottom of viewport */
  .cart-summary {
    position: sticky;
    bottom: 0;
    z-index: 50;
    border-radius: var(--radius) var(--radius) 0 0;
    box-shadow: 0 -4px 24px var(--shadow);
    background: var(--cream);
    padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
  }
}

@media (max-width: 480px) {
  .cart-row {
    gap: 0.75rem;
  }

  .cart-row-name { font-size: 0.9rem; }

  .cart-remove {
    min-width: 36px;
    min-height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}


/* ── 7. Checkout page ────────────────────────────────────────
   Single column, full-width payment button sticky at bottom,
   larger shipping option touch targets.                        */
@media (max-width: 768px) {
  .checkout-page { padding-bottom: 6rem; }

  .checkout-layout {
    grid-template-columns: 1fr;
  }

  /* Pull the order summary panel above the form on mobile */
  .checkout-right {
    order: -1;
    position: static;
  }

  /* Sticky payment / submit button */
  .btn-gold.btn-full {
    position: sticky;
    bottom: 0;
    z-index: 60;
    width: 100%;
    border-radius: 0;
    padding-bottom: calc(0.85rem + env(safe-area-inset-bottom, 0px));
    margin-top: 0.5rem;
  }
}

@media (max-width: 480px) {
  .btn-gold.btn-full {
    font-size: 1rem;
    padding: 1rem;
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  }

  /* Larger shipping option touch targets */
  .shipping-option {
    padding: 1rem;
    min-height: 52px;
  }

  .shipping-options {
    gap: 0.75rem;
  }
}


/* ── 8. Forms — general mobile polish ───────────────────────
   44 px min-height for inputs/selects/textareas, clear labels,
   prevent iOS auto-zoom (font-size ≥ 1rem on focus).          */
@media (max-width: 768px) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  select,
  textarea,
  .form-group input,
  .form-group select,
  .form-group textarea {
    min-height: 44px;
    font-size: 1rem;        /* prevents iOS zoom on focus */
    padding: 0.7rem 0.9rem;
  }

  textarea,
  .form-group textarea {
    min-height: 100px;
  }

  .form-group label {
    font-size: 0.88rem;
    margin-bottom: 0.45rem;
    display: block;
  }

  /* Coupon input */
  .coupon-row input {
    min-height: 44px;
    font-size: 1rem;
  }
}

/* Error state visibility */
.form-group input.error,
.form-group select.error,
.form-group textarea.error {
  border-color: #e05555 !important;
  background: #fff5f5 !important;
}


/* ── 9. Filter / sort bar (v4.1) ────────────────────────────
   Stack vertically ≤ 600 px, price buttons wrap, sort full-width */
@media (max-width: 600px) {
  .filter-bar,
  .sort-bar {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    align-items: stretch;
  }

  /* Price / filter buttons: wrap and fill row */
  .price-filters,
  .filter-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  .price-filters .btn,
  .price-filters button,
  .filter-buttons .btn,
  .filter-buttons button {
    flex: 1 1 auto;
    min-width: calc(50% - 0.25rem);
    justify-content: center;
    text-align: center;
  }

  /* Sort select: full width */
  .sort-select,
  select.sort-select,
  [name="sort"],
  [id="sort"] {
    width: 100%;
    min-height: 44px;
    font-size: 1rem;
  }
}


/* ── 10. Gift wrap option ────────────────────────────────────
   Styles for .gift-wrap-option used in checkout.              */
.gift-wrap-option {
  margin: 1.2rem 0;
  padding: 1rem 1.2rem;
  background: var(--warm-white);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.2s;
}

.gift-wrap-option:has(input:checked) {
  border-color: var(--gold);
  background: var(--gold-pale);
}

.gift-wrap-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
}

.gift-wrap-label input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--gold);
  flex-shrink: 0;
}

.gift-wrap-icon  { font-size: 1.4rem; }

.gift-wrap-price {
  display: block;
  font-size: 0.8rem;
  color: var(--text-light);
  margin-top: 0.1rem;
}


/* ── 11. Order status timeline ──────────────────────────────
   Desktop: horizontal row; mobile: vertical stack with a
   connecting line on the left side.                           */
.order-status-timeline {
  display: flex;
  gap: 0;
  align-items: flex-start;
  justify-content: space-between;
  position: relative;
  padding: 0.5rem 0;
  overflow-x: auto;
}

/* Horizontal connector line */
.order-status-timeline::before {
  content: '';
  position: absolute;
  top: 22px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--border);
  z-index: 0;
}

.timeline-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  flex: 1;
  min-width: 60px;
  position: relative;
  z-index: 1;
}

.timeline-step-icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--cream);
  border: 2px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  transition: border-color 0.2s, background 0.2s;
}

.timeline-step.active .timeline-step-icon,
.timeline-step.done   .timeline-step-icon {
  border-color: var(--gold);
  background: var(--gold-pale);
}

.timeline-step-label {
  font-size: 0.72rem;
  font-weight: 700;
  text-align: center;
  color: var(--text-light);
  letter-spacing: 0.3px;
}

.timeline-step.active .timeline-step-label,
.timeline-step.done   .timeline-step-label {
  color: var(--gold-deep);
}

/* Mobile: vertical stack, connecting line on the left */
@media (max-width: 600px) {
  .order-status-timeline {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    overflow-x: visible;
    padding-left: 1.5rem;
  }

  /* Vertical connecting line */
  .order-status-timeline::before {
    top: 0;
    bottom: 0;
    left: 21px;
    right: auto;
    width: 2px;
    height: 100%;
  }

  .timeline-step {
    flex-direction: row;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
    min-height: 56px;
    padding: 0.35rem 0;
  }

  .timeline-step-icon {
    flex-shrink: 0;
  }

  .timeline-step-label {
    text-align: left;
    font-size: 0.88rem;
  }
}


/* ── 12. Sticky bottom bars — safe-area-inset-bottom ────────
   Ensures content is not hidden by iPhone notch / home bar.   */

.toast {
  bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
}

@media (max-width: 768px) {
  .checkout-actions,
  .sticky-pay-bar {
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
  }
}

/* Product condition. A stated fact about the item, so it reads as a quiet
   line rather than competing with the sale and stock badges. */
.product-condition {
  font-size: .72rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-light);
  margin-bottom: .2rem;
}

/* Content that begins immediately under the header: its overlap, then the
   one gap. Every inner page's <main> uses this (pass 4, phase 7); nothing
   adds its own header clearance. */
.below-nav { padding-top: calc(var(--nav-overlap, var(--nav-h)) + var(--below-nav-gap, 1.5rem)); }

/* ══════════════════════════════════════════════════════════════
   Product detail page  (/product/{slug})

   Built from the same tokens as everything else, so a store that has
   picked its own colors or is running a seasonal theme gets a product
   page that matches without anyone touching this file.
   ══════════════════════════════════════════════════════════════ */

.pdp {
  max-width: 1120px;
  margin: 0 auto;
  /* No padding-top here: .below-nav owns it, and a shorthand would silently
     win over it depending on which rule the browser reads last. */
  padding-left: 1.5rem;
  padding-right: 1.5rem;
  padding-bottom: 4rem;
}

.pdp-crumbs {
  font-size: .82rem;
  color: var(--text-light);
  margin-bottom: 1.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
  align-items: center;
}
.pdp-crumbs a { color: var(--text-light); text-decoration: none; }
.pdp-crumbs a:hover { color: var(--gold); text-decoration: underline; }
.pdp-crumbs span[aria-hidden] { opacity: .5; }
.pdp-crumbs [aria-current] { color: var(--text); }

/* Only an admin ever sees this. */
.pdp-withdrawn {
  background: var(--gold-pale);
  border: 1px solid var(--gold);
  color: var(--on-gold-pale, var(--heading-ink, var(--dark)));
  border-radius: var(--radius-sm);
  padding: .75rem 1rem;
  font-size: .88rem;
  margin-bottom: 1.5rem;
}

/* A preview of something not saved yet: the same band as a withdrawn product,
   because it is the same kind of message — this is not what shoppers see. */
.pdp-preview-note {
  background: var(--gold-pale);
  border: 1px dashed var(--gold);
  color: var(--on-gold-pale, var(--heading-ink, var(--dark)));
  border-radius: var(--radius-sm);
  padding: .75rem 1rem;
  font-size: .88rem;
  line-height: 1.55;
  margin-bottom: 1.5rem;
}

/* The same note on the homepage, for the Themes page's preview of a look not
   saved yet (index.php, includes/theme-preview.php). Pinned to the foot of the
   frame rather than pushed into the page, so the page under it is laid out
   exactly as a shopper gets it. Above the header, below an open quick view. */
.theme-preview-note {
  position: fixed;
  left: 50%;
  bottom: .75rem;
  transform: translateX(-50%);
  z-index: 950;
  width: max-content;
  max-width: calc(100% - 1.5rem);
  margin: 0;
  padding: .55rem .9rem;
  background: var(--gold-pale);
  border: 1px dashed var(--gold);
  color: var(--on-gold-pale, var(--heading-ink, var(--dark)));
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
  font-size: .8rem;
  line-height: 1.45;
  text-align: center;
  transition: outline-color .2s;
  outline: 2px solid transparent;
  outline-offset: 2px;
}
/* Pressed something that is paused: the note says why, by drawing the eye. */
.theme-preview-note.is-flash { outline-color: var(--gold); }

.pdp-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 3rem;
  align-items: start;
}

/* ── Images ── */
.pdp-media { position: sticky; top: 6rem; }
.pdp-img {
  width: 100%;
  height: auto;   /* the width/height attributes reserve the space; they must not stretch the picture */
  display: block;
  border-radius: var(--radius);
  box-shadow: 0 6px 26px var(--shadow-sm);
  background: var(--warm-white);
}
.pdp-img-placeholder {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
  border-radius: var(--radius);
  background: var(--cream);
  border: 1px solid var(--border);
}
.pdp-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: .55rem;
  margin-top: .9rem;
}
.pdp-thumb {
  width: 68px;
  height: 68px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--border);
  background-size: cover;
  background-position: center;
  cursor: pointer;
  padding: 0;
  transition: border-color var(--dur) var(--ease);
}
.pdp-thumb:hover { border-color: var(--gold-light); }
.pdp-thumb.active { border-color: var(--gold); }

/* ── Details ── */
.pdp-cat {
  font-size: .7rem;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: .5rem;
}
.pdp-name {
  font-family: var(--ff-head);
  font-size: clamp(1.7rem, 3.4vw, 2.4rem);
  line-height: 1.15;
  color: var(--heading-ink, var(--dark));
  margin: 0 0 .7rem;
  /* The quick view's rule (.modal-name), here too: a long unbroken run in a
     name -- a SKU, a run-together word -- widened the whole page on a phone
     and was clipped at its edge (pass 4, phase 23 QA matrix). */
  overflow-wrap: anywhere;
  hyphens: auto;
}
/* The breadcrumb ends with the same name, and the columns may shrink below
   their longest word instead of pushing the page wider. */
.pdp-crumbs > * { min-width: 0; }
.pdp-crumbs [aria-current] { overflow-wrap: anywhere; }
.pdp-grid > * { min-width: 0; }
.pdp-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .9rem;
  font-size: .74rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-light);
  margin-bottom: 1.1rem;
}

.pdp-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .6rem;
  margin-bottom: .5rem;
}
.pdp-now { font-size: 1.9rem; font-weight: 700; color: var(--heading-ink, var(--dark)); }
.pdp-was { font-size: 1.1rem; color: var(--text-light); }
.pdp-badge {
  background: var(--rose);
  color: var(--on-rose, #fff);
  font-size: .68rem;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: .25rem .6rem;
  border-radius: 50px;
}
.pdp-bulk { font-size: .85rem; color: var(--text-light); margin-bottom: 1rem; }

.pdp-desc {
  line-height: 1.75;
  color: var(--text);
  margin: 1.2rem 0 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
}

/* Details: facts about the item, as against the choices above the buy button.
   A two-column grid rather than a table, so a long value wraps under itself
   instead of stretching the label column to match. */
.pdp-details {
  display: grid;
  grid-template-columns: minmax(6rem, auto) 1fr;
  gap: .45rem 1.25rem;
  margin: 0 0 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
  font-size: .95rem;
  line-height: 1.6;
}
.pdp-desc + .pdp-details { border-top: 0; padding-top: 0; margin-top: -.4rem; }
.pdp-details dt {
  color: var(--text-muted);
  font-size: .82rem;
  letter-spacing: .02em;
  text-transform: uppercase;
  padding-top: .1rem;
}
.pdp-details dd { margin: 0; color: var(--text); }

.pdp-oos {
  font-weight: 700;
  color: var(--rose);
  text-transform: uppercase;
  letter-spacing: .05em;
  font-size: .85rem;
}

/* ── Buy box ── */
.pdp-buy { margin-top: .5rem; }
.pdp-opt { margin-bottom: 1rem; }
.pdp-opt-label {
  display: block;
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-light);
  margin-bottom: .35rem;
}
.pdp-select,
.pdp-text,
.pdp-qty {
  font-family: var(--ff-body);
  font-size: .95rem;
  color: var(--text);
  background: var(--warm-white);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .6rem .75rem;
  width: 100%;
  max-width: 320px;
}
.pdp-qty { max-width: 110px; }
.pdp-select:focus,
.pdp-text:focus,
.pdp-qty:focus {
  outline: none;
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-pale);
}

.pdp-add {
  display: inline-block;
  border: none;
  cursor: pointer;
  font-family: var(--ff-body);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .03em;
  padding: .85rem 2.4rem;
  border-radius: 50px;
  margin-top: .4rem;
}
.pdp-add[disabled] { opacity: .55; cursor: not-allowed; }

/* Confirmation, and the reason when it does not work -- a size that sold out
   between the page loading and the click, for instance. */
.pdp-buy-msg {
  margin-top: .8rem;
  font-size: .88rem;
  font-weight: 600;
  color: var(--gold-deep);
}
.pdp-buy-msg.bad { color: var(--rose); }

.pdp-custom { display: inline-block; margin-top: 1.2rem; }

/* ── 404 ── */
.pdp-404 { text-align: center; padding: 4rem 0; }
.pdp-404 h1 { font-family: var(--ff-head); font-size: 3rem; color: var(--gold); margin: 0; }
.pdp-404 p { color: var(--text-light); margin: 1rem 0 1.6rem; }
.pdp-back { display: inline-block; padding: .75rem 2rem; border-radius: 50px; text-decoration: none; }

@media (max-width: 860px) {
  .pdp-grid { grid-template-columns: 1fr; gap: 2rem; }
  .pdp-media { position: static; }
}

/* ── Quick-view: secondary actions ───────────────────────────
   A hierarchy, rather than three things all shouting. "Add to Cart" is the
   primary and keeps its weight; these sit under it, quieter, in the order
   somebody actually wants them. */
.modal-secondary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem 1rem;
  margin-top: .9rem;
}
.modal-details-link {
  font-size: .9rem;
  font-weight: 600;
  color: var(--gold-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.modal-share {
  background: none;
  border: 1px solid var(--border);
  border-radius: 50px;
  padding: .4rem .9rem;
  font: inherit;
  font-size: .84rem;
  color: var(--text-light);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}
.modal-share:hover { border-color: var(--gold); color: var(--gold); }
.modal-share:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* Feedback after copying.
   It was a paragraph in the flow, which meant the card grew by a line when the
   message appeared and shrank again when it cleared -- the whole modal moved
   under the reader's eyes. It is a tooltip over the button now: absolutely
   positioned, so it costs no layout, fades in and out, and still carries
   role="status" so a screen reader announces it. */
.share-wrap { position: relative; display: inline-flex; }
.share-tip {
  position: absolute;
  bottom: calc(100% + .45rem);
  left: 50%;
  transform: translate(-50%, .25rem);
  z-index: 5;
  background: var(--dark);
  color: #fff;
  font-size: .76rem;
  line-height: 1.3;
  white-space: nowrap;
  padding: .34rem .6rem;
  border-radius: 6px;
  box-shadow: 0 4px 14px rgba(0,0,0,.18);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s linear .18s;
}
.share-tip::after {
  /* The little pointer. */
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--dark);
}
.share-tip.show {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
  transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s;
}
@media (prefers-reduced-motion: reduce) {
  .share-tip { transition: opacity .01s, visibility 0s linear .01s; }
  .share-tip.show { transition: opacity .01s, visibility 0s; }
}

/* The custom-order ask. Was a full-width bordered pill competing with the
   primary action on every product; now a quiet line under everything else. */
.modal-custom-ask {
  display: block;
  margin-top: 1rem;
  padding-top: .85rem;
  border-top: 1px solid var(--border);
  font-size: .85rem;
  color: var(--text-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.modal-custom-ask:hover { color: var(--gold); }

/* Same control on the full product page. It sits below the buy action rather
   than beside it: on the page somebody has already committed to opening, the
   share is a second thought, not a competing one. */
.pdp-secondary {
  margin-top: 1rem;
  display: flex;
  align-items: center;
  gap: .75rem;
}
/* The custom-order ask, matched to the quick view's treatment. .modal-custom-ask
   carries the look; this only widens the divider to the column. */
.pdp-custom-ask { margin-top: 1.25rem; }
/* Sold out: "Want one like this?" and the two ways to get one. */
.pdp-like { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--border, rgba(0,0,0,.1)); display: flex; flex-direction: column; gap: .4rem; }
.pdp-like-q { margin: 0; font-weight: 600; }
.pdp-like .pdp-custom-ask { margin-top: 0; }
.pdp-like-wanted { font-size: .9rem; color: inherit; opacity: .8; text-decoration: underline; text-underline-offset: 2px; }

/* ── The product page, pass 3 (7): the quick view's language on a page ──
   docs/QUICK-VIEW.md is the contract. The page keeps its own layout -- a
   gallery column, a words column -- and takes the quick view's vocabulary:
   price and status on one line, choices as pressed chips with the same
   selected, sold-out and optional states, one main action, and on a phone
   the sticky purchase bar. */
.pdp-price { align-items: center; gap: .35rem .75rem; margin-bottom: .8rem; }
.pdp-status {
  display: inline-flex; align-items: center;
  padding: .18rem .6rem;
  border: 1.5px solid currentColor; border-radius: 999px;
  color: var(--text);
  font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.pdp-cond { font-size: .86rem; font-weight: 600; color: var(--text-light); }

.pdp-group { border: 0; margin: 0 0 1.1rem; padding: 0; min-width: 0; }
.pdp-group-label {
  padding: 0; margin: 0 0 .5rem;
  font-size: .76rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-light);
}
.pdp-optional { font-weight: 600; letter-spacing: 0; text-transform: none; }
.pdp-picked { margin-left: .5rem; font-size: .88rem; font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text); }
.pdp-choices { display: flex; flex-wrap: wrap; gap: .45rem; }
.pdp-choice {
  position: relative;
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 42px; padding: .4rem .95rem;
  border: 1.5px solid var(--border); border-radius: var(--btn-radius-sm, 6px);
  background: var(--warm-white); color: var(--text);
  font-size: .92rem; cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}
/* The radio stays in the page, for the keyboard and a screen reader; the
   label is what is drawn. */
.pdp-choice input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.pdp-choice:hover:not(.is-out) { border-color: var(--text-light); }
.pdp-choice.is-on,
.pdp-choice:has(input:checked) {
  border-color: var(--heading-ink, var(--dark));
  box-shadow: inset 0 0 0 1px var(--heading-ink, var(--dark));
  background: color-mix(in srgb, var(--heading-ink, var(--dark)) 10%, var(--warm-white));
  font-weight: 700;
}
.pdp-choice:has(input:focus-visible) { outline: 2px solid var(--gold); outline-offset: 2px; }
.pdp-choice.is-out { color: var(--text-light); text-decoration: line-through; opacity: .55; cursor: not-allowed; }
.pdp-swatch { flex: none; width: 18px; height: 18px; border-radius: 50%; border: 1px solid rgba(0,0,0,.2); }
@media (pointer: coarse) { .pdp-choice { min-height: 44px; } }
.pdp-group.is-missing .pdp-group-label { color: var(--text); }
.pdp-group.is-missing .pdp-choices { border-radius: 8px; box-shadow: 0 0 0 2px var(--rose, #b3261e); }
.pdp-need { margin: .6rem 0 0; font-size: .9rem; font-weight: 600; color: var(--text); }
.pdp-need:not(.is-on) { display: none; }
.pdp-need.is-on::before { content: '! '; color: var(--rose, #b3261e); font-weight: 800; }

/* Quantity and the main action on one row: the button right under what it
   depends on, as wide as the row allows. */
.pdp-cta { display: flex; align-items: flex-end; flex-wrap: wrap; gap: .75rem; margin-top: .3rem; }
.pdp-cta .pdp-qty { width: 88px; }
.pdp-cta .pdp-add { flex: 1 1 12rem; min-height: 48px; margin-top: 0; }

/* Sold out's next step: a real button, not the gold one, because it is not
   buying -- the quick view's .qv-alt. */
.pdp-like.pdp-next { margin-top: .4rem; padding-top: 0; border-top: 0; gap: .55rem; }
.pdp-next-ask {
  display: flex; align-items: center; justify-content: center;
  min-height: 48px; padding: .7rem 1.2rem;
  border: 1.5px solid var(--border); border-radius: var(--btn-radius-sm, 6px);
  color: var(--text); font-weight: 700; text-decoration: none; text-align: center;
}
.pdp-next-ask:hover { border-color: var(--text-light); color: var(--text); }
.pdp-next-ask:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pdp-next-more { font-size: .9rem; color: inherit; opacity: .8; text-decoration: underline; text-underline-offset: 2px; }

/* What only a page has room for: sections under one quiet heading each. */
.pdp-more { margin-top: 1.8rem; }
.pdp-section { padding: 1.15rem 0; border-top: 1px solid var(--border); }
.pdp-section-h {
  margin: 0 0 .7rem;
  font-family: var(--ff-body); font-size: .78rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--text-light);
}
.pdp-more .pdp-desc { margin: 0; padding: 0; border: 0; }
.pdp-desc p { margin: 0 0 .8em; }
.pdp-desc p:last-child { margin-bottom: 0; }
.pdp-more .pdp-details { margin: 0; padding: 0; border: 0; }
.pdp-policies { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; margin: .8rem 0 0; font-size: .92rem; }
.pdp-policies a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.pdp-seller-name { margin: 0; font-weight: 700; color: var(--heading-ink, var(--dark)); }
.pdp-seller-tag { margin: .15rem 0 0; font-size: .92rem; color: var(--text-light); }
.pdp-seller-note { margin: .6rem 0 0; font-size: .92rem; color: var(--text); }
.pdp-seller-more { display: inline-block; margin-top: .6rem; font-weight: 700; color: inherit; text-decoration: underline; text-underline-offset: 3px; }

/* The purchase bar on a phone (7A): shown by product-page.js only while the
   page's own main action is off the screen. The page gains room at its foot
   while it shows, so it never covers the end of the page, and the toast and
   the back-to-top button move up above it. */
.pdp-sticky { display: none; }
@media (max-width: 860px) {
  .pdp-sticky:not([hidden]) {
    display: block;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 800;
    background: var(--warm-white);
    border-top: 1px solid var(--border);
    box-shadow: 0 -8px 24px rgba(0, 0, 0, .12);
    padding: .6rem max(1rem, env(safe-area-inset-right, 0px)) calc(.6rem + env(safe-area-inset-bottom, 0px)) max(1rem, env(safe-area-inset-left, 0px));
  }
  .pdp-sticky-in { display: flex; align-items: center; gap: .75rem; max-width: 1120px; margin: 0 auto; }
  .pdp-sticky-what { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
  .pdp-sticky-name { font-size: .86rem; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .pdp-sticky-price { font-size: .95rem; font-weight: 700; color: var(--heading-ink, var(--dark)); white-space: nowrap; }
  /* Sold out, the price and the status are the whole message. */
  .pdp-sticky.is-soldout .pdp-sticky-name { display: none; }
  .pdp-sticky-go { flex: none; display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: .6rem 1.3rem; border-radius: 50px; font-weight: 700; }
  .pdp-sticky .pdp-next-ask.pdp-sticky-go { border-radius: var(--btn-radius-sm, 6px); }
  body.has-pdp-sticky { padding-bottom: calc(4.5rem + env(safe-area-inset-bottom, 0px)); }
  body.has-pdp-sticky .scroll-top,
  body.has-pdp-sticky .toast { bottom: calc(5.4rem + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 360px) {
  .pdp-sticky-what { display: none; }
  .pdp-sticky-go { flex: 1 1 auto; }
}

@media (max-width: 30rem) {
  /* Tap targets, and no side-by-side squeeze on a narrow phone. */
  .modal-secondary { flex-direction: column; align-items: stretch; }
  .share-wrap { display: flex; }
  .modal-share { flex: 1; }
  .modal-share { justify-content: center; padding: .6rem .9rem; }
  .modal-details-link { padding: .3rem 0; }
}
/* Saved items are available to guests as well as customer accounts. */
.wishlist-heart {
  position:absolute; top:.5rem; right:.5rem; z-index:2;
  display:flex; align-items:center; justify-content:center; gap:.4rem;
  width:2.15rem; height:2.15rem; padding:0;
  border:1px solid rgba(0,0,0,.08); border-radius:999px;
  background:rgba(255,255,255,.92); color:#8c817b;
  box-shadow:0 1px 5px rgba(0,0,0,.15); cursor:pointer;
  font:inherit; font-size:1.2rem; line-height:1;
  transition:transform .15s, color .15s, background .15s;
}
.wishlist-heart:hover { transform:scale(1.08); background:#fff; color:#b32f55; }
.wishlist-heart.wishlisted { color:#b32f55; }
.wishlist-heart .heart-empty, .wishlist-heart.wishlisted .heart-full { display:inline; }
.wishlist-heart .heart-full, .wishlist-heart.wishlisted .heart-empty { display:none; }
.wishlist-heart:disabled { cursor:wait; opacity:.7; }
.wishlist-heart.pdp-save {
  position:static; width:auto; min-height:2.5rem; padding:.55rem .9rem;
  border-color:var(--border); box-shadow:none; font-size:.88rem;
  background:transparent; color:var(--text-light);
}
.wishlist-heart.pdp-save:hover, .wishlist-heart.pdp-save.wishlisted {
  transform:none; color:var(--heading-ink, var(--dark)); background:var(--cream);
}
.wishlist-heart.pdp-save .heart-empty,
.wishlist-heart.pdp-save .heart-full { font-size:1.15rem; }
.nav-saved-link { white-space:nowrap; }
.nav-saved-count {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:1.25rem; height:1.25rem; padding:0 .3rem; margin-left:.15rem;
  border-radius:999px; background:var(--gold); color:var(--on-gold, #fff); font-size:.68rem;
}
/* wishlist.js hides the count at zero with the hidden attribute, which a
   display rule outranks: "Saved 0" showed on every shop that had saved
   nothing. */
.nav-saved-count[hidden] { display:none; }

/* ── Saved and Cart as icons in the desktop row (pass 3, 6.10) ──
   The Marketplace draws them as a heart and a cart with the count as a badge,
   and now the shop does too, in its own colours: the icon is the link's own
   ink (the theme's tokens -- light over the hero, dark once scrolled), the
   badge the shop's gold, the hover and focus rings drawn in currentColor so
   they follow both. The words are read, not shown. Below 769px the phone
   header is untouched: the cart is the bar's icon, and Saved is a row in the
   menu with its word beside the heart. */
.nav-icon-link .nav-icon { flex: none; }
.nav-links .nav-icon { width: 18px; height: 18px; }
@media (min-width: 769px) {
  .nav-links .nav-icon-link {
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 38px; height: 38px; border-radius: 50%;
    transition: color var(--dur), background-color var(--dur);
  }
  .nav-links .nav-icon { width: 20px; height: 20px; display: block; }
  .nav-links .nav-icon-link::after { display: none; }
  .nav-icon-link .nav-icon-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .nav-links .nav-icon-link:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
  .nav-links .nav-icon-link:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
  .nav-icon-link .cart-count,
  .nav-icon-link .nav-saved-count {
    position: absolute; top: 0; right: -4px;
    min-width: 17px; height: 17px; margin: 0; padding: 0 4px;
    border-radius: 9px; font-size: .64rem; font-weight: 700; line-height: 1;
  }
  .nav-cart-count.is-zero { display: none; }
}
@media (min-width: 769px) and (pointer: coarse) {
  .nav-links .nav-icon-link { width: 44px; height: 44px; }
}


/* ── Policy text ──
   A deliberate blank line the shop owner typed. The admin preview uses the
   same rule, and the two have to match or the preview lies. */
.policy-content .policy-gap { margin: 0; height: .6em; }


/* ── The network, apart from the shop's own links (pass 4, 6.4) ──
   Last in the row, after a rule, under its own name and never in the shop's
   menu type: no uppercase, no underline, the platform's name as written. The
   rule and the outline are drawn in the link's own ink, so they follow the
   theme over the hero and once scrolled. Below 769px it is the menu's last
   section, with its caption on a line of its own. */
.nav-network-link {
  display: inline-flex !important; align-items: center;
  font-size: .78rem !important; font-weight: 600 !important;
  letter-spacing: .2px !important; text-transform: none !important;
  white-space: nowrap;
}
.nav-network-link::after { display: none !important; }
.nav-network-caption {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.nav-network-name { display: inline-flex; align-items: center; gap: .35em; }
.nav-network-short { display: none; }
.nav-network-name svg { flex: none; }
@media (min-width: 769px) {
  .nav-links > .nav-network {
    display: flex; align-items: center;
    margin-left: .25rem; padding-left: 1.25rem;
    border-left: 1px solid color-mix(in srgb, var(--nav-link-top, rgba(232, 201, 122, 0.82)) 35%, transparent);
  }
  .site-nav.scrolled .nav-links > .nav-network {
    border-left-color: color-mix(in srgb, var(--nav-link, var(--text)) 25%, transparent);
  }
  .nav-network-link {
    padding: .3rem .8rem !important;
    border: 1.5px dashed currentColor; border-radius: 20px;
    opacity: .82; transition: opacity .2s, background .2s, color .2s;
  }
  .nav-network-link:hover,
  .nav-network-link:focus-visible { opacity: 1; background: color-mix(in srgb, currentColor 12%, transparent); }
  .nav-network-link:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
  /* A long shop name on a crowded row: the network's name gives way first,
     to "Marketplace" and then to its icon (public-nav.js), rather than
     pushing the header onto a second row. The full name stays in the link. */
  .nav-network-label { max-width: 15rem; overflow: hidden; text-overflow: ellipsis; }
  .nav-network.is-short .nav-network-label,
  .nav-network.is-icon .nav-network-label {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .nav-network.is-short .nav-network-short { display: inline; }
  .nav-network.is-icon .nav-network-link { padding: .3rem .55rem !important; }
}
@media (min-width: 769px) and (pointer: coarse) {
  .nav-network-link { min-height: 44px; }
}

/* ── Mid-basket ─────────────────────────────────────────────
   A shopper part-way through a basket built across several shops. The link
   says so as well as where it goes, so it looks like a thing in progress
   rather than a second way to leave. */
.nav-network-link.has-run {
  opacity: 1;
  border-style: solid;
  border-color: currentColor;
  /* The tagline's ink, which the theme keeps readable on the bar it sits on
     (themeReadableAccents(), 6.3); plain gold was not, on a light bar. */
  color: var(--nav-tag-top, var(--gold-light)) !important;
}
.site-nav.scrolled .nav-network-link.has-run { color: var(--nav-tag, var(--gold)) !important; }


/* ══════════════════════════════════════════════════════════════
   The nav, when a shop has grown
   ══════════════════════════════════════════════════════════════ */

/* A 2rem gap between eleven items is 352px of nothing, on a row that had run
   out of room. Tighter, and nothing breaks mid-phrase: "Gift Cards" and
   "Custom Orders" were each wrapping onto two lines, which is what made the
   header three rows tall. */
.nav-links { gap: 1.25rem; flex-wrap: wrap; }
.nav-links > li { white-space: nowrap; }

/* ── The More group ── */
.nav-more { position: relative; }
.nav-more-btn {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  /* The same size, weight, case and spacing as the links beside it: fixed
     values here made "More" bold beside a light "Shop" in every family that
     changes the links (2026-10-12). */
  font-size: var(--nav-size, .88rem);
  font-weight: var(--nav-weight, 700);
  letter-spacing: var(--nav-tracking, .5px);
  text-transform: var(--nav-transform, none);
  /* The same ink as the links beside it. Fixed gold vanished on a solid
     light header. */
  color: var(--nav-link-top, rgba(232, 201, 122, 0.82));
  cursor: pointer;
  transition: color var(--dur);
}
.site-nav.scrolled .nav-more-btn { color: var(--nav-link, var(--text)); }
/* The hover ink is the tagline's, which the theme keeps readable on the bar
   it sits on (themeReadableAccents(); pass 4, 6.3) -- fixed gold was 2.51:1
   on a light bar. */
.nav-more-btn:hover { color: var(--nav-tag-top, var(--gold-light)); }
.site-nav.scrolled .nav-more-btn:hover { color: var(--nav-tag, var(--gold)); }
.nav-more-btn:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; border-radius: 4px; }
.nav-more-btn svg { transition: transform var(--dur) var(--ease); }
.nav-more-btn[aria-expanded="true"] svg { transform: rotate(180deg); }

.nav-more-panel {
  display: none;
  position: absolute;
  top: calc(100% + .75rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 60;
  min-width: 13rem;
  padding: .4rem;
  list-style: none;
  border-radius: 12px;
  /* The bar's own surface and ink (pass 4, 6.3). It was a fixed cream panel
     with the theme's --text on it, which is near white in Dark Modern: the
     menu read nothing. The pair is one the theme already keeps at 4.5:1 in
     every family (themeReadableSurfaces(), --nav-bg / --nav-link). */
  border: 1px solid color-mix(in srgb, var(--nav-link, var(--text)) 16%, transparent);
  background: var(--nav-bg, rgba(253, 248, 242, 0.98));
  backdrop-filter: blur(14px);
  box-shadow: 0 12px 34px var(--shadow);
}
.nav-more-panel.open { display: block; }
.nav-more-panel > li { white-space: nowrap; }
.nav-more-panel a {
  display: block;
  padding: .55rem .8rem;
  border-radius: 8px;
  font-size: .85rem;
  color: var(--nav-link, var(--text)) !important;
}
.nav-more-panel a:hover,
.nav-more-panel a:focus-visible { background: color-mix(in srgb, var(--nav-link, var(--text)) 11%, transparent); }
.nav-more-panel a:focus-visible { outline: 2px solid var(--nav-tag, var(--gold)); outline-offset: -2px; }
.nav-more-panel a[aria-current="page"] { color: var(--nav-tag, var(--gold)) !important; }
/* The underline animation belongs to the row, not to a dropdown. */
.nav-more-panel a::after { display: none !important; }

@media (max-width: 768px) {
  /* Inside the drawer the whole list is already open, so the group is too:
     flattened into the column it sits in, with the button out of the way.
     A nested dropdown inside a dropdown is a menu nobody can operate with a
     thumb. */
  .nav-more-btn { display: none; }
  .nav-more-panel {
    display: block;
    position: static;
    transform: none;
    min-width: 0;
    padding: 0;
    border-radius: 0;
    background: none;
    backdrop-filter: none;
    box-shadow: none;
  }
  /* Matching the drawer's own links, not the dropdown's: see "The header on
     a phone" below. */
}


/* ══════════════════════════════════════════════════════════════
   The header on a phone
   ══════════════════════════════════════════════════════════════
   One row, the way a phone header reads: the menu button on the left, the
   shop's name in the middle, the cart on the right. Everything else is in the
   menu below the bar.

   What it replaced: the button on the right, no cart in the bar at all, and a
   menu panel painted a fixed cream whatever the theme -- so on Dark Modern the
   links, in the theme's light text, sat on cream and could barely be read.
   Inside it the rows were centred, indented and pill-shaped by turns. The
   panel now takes the theme's own surface and text, and every row is the
   same: left-aligned, full width, 48px tall.

   A header that floats over a hero picture goes solid while the menu is open,
   so the menu hangs from a bar rather than from a picture. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.nav-basket { display: none; }
.nav-toggle .nav-toggle-close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-close { display: block; }
.nav-backdrop { display: none; }

@media (max-width: 768px) {
  .site-nav,
  .site-nav.scrolled { padding: .4rem 0; }
  .site-nav .nav-inner {
    display: grid;
    grid-template-columns: 48px minmax(0, 1fr) 48px;
    align-items: center;
    gap: 0 .5rem;
    padding: .15rem max(.75rem, env(safe-area-inset-right, 0px)) .15rem max(.75rem, env(safe-area-inset-left, 0px));
  }

  .nav-toggle {
    grid-column: 1; grid-row: 1; justify-self: start;
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; min-width: 44px; min-height: 44px;
    padding: 0; border-radius: 10px;
  }
  .nav-logo {
    grid-column: 2; grid-row: 1; justify-self: center;
    align-items: center; text-align: center;
    min-width: 0; max-width: 100%;
  }
  .nav-logo .logo-name { font-size: 1.2rem; line-height: 1.15; overflow-wrap: anywhere; }
  .nav-logo .logo-tag {
    display: block; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-size: .68rem;
  }
  .nav-logo-img,
  .site-nav.scrolled .nav-logo-img { height: auto; max-height: 40px; max-width: 100%; }

  .nav-basket {
    grid-column: 3; grid-row: 1; justify-self: end;
    position: relative;
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; border-radius: 10px;
    color: var(--nav-ink-top, #fff);
    transition: color var(--dur);
  }
  .site-nav.scrolled .nav-basket,
  .site-nav.menu-open .nav-basket { color: var(--nav-ink, var(--dark)); }
  .nav-basket-count { position: absolute; top: 2px; right: 0; }
  .nav-basket-count.is-zero { display: none; }
  .nav-toggle:focus-visible,
  .nav-basket:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }

  .site-nav.menu-open { background: var(--nav-bg, var(--warm-white)); box-shadow: none; }
  .site-nav.menu-open .nav-logo .logo-name,
  .site-nav.menu-open .nav-toggle { color: var(--nav-ink, var(--dark)); }
  .site-nav.menu-open .nav-logo .logo-tag { color: var(--nav-tag, var(--gold)); }

  /* ── The menu ── */
  .nav-links {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: stretch; flex-wrap: nowrap;
    gap: 0;
    max-width: none;
    max-height: calc(100vh - var(--nav-h, 64px) - var(--closed-bar-h, 0px));
    max-height: calc(100dvh - var(--nav-h, 64px) - var(--closed-bar-h, 0px));
    overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain;
    margin: 0;
    padding: .35rem 0 calc(.75rem + env(safe-area-inset-bottom, 0px));
    list-style: none;
    background: var(--warm-white);
    border-top: 1px solid var(--border);
    box-shadow: 0 18px 40px rgba(0, 0, 0, .22);
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .nav-links.open { display: flex; }
  .nav-links > li { white-space: normal; }
  .nav-links a,
  .nav-links .nav-more-panel a {
    display: flex !important; align-items: center; gap: .5rem;
    min-height: 48px;
    padding: .55rem max(1.25rem, env(safe-area-inset-left, 0px)) !important;
    border: 0; border-radius: 0; opacity: 1;
    font-size: 1rem !important; font-weight: 600 !important;
    letter-spacing: normal; text-transform: none;
    color: var(--text) !important;
    background: none;
  }
  .nav-links a::after { display: none !important; }
  .nav-links a:hover,
  .nav-links a:focus-visible { background: var(--cream); color: var(--text) !important; }
  .nav-links a:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
  .nav-links a[aria-current="page"] { color: var(--gold) !important; }
  /* Three groups: what the shop has, then you -- saved, signing in -- and
     last, apart, the network the shop belongs to (pass 4, 6.4). */
  .nav-links > .nav-more + li { margin-top: .35rem; padding-top: .35rem; border-top: 1px solid var(--border); }
  .nav-links > .nav-network { margin-top: .5rem; padding-top: .5rem; border-top: 1px solid var(--border); }
  .nav-links .nav-network-link { flex-direction: column; align-items: flex-start !important; gap: .1rem !important; }
  .nav-links .nav-network-caption {
    position: static; width: auto; height: auto; overflow: visible; clip: auto; clip-path: none;
    font-size: .75rem; font-weight: 600; color: var(--text-light);
  }
  .nav-links .nav-network-link.has-run { color: var(--text) !important; }
  /* One icon size down the menu: the heart is 20px, so these are too. */
  .nav-links .nav-account-link svg,
  .nav-links .nav-admin-link svg,
  .nav-links .nav-network-name svg { width: 20px; height: 20px; }
  /* In the bar already. */
  .nav-links .nav-cart-item,
  .nav-links .nav-home-item { display: none; }
  .nav-links .nav-saved-link { justify-content: flex-start; }
  .nav-links .nav-account-link svg,
  .nav-links .nav-admin-link svg { margin-right: 0 !important; }

  .nav-backdrop:not([hidden]) {
    display: block;
    position: fixed; inset: 0; z-index: 899;
    background: rgba(0, 0, 0, .45);
  }
  html.nav-menu-open,
  html.nav-menu-open body { overflow: hidden; }
}
@media (max-width: 340px) {
  .nav-logo .logo-name { font-size: 1.08rem; }
  .nav-logo .logo-tag { font-size: .64rem; }
}


/* ── The footer as a site map ────────────────────────────────
   The header now puts everything except browsing behind More, which is right
   for a header and wrong for the bottom of a page: down here there is room,
   and somebody who has scrolled this far is looking for something specific.

   auto-fit rather than a fixed count, because how many groups there are
   depends on what the owner switched on -- a shop with no accounts and no
   marketplace has two, and two columns centred is the right answer for it. */
.footer-map {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, max-content));
  justify-content: center;
  gap: 1.6rem 3.5rem;
  margin-bottom: 1.6rem;
  text-align: left;
}
.footer-map-col h3 {
  margin: 0 0 .6rem;
  font-family: inherit;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  /* Token, not fixed white: a light-footer family (Boutique, Minimal,
     Artist, Tag Sale, Bold) paints this band pale and a hard white column
     heading disappears into it. */
  color: var(--footer-ink-dim, rgba(255, 255, 255, 0.55));
}
.footer-map-col ul { list-style: none; margin: 0; padding: 0; }
.footer-map-col li + li { margin-top: .35rem; }
.footer-map-col a {
  font-size: .85rem;
  color: var(--footer-link, rgba(255, 255, 255, 0.55));
  transition: color var(--dur);
}
.footer-map-col a:hover { color: var(--gold-light); }

@media (pointer: coarse) {
  /* The same 44px the rest of the footer's links got. */
  .footer-map-col a { display: inline-flex; align-items: center; min-height: 44px; }
  .footer-map-col li + li { margin-top: 0; }
}

@media (max-width: 560px) {
  /* One column, and centred like the rest of the footer. A phone has no room
     for two columns of link text without the longer labels wrapping. */
  .footer-map { grid-template-columns: 1fr; gap: 1.4rem; text-align: center; }
}

/* ── The product quick view as a bottom sheet, on phones ──────────
   Under 640px the centred modal becomes a drawer that rises from the bottom
   edge and follows the finger (assets/js/sheet.js drives --sheet-y and
   --sheet-progress). Nothing inside the box changes: same picture, options,
   price and buttons. Wider than a phone these rules do not apply and the
   modal is what it was. */
.sheet-grip { display: none; }
@media (max-width: 640px) {
  .modal-overlay.is-sheet {
    align-items: flex-end;
    padding: 0;
    transition: none;
  }
  .modal-overlay.is-sheet.open { opacity: calc(1 - var(--sheet-progress, 0)); }
  .modal-overlay.is-sheet .modal {
    width: 100%;
    max-width: none;
    height: auto;
    max-height: 92vh;
    max-height: 92dvh;
    grid-template-columns: 1fr;
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -14px 44px rgba(30, 18, 12, .28);
    overscroll-behavior: contain;
    /* Off screen until the spring brings it up; the variable is the whole
       animation, so there is no transition to fight the finger. */
    transform: translate3d(0, var(--sheet-y, 100%), 0);
    transition: none;
    will-change: transform;
  }
  .modal-overlay.is-sheet .sheet-grip {
    display: flex;
    justify-content: center;
    position: sticky;
    top: 0;
    z-index: 3;
    padding: .6rem 0 .4rem;
    background: var(--warm-white);
    touch-action: none;
    cursor: grab;
  }
  .modal-overlay.is-sheet.is-dragging .sheet-grip { cursor: grabbing; }
  .sheet-grip span {
    width: 42px;
    height: 5px;
    border-radius: 3px;
    /* The text colour, faint: a fixed dark grip vanished on a dark family. */
    background: var(--text);
    opacity: .28;
  }
  .modal-overlay.is-sheet .modal-img-pane {
    border-radius: 0;
    height: min(40vh, 340px);
  }
  .modal-overlay.is-sheet .modal-close { top: .55rem; right: .6rem; z-index: 4; }
  .modal-overlay.is-sheet .modal-body {
    padding-bottom: calc(1.25rem + env(safe-area-inset-bottom, 0px));
  }
}
@media (prefers-reduced-motion: reduce) {
  .modal-overlay, .modal { transition: none; }
  .modal { transform: none; }
}

/* Opening hours inside a contact card: days left, hours right. */
.contact-hours { display: grid; grid-template-columns: auto auto; justify-content: center; gap: .15rem .9rem; margin: .3rem 0 0; font-size: .92rem; }
.contact-hours dt { font-weight: 600; text-align: right; }
.contact-hours dd { margin: 0; text-align: left; }
.contact-card .contact-note { font-size: .85rem; opacity: .85; }

/* ── The shop's sign-in pages (pass 4, phase 8): sign-in.php, forgot-password.php,
   customer-reset.php. One card in the shop's own look. ── */
.auth-wrap { max-width: 460px; margin: 0 auto; padding: 0 1rem 4.5rem; }
.auth-card {
  background: var(--warm-white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2.2rem 2.2rem 2.4rem;
  box-shadow: 0 4px 32px var(--shadow-sm);
}
.auth-card h1 { font-family: var(--ff-head); font-size: 1.7rem; color: var(--heading-ink, var(--dark)); margin: 0 0 .4rem; }
.auth-lede { color: var(--text-light); font-size: .92rem; line-height: 1.55; margin: 0 0 1.4rem; }
.auth-form .form-group { margin-bottom: 1.1rem; }
.auth-form label { display: block; color: var(--text); font-size: .84rem; font-weight: 700; margin-bottom: .4rem; }
.auth-form input[type="text"], .auth-form input[type="email"], .auth-form input[type="password"] {
  width: 100%; box-sizing: border-box; min-height: 44px;
  border: 1.5px solid var(--border); background: var(--cream); color: var(--heading-ink, var(--dark));
  border-radius: var(--radius-sm); padding: .7rem 1rem; font: inherit; font-size: .95rem;
}
.auth-form input:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-color: var(--gold); }
.auth-btn {
  width: 100%; min-height: 48px; padding: .8rem 1rem; border: 0; border-radius: var(--radius-sm);
  background: var(--gold); color: var(--on-gold, #fff); font: inherit; font-size: 1rem; font-weight: 700; cursor: pointer;
}
.auth-btn:hover { filter: brightness(0.95); }
.auth-btn:focus-visible, .auth-choice-btn:focus-visible { outline: 3px solid var(--heading-ink, var(--dark)); outline-offset: 2px; }
.auth-btn[disabled] { opacity: .6; cursor: default; }
.auth-btn-outline { background: transparent; color: var(--heading-ink, var(--dark)); border: 1.5px solid var(--border); }
.auth-or { display: flex; align-items: center; gap: .8rem; margin: 1.3rem 0 1rem; color: var(--text-light); font-size: .8rem; }
.auth-or::before, .auth-or::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.auth-note { font-size: .82rem; color: var(--text-light); margin: .45rem 0 0; min-height: 1em; }
.auth-links { margin: 1.4rem 0 0; font-size: .88rem; color: var(--text-light); text-align: center; line-height: 2; }
.auth-links a { color: var(--eyebrow-ink, var(--gold)); font-weight: 600; }
.auth-error, .auth-ok { border-radius: var(--radius-sm); padding: .75rem 1rem; font-size: .9rem; line-height: 1.5; margin: 0 0 1.2rem; }
.auth-error { background: #fef2f2; border: 1px solid #fca5a5; color: #991b1b; }
.auth-ok { background: #f0fdf4; border: 1px solid #86efac; color: #14532d; }
.auth-choice { display: grid; gap: .8rem; }
.auth-choice-btn {
  display: block; width: 100%; min-height: 64px; text-align: left; cursor: pointer;
  background: var(--cream); color: var(--heading-ink, var(--dark));
  border: 1.5px solid var(--border); border-radius: var(--radius-sm); padding: .9rem 1.1rem; font: inherit;
}
.auth-choice-btn:hover { border-color: var(--gold); }
.auth-choice-btn strong { display: block; font-size: 1rem; }
.auth-choice-btn span { display: block; font-size: .86rem; color: var(--text-light); margin-top: .15rem; }
@media (max-width: 480px) { .auth-card { padding: 1.6rem 1.2rem 1.8rem; } }
/* The account page's Signing in card (pass 4, phase 8B). */
.ca-note { font-size: .9rem; line-height: 1.55; color: var(--text-light); margin: 0 0 1rem; }
.ca-passkeys { list-style: none; margin: 0 0 1rem; padding: 0; }
.ca-passkeys li { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: .6rem 0; border-bottom: 1px solid var(--border); }
.ca-passkeys small { display: block; color: var(--text-light); font-size: .8rem; }
.ca-passkeys button { min-height: 44px; }
.ca-passkey-add, .ca-passkey-confirm { display: grid; gap: .5rem; max-width: 360px; }
.ca-passkey-add input, .ca-passkey-confirm input { min-height: 44px; border: 1.5px solid var(--border); background: var(--cream); color: var(--heading-ink, var(--dark)); border-radius: var(--radius-sm); padding: .6rem .9rem; font: inherit; }
.ca-passkey-add label, .ca-passkey-confirm label { font-size: .84rem; font-weight: 700; color: var(--text); }

/* ── A parcel's journey (pass 4, phase 15; includes/tracking-journey.php) ──
   Places are areas; solid legs join real scans, the dashed curve is the part
   nobody knows. The motion is a line drawing itself in and a slow pulse on
   the last scan, and neither happens under reduced motion. */
.tj { margin: 1.1rem 0 .6rem; --tj-accent: currentColor; --tj-ink: currentColor; --tj-paper: #fff; }
.tj-map { display: block; width: 100%; height: auto; border-radius: 10px;
  background: color-mix(in srgb, var(--tj-ink) 4%, transparent); }
.tj-grid polyline { fill: none; stroke: color-mix(in srgb, var(--tj-ink) 9%, transparent); stroke-width: 1; }
.tj-done { fill: none; stroke: var(--tj-accent); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 100; stroke-dashoffset: 0; }
.tj-ahead { fill: none; stroke: color-mix(in srgb, var(--tj-ink) 45%, transparent); stroke-width: 2; stroke-dasharray: 4 7; stroke-linecap: round; }
.tj-origin { fill: var(--tj-paper); stroke: var(--tj-accent); stroke-width: 3; }
.tj-dest { fill: none; stroke: var(--tj-ink); stroke-width: 2; }
.tj-dest-core { fill: var(--tj-ink); }
.tj-stop { fill: var(--tj-accent); opacity: .65; }
.tj-now { fill: var(--tj-accent); stroke: var(--tj-paper); stroke-width: 2; }
.tj-now-ring { fill: var(--tj-accent); opacity: .3; }
.tj-label { font-size: 13px; font-weight: 700; fill: var(--tj-ink);
  paint-order: stroke; stroke: var(--tj-paper); stroke-width: 4px; stroke-linejoin: round; }
.tj figcaption { margin-top: .5rem; font-size: .82rem; line-height: 1.5; opacity: .85; }
/* The drawing scales with its box; its words must not shrink with it. At
   phone width the 640-unit map is about 340px wide, so labels are set in
   larger units to stay near 12px. */
@media (max-width: 560px) {
  .tj-label { font-size: 23px; stroke-width: 6px; }
  .tj-done { stroke-width: 5; }
  .tj-ahead { stroke-width: 3; }
}
@media (prefers-reduced-motion: no-preference) {
  .tj-done { animation: tj-draw 1.6s ease-out both; }
  .tj-now-ring { animation: tj-pulse 2.4s ease-out infinite; transform-box: fill-box; transform-origin: center; }
}
@keyframes tj-draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes tj-pulse { 0% { opacity: .5; transform: scale(.6); } 80%, 100% { opacity: 0; transform: scale(1.9); } }
/* The line of stops, when there is no honest map to draw. */
.tj-line { list-style: none; display: flex; margin: 0; padding: 0; }
.tj-line li { flex: 1; position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; font-size: .86rem; line-height: 1.35; }
.tj-line li::before { content: ''; position: absolute; top: 8px; right: 50%; width: 100%; height: 2px;
  background: color-mix(in srgb, var(--tj-ink) 25%, transparent); }
.tj-line li:first-child::before { display: none; }
.tj-dot { position: relative; z-index: 1; width: 18px; height: 18px; border-radius: 50%; border: 3px solid var(--tj-accent); background: var(--tj-paper); }
.tj-line-now .tj-dot { background: var(--tj-accent); }
.tj-line-dest .tj-dot { border-color: var(--tj-ink); }
.tj-line b { margin-top: .35rem; }
.tj-line small { opacity: .75; font-size: .76rem; }
.os-status-card .tj { --tj-accent: var(--eyebrow-ink, var(--gold)); --tj-ink: var(--text); --tj-paper: var(--warm-white); }
.os-scans { margin: .4rem 0 1rem; font-size: .88rem; }
.os-scans summary { cursor: pointer; font-weight: 700; min-height: 44px; display: flex; align-items: center; }
.os-scan-list { list-style: none; margin: .2rem 0 0; padding: 0; display: grid; gap: .45rem; }
.os-scan-list li { display: grid; grid-template-columns: 9.5rem 1fr; gap: .1rem .8rem; }
.os-scan-list time { color: var(--text-light); font-variant-numeric: tabular-nums; }
.os-scan-list small { grid-column: 2; color: var(--text-light); }
@media (max-width: 520px) { .os-scan-list li { grid-template-columns: 1fr; } .os-scan-list small { grid-column: 1; } }

/* ══ New-shop polish (2026-10-12) ═══════════════════════════════════════════
   From a real first shop opened on the Minimal look (Shoreline Handyman): the
   page has to hold together whatever sections are on, whatever a merchant has
   or has not written yet, in every family. Each rule says what it fixed.
   Placed last so it settles the cascade without raising specificity elsewhere. */

/* Small words never drop below about 11px. Minimal's eyebrow scale took the
   header tagline to 7px and the footer's to 9px. */
.nav-logo .logo-tag { font-size: max(.7rem, calc(.78rem * var(--eyebrow-scale, 1))); }
.footer-tagline     { font-size: max(.72rem, calc(1rem * var(--eyebrow-scale, 1))); }
.hero-eyebrow       { font-size: max(.75rem, calc(1.5rem * var(--eyebrow-scale, 1))); }

/* A plain banner (no picture, no video) is a heading and its buttons: it does
   not need most of a screen, and the empty space read as a page still loading. */
.hero.hero--plain { min-height: min(var(--hero-min-h, 100vh), 62vh); }
/* On a phone it is as tall as its words, below a header that floats over it (--nav-overlap is 0 for a solid bar). */
@media (max-width: 760px) { .hero.hero--plain { min-height: 0; padding-top: calc(var(--nav-overlap, 0px) + 3rem * var(--space, 1)); padding-bottom: calc(3rem * var(--space, 1)); } }

/* One or two products: centred cards at a readable width. */
.products-grid.products-grid--few { grid-template-columns: repeat(auto-fit, minmax(240px, 360px)); justify-content: center; }

/* About without a photo: the story alone, centred at reading width. */
.about-inner.about-inner--text { grid-template-columns: minmax(0, 46rem); justify-content: center; text-align: center; gap: 0; }
.about-inner--text .about-pillars { justify-content: center; text-align: left; }

/* Custom orders: the tags read on the dark band in every family (Minimal's
   accent was grey on near-black, 2.8:1), as a list without bullets; the two
   form fields stack before an email address would be cut off; and the band
   is not taller than what it holds. */
.section-custom-orders { padding-block: calc(5rem * var(--space, 1)); }
ul.event-tags { list-style: none; padding: 0; }
.event-tag {
  color: rgba(255,255,255,.9);
  background: rgba(255,255,255,.07);
  border-color: rgba(255,255,255,.24);
  border-color: color-mix(in srgb, var(--gold-light) 40%, rgba(255,255,255,.22));
}
.quick-form .form-row { grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); column-gap: 1rem; row-gap: 0; }
.btn-block { width: 100%; justify-content: center; }

/* The wholesale card: the soft card every other panel is, not a hairline in
   the accent (Minimal's was a dark rule); its button readable, not grey on black. */
.wholesale-card { border-color: var(--border); box-shadow: 0 4px 20px var(--shadow-sm); }
/* (A dark button's label: includes/theme.php, themeStyleTag(), gives a
   colourless accent the plain readable ink instead of a just-readable grey.) */

/* Contact icons are line drawings now (contact.php): the theme's accent. */
.contact-card-icon { display: flex; justify-content: center; color: var(--gold); line-height: 0; }

/* The footer reads as one centred block: name, tagline, site map, policies.
   Policy links are small print in the footer's own ink; a blanket
   `.site-footer a` rule had painted them in the accent, darker than the links
   above them. On a phone they wrap as a centred row instead of an uneven grid. */
.footer-map { text-align: center; }
.site-footer .footer-policy-nav a { color: var(--footer-ink-dim, rgba(255,255,255,.55)); }
.site-footer .footer-policy-nav a:hover { color: var(--footer-tag, var(--gold-light)); }
@media (max-width: 768px) {
  .footer-policy-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: .4rem 1.25rem; max-width: none; }
}

/* With no tagline under it, the shop name still has room above the site map. */
.site-footer .footer-logo + .footer-map, .site-footer .footer-logo + nav { margin-top: 1.4rem; }
