/* Smithllery — light, product-first commerce system.
   Porcelain ground, blush + champagne pastel bands, gold and near-black from the
   logo artwork, one vibrant rose for offers. Photography does the talking. */

/* Client rule: "Wherever SMITHLLERY comes we use font geometric 415 blk bt".
   Licensed Bitstream face — see assets/fonts/README.md. Until the file is
   dropped in, League Spartan Black stands in. */
/* UNCOMMENT once assets/fonts/geometric-415-blk-bt.woff2 is in place. It is left
   off only so the demo does not 404 twice on every page load for a file we do
   not have yet; the family stays first in --wordmark below, so anyone with the
   font installed locally already gets the real thing. */
/*
@font-face {
  font-family: "Geometric 415 Blk BT";
  src: url("../fonts/geometric-415-blk-bt.woff2") format("woff2"),
       url("../fonts/geometric-415-blk-bt.woff") format("woff");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}
*/

:root {
  /* grounds — porcelain, not beige */
  --bg: #fffdfc;
  --surface: #ffffff;
  --tint: #fbf0f1;          /* pastel blush */
  --tint-2: #f6e5e8;
  --champagne: #f8f3e9;     /* pastel champagne */
  --photo-ground: #ffffff;   /* white behind every product photo (30 Sep; was blush #f3ecec) */

  /* ink */
  --ink: #17140f;
  --ink-2: #4b443b;
  --muted: #726a5e;   /* passes AA on porcelain, blush and champagne */

  /* brand — from the logo artwork: gold on near-black deep green */
  --deep: #101a10;
  --deep-hi: #1d2d1c;
  --gold: #8b6413;          /* accessible gold for text on light grounds */
  --gold-soft: #c9a24a;     /* decorative gold — rules, icons */
  --gold-bright: #efc350;   /* gold as it sits on the deep grounds */

  /* vibrant — offers, sale prices, commerce signals */
  --rose: #d6336c;
  --rose-hi: #b82a5b;
  --sale: var(--rose);

  --line: rgba(23, 20, 15, 0.12);
  --line-2: rgba(23, 20, 15, 0.24);
  --line-gold: rgba(201, 162, 74, 0.45);

  /* Palmonas runs one family for everything — measured Nunito Sans on 1419
     elements, no serif anywhere. --serif is kept as an alias so the many rules
     that reference it keep working. */
  --sans: "Nunito Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --wordmark: "Geometric 415 Blk BT", "League Spartan", "Nunito Sans", ui-sans-serif, system-ui, sans-serif;
  /* Hero display only. Cormorant is the jewellery/luxury pairing; the body
     stays Nunito Sans so this reads as an accent, not a second brand voice. */
  --display: "Cormorant Garamond", Georgia, "Times New Roman", serif;

  --gutter: clamp(1.25rem, 4vw, 3rem);
  --max: 1400px;
  --bar-h: 2.1rem;
  --header-h: 4.5rem;
  --top: calc(var(--bar-h) + var(--header-h));
  --radius: 14px;
  --radius-sm: 10px;
  /* ---- motion tokens ----
     One system, reused. Durations in ms, offsets in px, mirrored in motion.js
     so CSS and GSAP animate to the same numbers. No bounce/elastic anywhere:
     the brand lane here is restrained, not playful. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);   /* entrances */
  --ease-emph: cubic-bezier(0.16, 1, 0.30, 1);
  --ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* exits, faster */
  --d-micro: 160ms;
  --d-ui: 220ms;
  --d-pop: 280ms;
  --d-section: 620ms;
  --d-modal: 360ms;         /* lightbox open; closes on --d-pop */
  --d-tiles: 520ms;         /* page-to-page tile dissolve, both halves (vt.js) */
  --o-sm: 8px;
  --o-md: 16px;
  --o-lg: 24px;
  --shadow: 0 18px 40px -28px rgba(23, 20, 15, 0.45);

  --fs-body: clamp(0.88rem, 0.86rem + 0.1vw, 0.94rem);
  --fs-h2: clamp(1.1rem, 1.02rem + 0.28vw, 1.32rem);
  --fs-hero: clamp(1.8rem, 1rem + 3.5vw, 3.8rem);

}

/* ---------- base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); color-scheme: light; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--fs-body);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
body.menu-open { overflow: hidden; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input, select { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--deep); outline-offset: 3px; }
[hidden] { display: none !important; }
::selection { background: var(--tint-2); }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip { position: absolute; left: 1rem; top: -200px; z-index: 300; background: var(--deep); color: #fff; padding: 0.7rem 1.1rem; font-weight: 600; }
.skip:focus { top: 1rem; }
.container { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
section { scroll-margin-top: calc(var(--top) + 1rem); }

.eyebrow { display: block; margin: 0 0 0.5rem; font-size: 0.64rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
.eyebrow::before { content: none; }
.section-head[style*="center"] .eyebrow { justify-content: center; }
.section-title { margin: 0; font-weight: 400; font-size: var(--fs-h2); line-height: 1.3; letter-spacing: 0.05em; text-transform: uppercase; }
.section-title em, .hero__title em { font-style: normal; color: var(--gold); }
.section-head { position: relative; display: flex; flex-wrap: wrap; align-items: end; justify-content: center; text-align: center; gap: 1rem; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
/* Was absolutely positioned, which overlapped the centred heading at some
   widths. Now it flows on its own centred line and cannot collide. */
/* align-items:end means "right" once the direction is column, which shoved the
   eyebrow and the Shop-all link to the right edge. Centre both. */
.section-head { flex-direction: column; align-items: center; }
.section-head--split { flex-direction: row; align-items: end; }
.section-head .link-arrow { margin-top: 0.1rem; }
.section-head--split { justify-content: space-between; text-align: left; }
.lede { max-width: 40rem; margin: 0.8rem 0 0; color: var(--ink-2); }

/* split text (motion.js) */
.w-mask { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.1em; margin-bottom: -0.1em; }
.w-in { display: inline-block; will-change: transform; }

/* ---------- icons: Solar (Iconify) ---------- */
.i {
  display: inline-block; flex: none; width: 1.25em; height: 1.25em;
  background-color: currentColor;
  -webkit-mask: var(--i) center / contain no-repeat;
  mask: var(--i) center / contain no-repeat;
}
.i-bag { --i: url("../img/icons/bag-4-linear.svg"); }
.i-heart { --i: url("../img/icons/heart-linear.svg"); }
.i-menu { --i: url("../img/icons/hamburger-menu-linear.svg"); }
.i-close { --i: url("../img/icons/close-circle-linear.svg"); }
.i-arrow { --i: url("../img/icons/arrow-right-linear.svg"); }
.i-arrow-left { --i: url("../img/icons/arrow-left-linear.svg"); }
.i-search { --i: url("../img/icons/magnifer-linear.svg"); }
.i-stars { --i: url("../img/icons/stars-minimalistic-linear.svg"); }
.i-shield { --i: url("../img/icons/shield-check-linear.svg"); }
.i-delivery { --i: url("../img/icons/delivery-linear.svg"); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.6rem;
  min-height: 3rem; padding: 0.85rem 1.6rem; border: 1px solid transparent; border-radius: 999px;
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  transition: background-color 0.35s var(--ease), color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.btn .i { transition: transform 0.45s var(--ease); }
.btn:hover .i { transform: translateX(4px); }
.btn--primary { background: var(--deep); color: #fff; }
.btn--primary:hover { background: var(--deep-hi); }
.btn--ghost { border-color: var(--line-2); color: var(--ink); }
.btn--ghost:hover { border-color: var(--deep); color: var(--deep); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn:disabled:hover { background: var(--deep); }
.btn--block { width: 100%; }
.link-arrow { display: inline-flex; align-items: center; gap: 0.5rem; padding-block: 0.4rem; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold); }
.link-arrow .i { transition: transform 0.45s var(--ease); }
.link-arrow:hover .i { transform: translateX(4px); }

/* ---------- header ---------- */
.site-header { position: sticky; top: 0; z-index: 60; background: var(--surface); border-bottom: 1px solid var(--line); }
.demo-bar {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  height: var(--bar-h); margin: 0; padding-inline: var(--gutter);
  background: var(--deep); color: #fff;
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.04em; white-space: nowrap; overflow: hidden;
}
.demo-bar__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--gold-bright); flex: none; }
/* Header (30 Sep, after denimtears.com): three columns, the outer two equal,
   so the wordmark sits in the true middle with air either side of it. */
.nav { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 1rem; height: var(--header-h); }
.nav__left { display: flex; align-items: center; gap: 0.1rem; justify-self: start; min-width: 0; }
.nav .wordmark { justify-self: center; align-items: center; }
.nav .wordmark__name { align-self: center; }
.nav .wordmark__tag::before, .menu__top .wordmark__tag::before { display: none; }
/* Lockup follows the client's artwork: a gold rule, "Bejewelled with", then
   SMITHLLERY in the mandated geometric black. */
.wordmark { display: flex; flex-direction: column; justify-content: center; line-height: 1; flex: none; }
.wordmark__tag {
  display: flex; align-items: center; gap: 0.45rem; margin-bottom: 0.3rem;
  font-size: 0.56rem; font-weight: 500; letter-spacing: 0.15em; color: var(--gold);
  white-space: nowrap;
}
.wordmark__tag::before { content: ""; width: 1.5rem; height: 1px; background: var(--gold-soft); flex: none; }
.wordmark__name {
  /* hug the letters: stretched to the tagline's width, the box misled the
     home hero's flight into the header (motion.js heroStack measures it) */
  align-self: flex-start;
  font-family: var(--wordmark); font-weight: 900; font-size: 1.3rem;
  letter-spacing: 0.055em; text-transform: uppercase;
}
/* The owner's gold logo (9 Oct): the header and menu draw the logo's own
   "Bejewelled With" rule and SMiTHLLERY lettering (logo-tag / logo-name, cut by
   scripts/process-logo.py) as masks filled with gold: deep on light grounds,
   bright over the home hero and in the footer. The words stay in the markup
   for screen readers, pushed out of the box. The name is 1em tall, so the
   font-size rules (compact header) still size it; the rule matches its width. */
:root {
  --logo-gold: linear-gradient(180deg, #c99a3f 0%, #a2741f 55%, #7f5a12 100%);
  --logo-gold-bright: linear-gradient(180deg, #fff0bf 0%, #f2c75a 42%, #c88d2b 100%);
}
.wordmark__name, .wordmark__tag {
  display: block; overflow: hidden; white-space: nowrap; text-indent: 110%; letter-spacing: 0;
  background: var(--logo-gold);
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
.wordmark__name { height: 1em; width: calc(1em * 818 / 104);
  -webkit-mask-image: url("../img/brand/logo-name.webp?v=2"); mask-image: url("../img/brand/logo-name.webp?v=2"); }
/* the final artwork (13 Oct) ends the rule flush with the name's right edge */
.wordmark__tag { align-self: flex-end; font-size: 1.3rem; width: calc(1em * 805 / 104); height: calc(1em * 49 / 104); margin-bottom: calc(1em * 16 / 104);
  -webkit-mask-image: url("../img/brand/logo-tag.webp?v=2"); mask-image: url("../img/brand/logo-tag.webp?v=2"); }
.wordmark__tag::before { display: none; }
.nav__links { display: flex; align-items: center; gap: clamp(1.4rem, 2.4vw, 2.2rem); }
.nav__links > a, .nav__drop-btn { position: relative; padding-block: 0.4rem; font-size: 0.9rem; font-weight: 500; letter-spacing: 0.01em; color: var(--ink-2); transition: color 0.3s; }
.nav__links a { position: relative; }
.nav__links a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; background: var(--gold); transform: scaleX(0); transform-origin: right; transition: transform 0.45s var(--ease); }
.nav__links a:hover, .nav__links a[aria-current="page"], .nav__drop-btn:hover { color: var(--ink); }
.nav__links a:hover::after, .nav__links a[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }
.nav__actions { display: flex; align-items: center; gap: 0.1rem; justify-self: end; }

/* Catalog: opens on hover (with a short grace period so a diagonal move to
   the menu doesn't close it), on click or tap, and on keyboard focus
   (app.js dropdown). The panel is a white card under the link. */
.nav__drop { position: relative; }
.nav__drop-btn { display: inline-flex; align-items: center; gap: 0.5rem; cursor: pointer; }
.chev { width: 0.4rem; height: 0.4rem; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform var(--d-ui) var(--ease); }
.nav__drop.is-open .chev { transform: translateY(1px) rotate(-135deg); }
.drop { position: absolute; top: 100%; left: -1.75rem; z-index: 5; padding-top: 0.85rem;
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity var(--d-ui) var(--ease), transform var(--d-pop) var(--ease), visibility 0s linear var(--d-pop); }
.nav__drop.is-open .drop { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
.drop__inner { display: grid; grid-template-columns: auto auto; gap: 3rem; padding: 1.5rem 1.9rem 1.6rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 26px 60px -30px rgba(14, 12, 9, 0.45); }
.drop__label { margin: 0 0 0.75rem; font-size: 0.64rem; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold); }
.drop__col { display: flex; flex-direction: column; align-items: flex-start; gap: 0.2rem; }
.drop__col a { padding-block: 0.3rem; font-size: 0.92rem; color: var(--ink-2); white-space: nowrap; }

/* Search: an icon that opens a slim bar under the header */
.search-panel { border-top: 1px solid var(--line); background: var(--surface); }
.search-panel__form { display: flex; align-items: center; gap: 0.9rem; min-height: 4rem; }
.search-panel__form .i { color: var(--muted); }
.search-panel__form input { flex: 1; min-width: 0; min-height: 3rem; border: 0; background: none; font-size: 1.02rem; }
.search-panel__form input:focus { outline: none; }
.search-panel__form input::placeholder { color: var(--muted); }
.icon-btn { position: relative; display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%; color: var(--ink); transition: background-color 0.3s, color 0.3s; }
.icon-btn:hover { background: var(--tint); color: var(--deep); }
.bag-count { position: absolute; top: 0.3rem; right: 0.2rem; display: grid; place-items: center; min-width: 1.05rem; height: 1.05rem; padding: 0 0.2rem; border-radius: 1rem; background: var(--deep); color: #fff; font-size: 0.6rem; font-weight: 700; line-height: 1; }
.menu-btn, .search-btn--phone { display: grid; }
.search-btn--wide { display: none; }
@media (min-width: 1000px) { .menu-btn, .search-btn--phone { display: none; } .search-btn--wide { display: grid; } }
@media (max-width: 999px) { .nav__links { display: none; } }
@media (max-width: 380px) { .nav .icon-btn { width: 2.35rem; } }
@media (max-width: 640px) { .demo-bar__long { display: none; } }
@media (min-width: 641px) { .demo-bar__short { display: none; } }

/* ---------- mobile menu ---------- */
/* A right-hand drawer rather than a full-screen takeover — the page stays
   visible behind it, which reads less abruptly on a phone. */
.menu {
  position: fixed; inset: 0 auto 0 0; z-index: 80;
  width: min(80vw, 22rem); overflow-y: auto;
  display: flex; flex-direction: column; padding: 0 var(--gutter) 2rem;
  background: var(--surface); box-shadow: 18px 0 48px -22px rgba(23, 20, 15, 0.45);
}
.menu__scrim { position: fixed; inset: 0; z-index: 79; background: rgba(23, 20, 15, 0.45); }
.menu__top { margin-inline: 0; }
.menu__top { display: flex; align-items: center; justify-content: space-between; height: var(--top); }
.menu__search { margin-bottom: 2rem; }
.menu__search form { position: relative; display: flex; }
.menu__search input { width: 100%; min-height: 3rem; padding: 0.7rem 3rem 0.7rem 1.1rem; border: 1px solid var(--line); border-radius: 999px; background: var(--bg); }
.menu__search button { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 2.2rem; height: 2.2rem; color: var(--muted); }
.menu__links { display: flex; flex-direction: column; gap: 0.2rem; }
.menu__links a { padding-block: 0.65rem; font-weight: 500; font-size: 1.05rem; line-height: 1.3; border-bottom: 1px solid var(--line); }
.menu__links a:last-child { border-bottom: 0; }
/* Catalog group in the phone menu (a <details>, open by default) */
.menu__group { border-bottom: 1px solid var(--line); }
.menu__group summary { display: flex; align-items: center; justify-content: space-between; padding-block: 0.65rem; font-weight: 500; font-size: 1.05rem; line-height: 1.3; cursor: pointer; list-style: none; }
.menu__group summary::-webkit-details-marker { display: none; }
.menu__group summary::after { content: ""; width: 0.45rem; height: 0.45rem; margin-right: 0.3rem; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform var(--d-ui) var(--ease); }
.menu__group[open] summary::after { transform: translateY(1px) rotate(-135deg); }
.menu__sub { display: flex; flex-direction: column; padding: 0 0 0.6rem 0.9rem; }
.menu__sub a { padding-block: 0.45rem; border-bottom: 0; font-size: 0.98rem; font-weight: 400; color: var(--ink-2); }
.menu__links a:hover { color: var(--gold); }
.menu__foot { margin: auto 0 0; color: var(--muted); font-size: 0.85rem; }

/* ---------- hero slider ---------- */
/* Full-bleed photography with the message overlaid, matching the three-slide
   banner on smithllery.com. A right-side scrim keeps white type legible over
   whatever the photograph is doing underneath — white on bare photo is not a
   contrast guarantee. */
.hero { position: relative; isolation: isolate; background: var(--deep); }
.hero__stage {
  position: relative; margin: 0; padding: 0; list-style: none;
  height: clamp(26rem, 62vh, 40rem);
}
.hero__slide {
  position: absolute; inset: 0; opacity: 0; visibility: hidden;
  display: grid; align-items: center;
}
.hero__slide.is-active { opacity: 1; visibility: visible; }
.hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; }
/* Landscape screens get the -wide slides (jewellery centre-right): a narrower
   screen crops more from the left, so the jewellery is never what goes. */
@media (min-aspect-ratio: 1001/1000) { .hero__img { object-position: 64% 50%; } }
.hero__slide::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(14, 12, 9, 0.12) 0%, rgba(14, 12, 9, 0.30) 38%, rgba(14, 12, 9, 0.68) 100%);
}
.hero__inner { position: relative; z-index: 2; display: flex; justify-content: flex-end; }
.hero__text { max-width: 38rem; text-align: right; color: #fff; }
.hero__kicker {
  margin: 0 0 0.55rem; font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--gold-bright);
}
.hero__title {
  position: relative;
  margin: 0 0 0.9rem; font-family: var(--display); font-size: var(--fs-hero);
  font-weight: 500; font-style: italic;
  /* 1.14 + the padding reserve keeps italic overhang and any tail off the
     crop edge; 1.04 clipped it. */
  line-height: 1.14; padding-bottom: 0.06em; letter-spacing: 0.015em;
  text-transform: uppercase; color: #fff;
}
/* One-time sheen (app.js heroSheen): a soft-edged window slides across the
   title carrying a gold copy of it; the copy counter-slides so it stays
   registered with the real text. Transforms only. */
.sheen { position: absolute; top: 0; bottom: 0; left: 0; width: 34%; overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 38%, #000 62%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 38%, #000 62%, transparent); }
.sheen__text { position: absolute; top: 0; left: 0; box-sizing: border-box; color: var(--gold-bright);
  text-shadow: 0 0 22px rgba(239, 195, 80, 0.45); }
.hero__lede { max-width: 30rem; margin: 0 0 1.5rem auto; color: rgba(255, 255, 255, 0.92); }
.hero__cta { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.7rem; }

.btn--light { background: #fff; color: var(--ink); }
.btn--light:hover { background: var(--gold-bright); color: var(--deep); }
.btn--outline { border-color: rgba(255, 255, 255, 0.7); color: #fff; }
.btn--outline:hover { background: #fff; color: var(--ink); border-color: #fff; }

.hero__nav {
  position: absolute; top: 50%; z-index: 4; translate: 0 -50%;
  display: grid; place-items: center; width: 2.8rem; height: 2.8rem;
  border-radius: 50%; background: rgba(255, 255, 255, 0.14); color: #fff;
  backdrop-filter: blur(6px);
  transition: background-color var(--d-ui) var(--ease), scale var(--d-ui) var(--ease);
}
.hero__nav:hover { background: rgba(255, 255, 255, 0.92); color: var(--ink); scale: 1.06; }
.hero__nav--prev { left: clamp(0.5rem, 2vw, 1.75rem); }
.hero__nav--next { right: clamp(0.5rem, 2vw, 1.75rem); }

.hero__dots { position: absolute; left: 0; right: 0; bottom: 1.1rem; z-index: 4; display: flex; justify-content: center; gap: 0.5rem; }
.hero__dots button {
  width: 1.9rem; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.4);
  transition: background-color var(--d-ui) var(--ease);
}
.hero__dots button[aria-selected="true"] { background: var(--gold-bright); }

@media (max-width: 899px) {
  .hero__stage { height: clamp(24rem, 78vh, 34rem); }
  /* Sit the message toward the bottom on a phone: centred, it covered the
     middle of the photograph, which is where the jewellery actually is. */
  .hero__slide { align-items: end; }
  .hero__inner { justify-content: center; padding-bottom: clamp(3rem, 11vw, 5rem); }
  .hero__text { max-width: 26rem; text-align: center; }
  .hero__lede { margin-inline: auto; }
  .hero__cta { justify-content: center; }
  .hero__slide::after { background: linear-gradient(180deg, rgba(14, 12, 9, 0.10) 0%, rgba(14, 12, 9, 0.30) 42%, rgba(14, 12, 9, 0.74) 100%); }
  .hero__nav { width: 2.3rem; height: 2.3rem; }
}

/* ---------- sections ---------- */
.section { padding-block: clamp(3rem, 6vw, 5.5rem); }
.section--tint { background: var(--tint); }
.section--champagne { background: var(--champagne); }

/* ---------- reel (home): the owner's film, playing on a loop, app.js reel ----------
   Static by default (no JS, reduced motion): the poster in a rounded card and
   the three lines beneath it. .is-film (added by app.js when motion is on)
   makes it a full-width film that plays while on screen, with one line at a
   time: over the film on laptops, under it on phones. */
.reel { position: relative; background: var(--bg);   /* white like its neighbours since 30 Sep (was blush) */
  padding-block: clamp(3rem, 6vw, 5.5rem); }
.reel__stage { position: relative; }
.reel__frame {
  position: relative; overflow: hidden; width: min(100% - 2 * var(--gutter), 1024px); margin: 0 auto;
  aspect-ratio: 16 / 9; border-radius: var(--radius); background: #eceae7;
}
.reel__poster, .reel__film { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; }
.reel__film { display: none; }
.reel__shade { display: none; }
.reel__lines { display: grid; gap: 1.4rem; justify-items: center; margin-top: clamp(1.8rem, 4vw, 2.6rem); padding-inline: var(--gutter); text-align: center; }
.reel__kicker { margin: 0 0 0.45rem; font-size: 0.66rem; font-weight: 600; letter-spacing: 0.24em; text-transform: uppercase; color: var(--gold); }
/* The hero's display face (Cormorant Garamond italic 500, the only weight
   loaded): the film is the page's second hero moment. */
.reel__title {
  margin: 0; font-family: var(--display); font-style: italic; font-weight: 500;
  font-size: clamp(1.9rem, 1.1rem + 3.4vw, 4.2rem); line-height: 1.14; padding-bottom: 0.06em;
  letter-spacing: 0.01em; color: var(--ink); text-wrap: balance;
}
/* "SMITHLLERY" always in the wordmark face (owner's rule). */
.reel__mark { font-family: var(--wordmark); font-style: normal; font-weight: 900; font-size: 0.62em; letter-spacing: 0.06em; text-transform: uppercase; }
.reel__cta { margin-top: 1.3rem; }

/* Playing: full width, as tall as the screen allows on laptops (16:9, centred
   crop past that); 4:3 on phones so the bracelets stay a good size. The lines
   share one grid cell and cross-fade as the film reaches each scene. */
.reel.is-film { padding-block: 0; }
.reel.is-film .reel__frame { width: 100%; height: min(56.25vw, 100svh); aspect-ratio: auto; border-radius: 0; background: var(--deep); }
.reel.is-film .reel__film { display: block; }
.reel.is-film .reel__lines { display: grid; gap: 0; }
.reel.is-film .reel__line { grid-area: 1 / 1; align-self: start; opacity: 0; visibility: hidden; transform: translateY(18px);
  transition: opacity var(--d-section) var(--ease), transform var(--d-section) var(--ease), visibility 0s linear var(--d-section); }
.reel.is-film .reel__line.is-on { opacity: 1; visibility: visible; transform: none;
  transition: opacity var(--d-section) var(--ease), transform var(--d-section) var(--ease), visibility 0s; }
@media (min-width: 701px) {
  .reel.is-film .reel__shade {
    display: block; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(180deg, rgba(16, 26, 16, 0) 38%, rgba(16, 26, 16, 0.55) 64%, rgba(16, 26, 16, 0.88) 100%);
  }
  /* Bottom-left, each line on the bottom edge (align-self: end): that
     corner is clear in all three scenes (the fabric, then the sleeve), where
     centred text sat on the bracelet (1 Oct). */
  .reel.is-film .reel__lines { position: absolute; left: clamp(1.5rem, 5vw, 5rem); right: clamp(1.5rem, 5vw, 5rem); bottom: clamp(1.6rem, 4vw, 3.6rem);
    margin: 0; padding: 0; justify-items: start; text-align: left; pointer-events: none; }
  .reel.is-film .reel__title { max-width: 16ch; }
  .reel.is-film .reel__line { align-self: end; }
  .reel.is-film .reel__line.is-on { pointer-events: auto; }
  .reel.is-film .reel__kicker { margin-bottom: 0.7rem; font-size: 0.8rem; font-weight: 700; color: #ffe39a;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6), 0 0 18px rgba(0, 0, 0, 0.55); }
  .reel.is-film .reel__title { color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.35), 0 2px 28px rgba(0, 0, 0, 0.45); }
}
@media (max-width: 700px) {
  .reel.is-film { padding-bottom: clamp(2.4rem, 8vw, 3.2rem); }
  .reel.is-film .reel__frame { height: auto; aspect-ratio: 4 / 3; }
  .reel.is-film .reel__poster, .reel.is-film .reel__film { object-position: 50% 50%; }   /* centred: the opening bracelet is mid-frame (58% pushed it left, 1 Oct) */
}

/* horizontal product row */
.row-head { display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between; gap: 1rem; margin-bottom: clamp(1.5rem, 3vw, 2.2rem); }
.row-nav { display: flex; align-items: center; gap: 0.5rem; }
.row-nav button { display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border: 1px solid var(--line-2); border-radius: 50%; color: var(--ink); transition: background-color 0.3s, color 0.3s, border-color 0.3s; }
.row-nav button:hover:not(:disabled) { background: var(--deep); border-color: var(--deep); color: #fff; }
.row-nav button:disabled { opacity: 0.3; cursor: not-allowed; }
.row-nav .link-arrow { margin-left: 0.75rem; }
@media (max-width: 640px) { .row-nav button { display: none; } }
.row { position: relative; overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: none; margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter); }
.row::-webkit-scrollbar { display: none; }
.row__track { display: flex; gap: clamp(0.9rem, 2vw, 1.5rem); width: max-content; margin: 0; padding: 0; list-style: none; }
.row__track > li { width: min(46vw, 11rem); scroll-snap-align: start; }
@media (min-width: 700px) { .row__track > li { width: clamp(11rem, 15vw, 13.5rem); } }
/* Phones: two stacked rows scrolling together. One row only ever showed two
   pieces, which reads as an empty shelf on the device most people shop from. */
@media (max-width: 699px) {
  .row__track {
    display: grid; grid-auto-flow: column;
    grid-template-rows: repeat(2, auto);
    gap: 1.1rem 0.7rem;
  }
  .row__track > li { width: 38vw; }
}

/* ---------- product card ---------- */
.card { position: relative; display: flex; flex-direction: column; height: 100%; }
.card__media { position: relative; margin: 0; aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
.card:hover .card__media img, .card:focus-visible .card__media img { transform: scale(1.05); }
/* Earring studio shots are square, already framed with even margins and
   baked onto --photo-ground (scripts/process-earring-photos.py). Contain
   keeps the whole pair; the band above and below is the same colour, so the
   card reads as one seamless photo. Kadas/bracelets keep cover. */
.card--contain .card__media img { object-fit: contain; }
/* Second angle on hover (New arrivals). It sits under the flag, and fades
   rather than cuts so the swap reads as the same piece from closer in. */
.card__alt { position: absolute; inset: 0; opacity: 0; transition: opacity var(--d-pop) var(--ease), transform 1s var(--ease); }
.card:hover .card__alt, .card:focus-visible .card__alt { opacity: 1; }
.card__flag { z-index: 1; }
.card__flag { position: absolute; top: 0.7rem; left: 0.7rem; padding: 0.3rem 0.62rem; border-radius: 999px; background: var(--rose); color: #fff; font-size: 0.64rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.card__flag--out { background: var(--deep); color: var(--gold-bright); }
/* Names wrap to different line counts, which used to push the category and
   price down by different amounts across a row. Clamp the name to two lines and
   push the price to the bottom so every card in a row lines up. */
.card__body { display: flex; flex-direction: column; flex: 1; padding-top: 0.85rem; }
.card__name {
  margin: 0; font-weight: 400; font-size: 0.9rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: calc(2 * 1.35em);
}
.row__track .card__name { font-size: 0.85rem; }
.row__track .card__cat { font-size: 0.6rem; }
.row__track .card__price { font-size: 0.92rem; }
.row__track .card__flag { top: 0.45rem; left: 0.45rem; padding: 0.24rem 0.5rem; font-size: 0.58rem; }
.card__cat { margin: 0.25rem 0 0.5rem; font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.card__price { margin-top: auto !important; }
.card__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.5rem; margin: 0; font-size: 0.95rem; font-weight: 700; }
.card__price s { font-size: 0.82rem; font-weight: 400; color: var(--muted); }
.card__save { font-size: 0.72rem; font-weight: 700; color: var(--sale); }

/* ---------- promises ---------- */
/* padding-block only: the container's side padding must survive (padding:0 would kill it). */
.promises { display: grid; gap: 1.6rem; margin-block: 0; padding-block: 0; list-style: none; }
@media (min-width: 760px) { .promises { grid-template-columns: repeat(2, 1fr); gap: clamp(1.5rem, 3vw, 2.5rem); } }
@media (min-width: 1100px) { .promises { grid-template-columns: repeat(4, 1fr); gap: clamp(1.25rem, 2.5vw, 2.25rem); } }
.promise { display: flex; align-items: flex-start; gap: 0.9rem; }
.promise .i { width: 1.6rem; height: 1.6rem; margin-top: 0.15rem; color: var(--gold); }
.promise h3 { margin: 0 0 0.2rem; font-weight: 600; font-size: 0.92rem; }
.promise p { margin: 0; color: var(--muted); font-size: 0.9rem; }

/* ---------- story ---------- */
.story { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); align-items: center; }
@media (min-width: 900px) { .story { grid-template-columns: 1fr 1fr; } }
.story__figure { margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); }
.story__figure :is(img, video) { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
/* The craft film at its own 3:2 (30 Sep). height: auto matters: the video's
   height="800" attribute otherwise wins over aspect-ratio and it stood 800px
   tall, cropped to a sliver. Phones: edge to edge, no rounding. */
.story__figure .story__film { height: auto; aspect-ratio: 3 / 2; }
@media (max-width: 899px) {
  .story__figure:has(.story__film) { margin-inline: calc(-1 * var(--gutter)); border-radius: 0; }
}
.story__list { display: grid; gap: 0.6rem; margin: 1.2rem 0 1.8rem; padding: 0; list-style: none; color: var(--ink-2); }
.story__list li { display: flex; align-items: center; gap: 0.6rem; }
.story__list .i { color: var(--gold); }

/* ---------- grids ---------- */
.grid { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem) clamp(0.9rem, 2vw, 1.5rem); grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); margin: 0; padding: 0; list-style: none; }
@media (max-width: 560px) { .grid { grid-template-columns: repeat(2, 1fr); } .card__name { font-size: 1.02rem; } .card__price { font-size: 0.92rem; } }
.notice { grid-column: 1 / -1; padding: 2.5rem 0; color: var(--ink-2); }
.notice a { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
.center-cta { display: flex; justify-content: center; margin-top: clamp(2rem, 4vw, 3rem); }

/* ---------- inner pages ---------- */
.page { padding-top: clamp(1.5rem, 3vw, 2.5rem); }
.page-hero { padding-bottom: clamp(1.5rem, 3vw, 2.5rem); }
.page-hero h1 { margin: 0; font-weight: 300; font-size: clamp(1.6rem, 1.3rem + 1.3vw, 2.2rem); line-height: 1.18; }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0 0 1.2rem; font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.crumbs a:hover { color: var(--gold); }
.page-hero__lede { max-width: 38rem; margin: 1rem 0 0; color: var(--ink-2); }

.shop { padding-bottom: clamp(3.5rem, 7vw, 6rem); }
.toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.85rem; margin-bottom: clamp(1.5rem, 3vw, 2.5rem); padding-block: 1rem; border-block: 1px solid var(--line); }
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.chip { min-height: 2.5rem; padding: 0.5rem 1.05rem; border: 1px solid var(--line-2); border-radius: 999px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-2); transition: background-color 0.3s, color 0.3s, border-color 0.3s; }
.chip:hover { border-color: var(--deep); color: var(--deep); }
.chip[aria-pressed="true"] { background: var(--deep); border-color: var(--deep); color: #fff; }
.toolbar__right { display: flex; align-items: center; gap: 1rem; margin-left: auto; }
.count { font-size: 0.8rem; color: var(--muted); }
.select { position: relative; display: inline-block; }
.select select { -webkit-appearance: none; appearance: none; min-height: 2.5rem; padding: 0.5rem 2.4rem 0.5rem 1.05rem; border: 1px solid var(--line-2); border-radius: 999px; background: transparent; font-size: 0.8rem; cursor: pointer; }
.select::after { content: ""; position: absolute; right: 1rem; top: 50%; width: 0.42rem; height: 0.42rem; margin-top: -0.32rem; border-right: 1.5px solid var(--ink); border-bottom: 1.5px solid var(--ink); transform: rotate(45deg); pointer-events: none; }
.shop-search { position: relative; display: flex; flex: 1 1 14rem; max-width: 22rem; }
.shop-search input { width: 100%; min-height: 2.5rem; padding: 0.5rem 2.6rem 0.5rem 1.05rem; border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface); font-size: 0.85rem; }
.shop-search button { position: absolute; right: 0.4rem; top: 50%; transform: translateY(-50%); display: grid; place-items: center; width: 2rem; height: 2rem; color: var(--muted); }
.shop-search button:hover { color: var(--deep); }

.pdp { display: grid; gap: clamp(1.5rem, 4vw, 4rem); padding-block: 0.5rem clamp(3rem, 6vw, 5rem); }
@media (min-width: 900px) { .pdp { grid-template-columns: 1.1fr 1fr; align-items: start; } .pdp__info { position: sticky; top: calc(var(--top) + 2rem); } }
.pdp__figure { position: relative; margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); }
/* One frame for every shot. The originals are 3:2, the new angles 4:3 or square;
   a fixed 4:3 frame with contain means switching never shifts the layout and
   never crops the piece. */
.pdp__figure { aspect-ratio: 4 / 3; touch-action: pan-y; }
.pdp__figure img { width: 100%; height: 100%; object-fit: contain; transition: transform 0.6s var(--ease), opacity var(--d-ui) var(--ease); }
.pdp__figure.is-swapping img { opacity: 0; transition: opacity var(--d-micro) var(--ease-in); }
/* Phone lightbox (app.js lightbox). The ground matches --photo-ground so the
   baked studio shots float with no visible edge. */
.lightbox { position: fixed; inset: 0; z-index: 200; touch-action: none; overscroll-behavior: contain; }
.lightbox[hidden] { display: none; }
.lightbox__bg { position: absolute; inset: 0; background: var(--photo-ground); }
.lightbox__img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; will-change: transform; user-select: none; -webkit-user-drag: none; }
.lightbox__img.is-settling { transition: transform var(--d-pop) var(--ease); }
.lightbox__close { position: absolute; top: max(0.75rem, env(safe-area-inset-top)); right: 0.75rem; z-index: 1; display: grid; place-items: center;
  width: 44px; height: 44px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.92); color: var(--ink); box-shadow: var(--shadow); }
.lightbox__close:active { transform: scale(0.95); }
.lightbox__hint { position: absolute; left: 0; right: 0; bottom: max(1rem, env(safe-area-inset-bottom)); margin: 0; text-align: center;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.pdp__thumbs { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.8rem; }
.pdp__thumb { position: relative; width: 4.6rem; aspect-ratio: 4 / 3; padding: 0; overflow: hidden; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--photo-ground); cursor: pointer; opacity: 0.72; transition: opacity var(--d-ui) var(--ease), border-color var(--d-ui) var(--ease); }
.pdp__thumb img { width: 100%; height: 100%; object-fit: cover; }
.pdp__thumb:hover { opacity: 1; }
.pdp__thumb.is-active { opacity: 1; border-color: var(--ink); box-shadow: 0 0 0 1px var(--ink); }
.pdp__thumb:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pdp__thumb:active { transform: scale(0.97); }
@media (pointer: fine) { .pdp__figure { cursor: zoom-in; } .pdp__figure.is-zoom { cursor: zoom-out; } .pdp__figure.is-zoom img { transform: scale(1.9); } }
.pdp__title { margin: 0 0 0.9rem; font-weight: 400; font-size: clamp(1.3rem, 1.15rem + 0.7vw, 1.7rem); line-height: 1.25; }
.pdp__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.7rem; margin: 0 0 0.7rem; font-size: 1.5rem; font-weight: 600; }
.pdp__price s { font-size: 1rem; font-weight: 400; color: var(--muted); }
.pdp__save { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--sale); }
.pdp__stock { display: inline-flex; align-items: center; gap: 0.5rem; margin: 0 0 1.5rem; font-size: 0.82rem; color: var(--ink-2); }
.pdp__stock::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #3f7a44; }
.pdp__stock.is-out::before { background: var(--muted); }
.pdp__desc { margin-bottom: 1.6rem; padding-top: 1.3rem; border-top: 1px solid var(--line); color: var(--ink-2); }
.pdp__desc p { margin: 0 0 1rem; white-space: pre-line; }
.pdp__desc p:last-child { margin-bottom: 0; }
.pdp__codes { display: grid; gap: 0.55rem; margin: 1.15rem 0 0; padding: 0.9rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.pdp__codes > div { display: grid; grid-template-columns: 7.5rem 1fr; gap: 0.6rem; align-items: baseline; }
.pdp__codes dt { margin: 0; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.pdp__codes dd { margin: 0; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.pdp__buy { display: grid; grid-template-columns: auto 1fr; gap: 0.7rem; margin-bottom: 1.4rem; }
.pdp__buy--ask { grid-template-columns: 1fr; }
.pdp__buy--ask .btn { gap: 0.6rem; }
/* Delivery check (Phase 9): hidden until the shop confirms Shiprocket is set up. */
.pdp__deliver { margin: -0.4rem 0 1.4rem; }
.pdp__deliver[hidden] { display: none; }
.pdp__deliver label { display: block; margin-bottom: 0.4rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2); }
.pdp__deliver-row { display: grid; grid-template-columns: 1fr auto; gap: 0.5rem; }
.pdp__deliver-row input {
  min-height: 3rem; padding: 0 1rem; border: 1px solid var(--line-2); border-radius: 999px;
  background: var(--surface); font: inherit; font-size: 0.95rem; letter-spacing: 0.08em; color: var(--ink);
}
.pdp__deliver-row input:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pdp__deliver-out { margin: 0.55rem 0 0; min-height: 1.2em; font-size: 0.86rem; color: var(--ink-2); }
.pdp__deliver-out:empty { display: none; }
.pdp__deliver-out.is-ok { color: #2f6b3a; }
.pdp__deliver-out.is-warn { color: var(--rose-hi); }
/* The owner's colour and Unique/SKU code, shown the way his tags print them. */
.pdp__specs { display: grid; gap: 0.55rem; margin: -0.4rem 0 1.6rem; padding: 0 0 1.3rem; border-bottom: 1px solid var(--line); font-size: 0.86rem; }
.pdp__specs div { display: grid; grid-template-columns: 9.5rem 1fr; gap: 1rem; }
.pdp__specs dt { font-size: 0.66rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); align-self: center; }
.pdp__specs dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
.qty { display: flex; align-items: center; border: 1px solid var(--line-2); border-radius: 999px; }
.qty button { width: 2.7rem; height: 3rem; font-size: 1.1rem; border-radius: 999px; }
.qty button:hover:not(:disabled) { color: var(--deep); }
.qty button:disabled { opacity: 0.35; cursor: not-allowed; }
.qty output { min-width: 1.5rem; text-align: center; font-weight: 700; }
.pdp__notes { display: grid; gap: 0.65rem; margin: 0 0 1.4rem; padding: 0; list-style: none; font-size: 0.9rem; color: var(--ink-2); }
.pdp__notes li { display: flex; align-items: center; gap: 0.7rem; }
.pdp__notes .i { color: var(--gold); }
.pdp__demo { margin: 0; padding: 0.8rem 1rem; border: 1px dashed var(--line-2); border-radius: var(--radius-sm); font-size: 0.8rem; color: var(--muted); }
.pdp__demo[hidden] { display: none; }
.pdp__demo a { color: var(--gold); text-decoration: underline; text-underline-offset: 3px; }
/* Top bar link while online ordering is paused */
.demo-bar__link { color: inherit; text-decoration: underline; text-underline-offset: 3px; overflow: hidden; text-overflow: ellipsis; }
/* Checkout while online ordering is paused */
.checkout__paused { display: grid; gap: 1rem; justify-items: start; max-width: 36rem; padding-block: 1rem 2rem; }
.checkout__paused p { margin: 0; color: var(--ink-2); }
.checkout__paused .btn { gap: 0.6rem; }
/* Contact and newsletter form feedback */
.signup__note.is-warn, .contact__note.is-warn { color: var(--rose-hi); }
.contact__form [aria-invalid="true"] { border-color: var(--rose-hi); }
.related { padding-bottom: clamp(3.5rem, 7vw, 6rem); }
.related .section-title { margin-bottom: clamp(1.5rem, 3vw, 2.2rem); text-align: center; }
.lost { display: grid; place-items: center; min-height: 60vh; padding-block: 3rem; text-align: center; }
.lost h1 { font-weight: 300; font-size: clamp(1.5rem, 1.25rem + 1.2vw, 2.1rem); margin: 0 0 0.8rem; }
.lost h1 em { font-style: italic; color: var(--gold); }
.lost .eyebrow { justify-content: center; }
.lost p { color: var(--ink-2); margin: 0 0 1.8rem; }

/* ---------- footer ---------- */
/* Deep ground on purpose: the logo artwork is gold-on-near-black, so it sits
   here as drawn instead of being knocked onto a light background. */
.footer { background: var(--deep); color: #f2ece2; }
.footer__inner { padding-block: clamp(2.5rem, 5vw, 4rem) 1.5rem; }
.footer__top { display: grid; gap: 2rem; }
@media (min-width: 760px) { .footer__top { grid-template-columns: 1.45fr 0.85fr 0.85fr 1fr 1.25fr; gap: 1.5rem 2rem; } }
.footer__brand { display: flex; align-items: center; gap: 1rem; }
.footer__brand p { max-width: 20rem; margin: 0; font-size: 0.9rem; line-height: 1.5; color: #ded5c6; }
.footer h3 { margin: 0 0 0.8rem; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold-bright); }
.footer ul { display: grid; gap: 0.5rem 1rem; margin: 0; padding: 0; list-style: none; font-size: 0.88rem; }
/* Two across on phones only — it was one long vertical scroll there. Desktop
   keeps a single column per group, which is what the owner approved. The
   contact list always stays single column: an email beside a phone number
   squashes both into unreadable wraps. */
@media (max-width: 759px) {
  .footer nav ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.footer__contact ul { grid-template-columns: 1fr; }
.footer a { color: #ded5c6; transition: color 0.3s; }
.footer a:hover { color: var(--gold-bright); }
.footer .soon { color: #9d9484; }
.footer__bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.6rem; margin-top: 2.5rem; padding-top: 1.2rem; border-top: 1px solid rgba(239, 195, 80, 0.22); font-size: 0.78rem; color: #9d9484; }

/* footer: the owner's whole gold logo (9 Oct) */
.footer__brand .footer__logo { width: min(15rem, 72vw); height: auto; border-radius: 0; }

/* ---------- 1. sticky header shrink ---------- */
.site-header { transition: box-shadow 0.45s var(--ease); }
.site-header.is-compact { box-shadow: 0 8px 26px -20px rgba(23, 20, 15, 0.55); }
.nav { transition: height 0.4s var(--ease); }
.wordmark { transition: padding-top 0.4s var(--ease); }
.wordmark__name { transition: font-size 0.4s var(--ease); }
.wordmark__tag { overflow: hidden; transition: opacity 0.3s var(--ease), max-height 0.4s var(--ease), margin-bottom 0.4s var(--ease); max-height: 1rem; }
.site-header.is-compact .nav { height: 3.5rem; }
.site-header.is-compact .wordmark { padding-top: 0; }
.site-header.is-compact .wordmark__name { font-size: 1.14rem; }
.site-header.is-compact .wordmark__tag { opacity: 0; max-height: 0; margin-bottom: 0; }

/* ---------- 2. add to bag ---------- */

/* ---------- 7. loading skeletons ---------- */
.sk-card { display: block; }
.sk-media { aspect-ratio: 4 / 5; border-radius: var(--radius); }
.sk-circle { width: var(--circle-size); aspect-ratio: 1; border-radius: 50%; margin-inline: auto; }
.sk-line { height: 0.8rem; margin-top: 0.7rem; border-radius: 4px; }
.sk-line--short { width: 45%; }
/* Opacity pulse, not a moving gradient: background-position repaints every frame. */
.sk-media, .sk-line { background-color: var(--tint); animation: sk 1.4s ease-in-out infinite; }
@keyframes sk { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

/* ---------- 10. carousel edge fade ---------- */
.row {
  --fade-l: 0px;
  --fade-r: 0px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
}
.row.can-left { --fade-l: 2.5rem; }
.row.can-right { --fade-r: 2.5rem; }

/* ---------- 11. offer / promise marquee ---------- */
.marquee { overflow: hidden; border-block: 1px solid var(--line-gold); background: var(--champagne); }
/* Held until the page has loaded so it doesn't compete with the first paint. */
.marquee__track { display: flex; width: max-content; margin: 0; padding: 0; list-style: none; animation: marquee 42s linear infinite paused; }
html.is-loaded .marquee__track { animation-play-state: running; will-change: transform; }
.marquee:hover .marquee__track, .marquee:focus-within .marquee__track { animation-play-state: paused; }
.marquee li { display: flex; align-items: center; gap: 0.6rem; padding: 0.85rem clamp(1.25rem, 3vw, 2.5rem); font-size: 0.76rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2); white-space: nowrap; }
.marquee li .i { width: 1.05rem; height: 1.05rem; color: var(--gold); }
.marquee li + li::before { content: "·"; margin-right: clamp(1.25rem, 3vw, 2.5rem); margin-left: calc(-1 * clamp(1.25rem, 3vw, 2.5rem) / 2); color: var(--gold-soft); }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
  .marquee { overflow-x: auto; }
}

/* ---------- 13. page transition ---------- */

/* ---------- toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: 1.5rem; z-index: 150;
  max-width: calc(100vw - 2rem); padding: 0.85rem 1.3rem; border-radius: 999px;
  background: var(--ink); color: var(--bg); font-size: 0.86rem; font-weight: 500; text-align: center;
  box-shadow: 0 20px 50px -20px rgba(23, 20, 15, 0.6);
  opacity: 0; transform: translate(-50%, 160%); pointer-events: none;
  transition: transform 0.6s var(--ease), opacity 0.35s var(--ease);
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }

/* ---------- motion defaults (only while motion.js runs) ---------- */
html.has-motion [data-split],
html.has-motion [data-reveal],
html.has-motion [data-reveal-item],
html.has-motion [data-image-reveal] { visibility: hidden; }

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

/* ---------- coverflow slider (palmonas "FOR EVERY YOU") ---------- */
/* Geometry lifted from the real thing: perspective 1200px on the stage, each
   slide 9deg of rotateY and -200px of translateZ per step away from centre.
   Slide is 480x616 there (aspect 0.78); we use 4/5 to match the product cards. */
.cf {
  --cf-w: clamp(13rem, 21vw, 18.75rem);   /* Skiper49: 300px square slides */
  position: relative;
  margin-top: clamp(0.5rem, 2vw, 1.5rem);
}
@media (max-width: 699px) { .cf { --cf-w: min(62vw, 15rem); } }
/* The edge fade used to be a mask-image on the stage, which made the browser
   re-rasterise the whole 3D strip on every frame of a spin (Safari worst).
   Two gradient veils in the section's own colour look the same and cost
   nothing (25 Sep). */
.cf__stage {
  position: relative;
  perspective: 1200px;
  height: calc(var(--cf-w) * 1.36);   /* room for the slide shadows below */
  overflow: hidden;
}
.cf__stage::before, .cf__stage::after {
  content: ""; position: absolute; top: 0; bottom: 0; z-index: 200; width: 8%; pointer-events: none;
}
.cf__stage::before { left: 0; background: linear-gradient(90deg, var(--bg), transparent); }
.cf__stage::after { right: 0; background: linear-gradient(-90deg, var(--bg), transparent); }
/* The track is a flat plane at z=0 and the side slides sit behind it
   (negative translateZ), so it swallowed every click aimed at them, and
   the centre one too. It takes no hits; the slides do (25 Sep). */
.cf__track {
  position: relative; height: 100%; margin: 0; padding: 0; list-style: none;
  transform-style: preserve-3d; pointer-events: none;
}
.cf__slide { pointer-events: auto; -webkit-tap-highlight-color: transparent; }
.cf__slide {
  position: absolute; top: 50%; left: 50%;
  width: var(--cf-w); aspect-ratio: 1;
  margin-left: calc(var(--cf-w) / -2);
  translate: 0 -50%;
  backface-visibility: hidden;
  will-change: transform;   /* each slide its own layer: a spin only composites */
}
.cf__slide a { position: relative; display: block; height: 100%; cursor: pointer; }
/* Swiper-style slide shadows: the edge turned away from you darkens.
   Each is its own layer (will-change): the spin changes their opacity every
   frame, and inside the slide's layer that repainted the photo too, every
   frame, so on a phone a turning photo arrived late and washed out (30 Sep).
   Lighter than Swiper's 0.5: on the white studio shots it read as a grey
   panel. */
.cf__shadow { position: absolute; inset: 0; border-radius: 4px; opacity: 0; pointer-events: none; will-change: opacity; }
.cf__shadow--l { background: linear-gradient(to right, rgba(14, 12, 9, 0.32), rgba(14, 12, 9, 0) 70%); }
.cf__shadow--r { background: linear-gradient(to left, rgba(14, 12, 9, 0.32), rgba(14, 12, 9, 0) 70%); }
/* "View piece" on the centre slide: shown on hover or keyboard focus, and
   always on touch screens (no hover there). Hidden mid-drag. */
.cf__view {
  position: absolute; left: 50%; bottom: clamp(0.6rem, 1.6vw, 1rem);
  display: inline-flex; align-items: center; gap: 0.4rem; white-space: nowrap;
  padding: 0.5rem 0.95rem; border-radius: 999px;
  background: rgba(255, 253, 252, 0.94); color: var(--ink); box-shadow: var(--shadow);
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0; transform: translate(-50%, 6px); pointer-events: none;
  transition: opacity var(--d-ui) var(--ease), transform var(--d-ui) var(--ease);
}
.cf__view .i { width: 1em; height: 1em; }
.cf__slide[data-cf-active="true"] a:hover .cf__view,
.cf__slide[data-cf-active="true"] a:focus-visible .cf__view { opacity: 1; transform: translate(-50%, 0); }
@media (hover: none) { .cf__slide[data-cf-active="true"] .cf__view { opacity: 1; transform: translate(-50%, 0); } }
.cf.is-dragging .cf__view { opacity: 0; }
@media (max-width: 699px) { .cf__view { padding: 0.4rem 0.7rem; font-size: 0.58rem; } }
.cf__slide img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: 4px; background: var(--photo-ground);
  /* One shadow for every slide: the centre used to swap to a far bigger blur,
     which repainted two layers at every switch, mid-spin (26 Sep). */
  box-shadow: 0 30px 50px -34px rgba(23, 20, 15, 0.7);
}

.cf__nav {
  position: absolute; top: 50%; z-index: 20; translate: 0 -50%;
  display: grid; place-items: center; width: 2.9rem; height: 2.9rem;
  border-radius: 50%; background: var(--surface); color: var(--ink);
  box-shadow: 0 10px 28px -14px rgba(23, 20, 15, 0.45);
  transition: background-color 0.3s, color 0.3s, scale 0.3s var(--ease);
}
.cf__nav--prev { left: clamp(0.5rem, 3vw, 3rem); }
.cf__nav--next { right: clamp(0.5rem, 3vw, 3rem); }
.cf__nav:hover { background: var(--deep); color: var(--gold-bright); scale: 1.06; }

.cf__meta { display: grid; justify-items: center; gap: 0.7rem; margin-top: 1.1rem; padding-inline: var(--gutter); }
.cf__caption { margin: 0; text-align: center; font-size: 0.94rem; color: var(--ink-2); min-height: 1.4em; }
.cf__caption b { font-weight: 600; color: var(--ink); }
.cf__caption span { color: var(--gold); }
/* Each dot is a 24px tap target (WCAG 2.5.8; PageSpeed flagged 7px dots
   with overlapping hit areas, 25 Sep); the visible dot is its ::after. */
.cf__dots { display: flex; flex-wrap: wrap; justify-content: center; gap: 0; }
.cf__dots button { display: grid; place-items: center; width: 24px; height: 24px; padding: 0; background: none; }
/* Swiper's bullets: 8px ink dots at 20%, the current one solid */
.cf__dots button::after {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ink); opacity: 0.2;
  transition: opacity 0.3s var(--ease);
}
.cf__dots button[aria-selected="true"]::after { opacity: 1; }

/* Grabbing feel while dragging */
.cf__stage { cursor: grab; }
.cf.is-dragging .cf__stage { cursor: grabbing; }

/* No 3D without motion: fall back to an ordinary swipeable row. */
.cf.is-flat .cf__stage {
  perspective: none; height: auto; overflow-x: auto; scroll-snap-type: x mandatory;
  -webkit-mask-image: none; mask-image: none; cursor: auto;
}
.cf.is-flat .cf__shadow { display: none; }
.cf.is-flat .cf__track { display: flex; gap: 1rem; height: auto; padding-inline: var(--gutter); width: max-content; }
.cf.is-flat .cf__slide {
  position: static; margin: 0; translate: none; transform: none !important;
  width: min(72vw, 18rem); scroll-snap-align: center;
}
.cf.is-flat .cf__nav { display: none; }

/* ---------- tabbed row bar (palmonas "TOP STYLES") ---------- */
.row-bar {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.75rem 1rem; margin-bottom: clamp(1.25rem, 2.5vw, 1.9rem);
}
.chips--center { justify-content: center; }
.row-bar .row-nav { margin-left: auto; }
@media (max-width: 860px) {
  .row-bar .row-nav { margin-left: 0; }
  .row-bar { justify-content: center; }
}
/* Palmonas' pills are small and tight */
.chip { font-size: 0.68rem; letter-spacing: 0.08em; }

/* ---------- newsletter (palmonas "Sign up and save") ---------- */
/* ---------- home: Instagram ("Check out our work") ----------
   One grid, five sizes of tile: a big one, two tall, two small. Row heights are
   fixed, so nothing shifts as the photos load. The photos are 360x640, so the
   grid is capped at 68rem: the big tile stays close to its real width. */
.insta .section-head { max-width: 68rem; margin-inline: auto; }
.insta__lede { max-width: 30rem; margin: 0.6rem 0 0; color: var(--ink-2); }
.insta__grid {
  display: grid; gap: clamp(0.5rem, 1.2vw, 0.9rem); max-width: 68rem; margin: 0 auto; padding: 0; list-style: none;
  grid-template-columns: 1.35fr 1fr 0.9fr 1fr;
  grid-template-rows: repeat(2, clamp(10rem, 19vw, 14rem));
  grid-template-areas: "a b c d" "a b e d";
}
.insta__tile--a { grid-area: a; }
.insta__tile--b { grid-area: b; }
.insta__tile--c { grid-area: c; }
.insta__tile--d { grid-area: d; }
.insta__tile--e { grid-area: e; }
.insta__tile a { position: relative; display: block; height: 100%; overflow: hidden; border-radius: var(--radius); background: var(--champagne); }
.insta__tile img { width: 100%; height: 100%; object-fit: cover; transition: transform 1s var(--ease); }
.insta__tile a::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(to top, rgb(23 20 15 / 0.38), transparent 55%);
  transition: opacity var(--d-pop) var(--ease);
}
.insta__badge {
  position: absolute; right: 0.7rem; bottom: 0.7rem; z-index: 1; display: grid; place-items: center;
  width: 2.2rem; height: 2.2rem; border-radius: 50%; background: rgb(255 255 255 / 0.92); color: var(--ink);
  opacity: 0; transform: translateY(6px); transition: opacity var(--d-pop) var(--ease), transform var(--d-pop) var(--ease);
}
.insta__badge .i { width: 1rem; height: 1rem; }
@media (hover: hover) {
  .insta__tile a:hover img { transform: scale(1.05); }
  .insta__tile a:hover::after, .insta__tile a:hover .insta__badge { opacity: 1; }
  .insta__tile a:hover .insta__badge { transform: none; }
}
.insta__tile a:focus-visible .insta__badge { opacity: 1; transform: none; }
/* Touch: the badge always shows, so the tiles read as links to Instagram. */
@media (hover: none) { .insta__badge { opacity: 1; transform: none; } }
@media (max-width: 699px) {
  .insta__grid {
    grid-template-columns: 1.2fr 1fr;
    grid-template-rows: repeat(4, clamp(7.5rem, 30vw, 10rem));
    grid-template-areas: "a b" "a b" "c d" "e d";
  }
  .insta__badge { right: 0.5rem; bottom: 0.5rem; width: 1.9rem; height: 1.9rem; }
}
@media (prefers-reduced-motion: reduce) {
  .insta__tile img, .insta__badge, .insta__tile a::after { transition: none; }
}

.signup { background: var(--champagne); border-top: 1px solid var(--line-gold); }
.signup__inner { display: grid; justify-items: center; gap: 0.7rem; padding-block: clamp(2.5rem, 5vw, 3.75rem); text-align: center; }
.signup__inner > p { max-width: 32rem; margin: 0; color: var(--ink-2); }
.signup__form { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; width: 100%; max-width: 30rem; margin-top: 0.6rem; }
.signup__form input {
  flex: 1 1 14rem; min-height: 3rem; padding: 0.7rem 1.1rem;
  border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
}
.signup__form input::placeholder { color: var(--muted); }
.signup__note { margin: 0.3rem 0 0; font-size: 0.74rem; color: var(--muted); }
.signup__follow { margin: 0.35rem 0 0; font-size: 0.9rem; color: var(--ink-2); }
.signup__follow a { color: var(--ink); font-weight: 700; text-decoration: underline; text-decoration-color: var(--gold); text-underline-offset: 0.2em; }
.signup__follow a:hover { color: var(--gold); }

/* ---------- social + brand icons ---------- */
/* Brand marks from Iconify Simple Icons, used only to link Smithllery's own
   real profiles. Chat glyph is Solar, like the rest of the interface icons. */
.i-instagram { --i: url("../img/icons/instagram-logo.svg"); }
.i-facebook  { --i: url("../img/icons/facebook-logo.svg"); }
.i-twitter   { --i: url("../img/icons/twitter-logo.svg"); }
.i-chat      { --i: url("../img/icons/chat-round-dots-linear.svg"); }
.i-letter    { --i: url("../img/icons/letter-linear.svg"); }
.i-phone     { --i: url("../img/icons/phone-linear.svg"); }
.i-map       { --i: url("../img/icons/map-point-linear.svg"); }

.footer .social, ul.social { display: flex; flex-wrap: wrap; gap: 0.55rem; margin: 1.15rem 0 0; padding: 0; list-style: none; }
.social a, .footer .social a {
  display: grid; place-items: center; width: 2.35rem; height: 2.35rem; border-radius: 50%;
  border: 1px solid rgba(239, 195, 80, 0.32); color: var(--gold-bright);
  transition: background-color 0.3s, color 0.3s, border-color 0.3s, scale 0.3s var(--ease);
}
.social a:hover { background: var(--gold-bright); color: var(--deep); border-color: transparent; scale: 1.06; }
.social .i { width: 1.02rem; height: 1.02rem; }

.footer__brand { flex-direction: column; align-items: flex-start; gap: 0.9rem; }
.footer__contact ul { font-size: 0.88rem; }
.footer__contact .addr { color: #9d9484; line-height: 1.6; }

/* ---------- floating WhatsApp ---------- */
.wa {
  position: fixed; right: clamp(0.85rem, 2vw, 1.5rem); bottom: clamp(0.85rem, 2vw, 1.5rem); z-index: 140;
  display: inline-flex; align-items: center; gap: 0.5rem;
  padding: 0.72rem 1rem; border-radius: 999px;
  background: #17803f; color: #fff; font-size: 0.82rem; font-weight: 600;
  box-shadow: 0 14px 34px -14px rgba(23, 20, 15, 0.55);
  transition: background-color 0.3s, scale 0.3s var(--ease);
}
.wa:hover { background: #12692f; scale: 1.04; }
.wa .i { width: 1.15rem; height: 1.15rem; }
@media (max-width: 600px) { .wa { padding: 0.85rem; } .wa__label { display: none; } }

/* ---------- journal: featured + grid ---------- */
.feature { display: grid; gap: clamp(1.1rem, 3vw, 2.5rem); padding-top: clamp(1.25rem, 3vw, 2rem); border-top: 1px solid var(--line-gold); }
@media (min-width: 900px) { .feature { grid-template-columns: 1.15fr 1fr; align-items: center; } }
.feature__media { margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); aspect-ratio: 4 / 3; }
.feature__media img { width: 100%; height: 100%; object-fit: cover; transition: scale 1.1s var(--ease); }
.feature:hover .feature__media img { scale: 1.035; }
.feature__title { margin: 0.5rem 0 0.7rem; font-size: clamp(1.3rem, 1.1rem + 0.9vw, 1.9rem); font-weight: 300; line-height: 1.22; }
.feature__excerpt { margin: 0 0 1.1rem; color: var(--ink-2); max-width: 34rem; }

.posts { display: grid; gap: clamp(1.75rem, 3vw, 2.75rem) clamp(1.1rem, 2vw, 1.75rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); margin: 0; padding: 0; list-style: none; }
/* The home strip holds a fixed four, so give it explicit tracks. auto-fill was
   reserving a fifth column at wide widths and leaving a gap on the right. */
[data-home-posts] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { [data-home-posts] { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.post { display: flex; flex-direction: column; height: 100%; }
.post__media { position: relative; margin: 0 0 0.9rem; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); aspect-ratio: 3 / 2; }
.post__media img { width: 100%; height: 100%; object-fit: cover; transition: scale 1.1s var(--ease); }
.post:hover .post__media img, .post:focus-visible .post__media img { scale: 1.05; }
.post__tag { display: inline-block; margin: 0 0 0.4rem; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold); }
.post__title { margin: 0 0 0.45rem; font-size: 1.02rem; font-weight: 500; line-height: 1.35; }
.post__excerpt { margin: 0 0 0.7rem; font-size: 0.88rem; color: var(--ink-2); }
.post__meta { margin: auto 0 0; font-size: 0.72rem; letter-spacing: 0.06em; color: var(--muted); }
.post__meta span + span::before { content: "·"; margin: 0 0.45rem; }

/* ---------- article ---------- */
.read-bar { position: fixed; inset: 0 0 auto; height: 2px; z-index: 90; pointer-events: none; }
.read-bar span { display: block; width: 100%; height: 100%; background: var(--gold); transform: scaleX(0); transform-origin: left center; }
.article { padding-bottom: clamp(2.5rem, 5vw, 4rem); }
.article__head { max-width: 44rem; margin: 0 auto clamp(1.5rem, 3vw, 2.25rem); padding-inline: var(--gutter); text-align: center; }
.article__title { margin: 0.45rem 0 0.8rem; font-size: clamp(1.6rem, 1.25rem + 1.6vw, 2.5rem); font-weight: 300; line-height: 1.16; }
.article__meta { margin: 0; font-size: 0.75rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.article__meta span + span::before { content: "·"; margin: 0 0.5rem; }
.article__hero { margin: 0 auto clamp(1.75rem, 4vw, 3rem); max-width: 68rem; padding-inline: var(--gutter); }
.article__hero figure { margin: 0; overflow: hidden; border-radius: var(--radius); background: var(--photo-ground); aspect-ratio: 16 / 9; }
.article__hero img { width: 100%; height: 100%; object-fit: cover; }
/* Wider measure (3 Oct, owner: too much scrolling): ~85 characters a line on a
   laptop instead of ~54, with slightly tighter leading and spacing. */
.article__body { max-width: 50rem; margin-inline: auto; padding-inline: var(--gutter); font-size: 1.02rem; line-height: 1.7; color: var(--ink-2); }
.article__body p { margin: 0 0 0.95em; }
@media (max-width: 699px) { .article__body { font-size: 0.96rem; line-height: 1.65; } }
.article__body p:first-of-type { font-size: 1.1rem; color: var(--ink); }
.article__body strong { color: var(--ink); }
.article__h3 { margin: 1.35em 0 0.4em; font-size: 0.98rem; font-weight: 700; line-height: 1.45; color: var(--ink); }
.article__list { margin: 0 0 1.05em; padding-left: 1.3em; }
.article__list li { margin: 0 0 0.3em; padding-left: 0.2em; }
.article__list li::marker { color: var(--gold); }
.article__cta { margin: 1.8em 0; }
.article__draft { max-width: 50rem; margin: 2rem auto 0; padding: 0.85rem 1.05rem; border: 1px dashed var(--line-2); border-radius: var(--radius-sm); font-size: 0.8rem; color: var(--muted); }

/* ---------- about ---------- */
.namestory { max-width: 44rem; margin-inline: auto; text-align: center; }
.namestory p { margin: 0 0 1em; color: var(--ink-2); }
.namestory em { color: var(--gold); font-style: normal; }
.team { display: grid; gap: clamp(1rem, 2.5vw, 1.75rem); margin: 0; padding: 0; list-style: none; }
@media (min-width: 820px) { .team { grid-template-columns: repeat(2, 1fr); } }
/* One card (owner removed Komal, 24 Sep): centred, at the width of one column. */
@media (min-width: 820px) { .team--solo { grid-template-columns: minmax(0, 36rem); justify-content: center; } }
.team__card { padding: clamp(1.25rem, 3vw, 1.85rem); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.team__card h3 { margin: 0 0 0.25rem; font-size: 1rem; font-weight: 600; }
.team__role { margin: 0 0 0.8rem; font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold); }
.team__card p { margin: 0; font-size: 0.9rem; color: var(--ink-2); }
.team__card p:not(.team__role) + p { margin-top: 0.75rem; }
.team__quote { margin: 1.1rem 0 0; padding-left: 1rem; border-left: 2px solid var(--gold-soft); }
.team__quote p { font-family: var(--display); font-style: italic; font-size: 1.15rem; line-height: 1.4; color: var(--ink); }
/* Founder card with his photo: beside the text from 640px, above it on phones. */
.team__card--photo { display: grid; gap: 1.25rem; }
.team__photo { width: 100%; max-width: 18rem; margin-inline: auto; aspect-ratio: 4 / 5; object-fit: cover; border-radius: calc(var(--radius) - 4px); background: var(--photo-ground); }
@media (min-width: 640px) { .team__card--photo { grid-template-columns: 15rem 1fr; align-items: center; gap: clamp(1.25rem, 3vw, 2rem); } .team__photo { max-width: none; align-self: start; } }
@media (min-width: 820px) { .team--solo:has(.team__card--photo) { grid-template-columns: minmax(0, 50rem); } }

/* ---------- contact ---------- */
.contact { display: grid; gap: clamp(1.75rem, 4vw, 3.5rem); }
@media (min-width: 900px) { .contact { grid-template-columns: 0.85fr 1.15fr; align-items: start; } }
.contact__cards { display: grid; gap: 0.85rem; margin: 0; padding: 0; list-style: none; }
.contact__card { display: flex; gap: 0.9rem; padding: 1.05rem 1.15rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.contact__card .i { flex: none; width: 1.35rem; height: 1.35rem; margin-top: 0.15rem; color: var(--gold); }
.contact__card h3 { margin: 0 0 0.2rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.contact__card p { margin: 0; font-size: 0.95rem; line-height: 1.5; }
.contact__card a:hover { color: var(--gold); }
.contact__form { max-width: 34rem; }
.field { display: grid; gap: 0.35rem; margin: 0 0 1rem; }
.field label { font-size: 0.76rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2); }
.field label span { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--muted); }
.field input, .field textarea {
  width: 100%; padding: 0.75rem 1rem; border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); background: var(--surface); font: inherit; color: var(--ink);
}
.field input { min-height: 3rem; }
.field textarea { resize: vertical; line-height: 1.6; }
.field input:focus-visible, .field textarea:focus-visible { border-color: var(--gold); }
.contact__note { margin: 0.9rem 0 0; font-size: 0.78rem; color: var(--muted); }

/* ---------- policy ---------- */
.policy { display: grid; gap: clamp(1.5rem, 4vw, 3.5rem); }
@media (min-width: 900px) {
  .policy { grid-template-columns: 15rem 1fr; align-items: start; }
  .policy__nav { position: sticky; top: calc(var(--top) + 2rem); }
}
.policy__nav { display: grid; gap: 0.2rem; align-content: start; }
.policy__nav a { display: block; padding: 0.65rem 0.95rem; border-radius: var(--radius-sm); font-size: 0.9rem; color: var(--ink-2); transition: background-color 0.3s, color 0.3s; }
.policy__nav a:hover { background: var(--tint); color: var(--ink); }
.policy__nav a[aria-current="page"] { background: var(--deep); color: var(--gold-bright); font-weight: 600; }
.policy__body { max-width: 40rem; }
.policy__body h2 { margin: 2rem 0 0.7rem; font-size: 0.78rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); }
.policy__body h2:first-child { margin-top: 0; }
.policy__body p { margin: 0 0 0.9em; color: var(--ink-2); line-height: 1.75; }
.policy__draft { margin: -0.75rem 0 2rem; padding: 0.8rem 1rem; border: 1px dashed var(--gold); border-radius: var(--radius); font-size: 0.85rem; color: var(--ink-2); }
.policy__body .lastup { margin-bottom: 2rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--line); font-size: 0.78rem; color: var(--muted); }
.policy__steps { margin: 0 0 0.9em; padding-left: 1.6rem; display: grid; gap: 0.7rem; }
.policy__steps li { color: var(--ink-2); line-height: 1.75; }
.policy__steps li::marker { font-weight: 700; color: var(--gold); }
.policy__bullets { margin: 0 0 0.9em; padding-left: 1.4rem; display: grid; gap: 0.5rem; }
.policy__bullets li { color: var(--ink-2); line-height: 1.7; }
.policy__bullets li::marker { color: var(--gold); }

/* ---------- article: figures, quotes, tags, share, prev/next ---------- */
.i-whatsapp { --i: url("../img/icons/whatsapp-logo.svg"); }
.i-link     { --i: url("../img/icons/link-linear.svg"); }

.article__h { margin: 2rem 0 0.7rem; font-size: 1.05rem; font-weight: 600; letter-spacing: 0.01em; color: var(--ink); }
.article__fig { margin: 2rem 0; }
/* Figures and galleries break out of the reading measure — the text column is
   34rem, the media is wider, which is what makes an editorial page feel airy. */
.article__fig, .article__gal { width: min(56rem, calc(100vw - var(--gutter) * 2)); margin-inline: calc(50% - min(28rem, 50vw - var(--gutter))); }
.article__fig img { width: 100%; border-radius: var(--radius); background: var(--photo-ground); }
.article__fig figcaption { margin-top: 0.65rem; font-size: 0.78rem; line-height: 1.5; color: var(--muted); text-align: center; }
.article__gal { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.6rem; margin-block: 2rem; padding: 0; list-style: none; }
@media (min-width: 700px) { .article__gal { grid-template-columns: repeat(4, 1fr); } }
.article__gal img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--radius-sm); background: var(--photo-ground); }

.pull {
  margin: 2rem 0; padding: 0 0 0 1.35rem; border-left: 2px solid var(--gold-soft);
  font-size: 1.14rem; line-height: 1.6; color: var(--ink);
}
.pull p { margin: 0; }

.tags { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; max-width: 34rem; margin: 2.5rem auto 0; padding-inline: var(--gutter); }
.tags__label { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.tags ul { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0; padding: 0; list-style: none; }
.tags li { padding: 0.3rem 0.7rem; border: 1px solid var(--line); border-radius: 999px; font-size: 0.74rem; color: var(--ink-2); }

.share { display: flex; align-items: center; gap: 0.7rem; max-width: 34rem; margin: 1.5rem auto 0; padding-inline: var(--gutter); }
.share__label { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.share ul { display: flex; gap: 0.45rem; margin: 0; padding: 0; list-style: none; }
.share a, .share button {
  display: grid; place-items: center; width: 2.2rem; height: 2.2rem; border-radius: 50%;
  border: 1px solid var(--line); color: var(--ink-2);
  transition: background-color var(--d-micro) var(--ease), color var(--d-micro) var(--ease),
              border-color var(--d-micro) var(--ease), translate var(--d-micro) var(--ease);
}
.share a:hover, .share button:hover { background: var(--deep); color: var(--gold-bright); border-color: transparent; translate: 0 -2px; }
.share .i { width: 0.95rem; height: 0.95rem; }

.artnav {
  display: grid; gap: 1rem; align-items: center;
  max-width: 46rem; margin: 3rem auto 0; padding: 1.5rem var(--gutter) 0;
  border-top: 1px solid var(--line);
}
@media (min-width: 760px) { .artnav { grid-template-columns: 1fr auto 1fr; } }
.artnav__item { display: grid; gap: 0.2rem; transition: translate var(--d-ui) var(--ease); }
.artnav__item span { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold); }
.artnav__item b { font-size: 0.92rem; font-weight: 500; line-height: 1.35; color: var(--ink); }
.artnav__item--next { text-align: right; }
.artnav__item--prev:hover { translate: -4px 0; }
.artnav__item--next:hover { translate: 4px 0; }
.artnav__back { font-size: 0.74rem; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.artnav__back:hover { color: var(--gold); }

/* ---------- card hover lift (micro, 160ms) ---------- */
.post, .card { transition: translate var(--d-micro) var(--ease); }
@media (hover: hover) {
  .post:hover, .card:hover { translate: 0 -3px; }
}

/* ---------- promise row reveal ---------- */
.promise { position: relative; padding-top: 1rem; }
.promise__rule { position: absolute; top: 0; left: 0; right: 0; height: 1px; background: var(--gold-soft); transform: scaleX(0); transform-origin: left center; }
/* Without motion the hairline is simply present and the text is never hidden. */
html:not(.has-motion) .promise__rule { transform: none; }
html.has-motion [data-promises] { visibility: hidden; }

/* ===========================================================================
   Apple HIG pass — Designing Fluid Interfaces (WWDC 2018) + The Details of
   UI Typography (WWDC 2020). Findings and measurements in PROJECT-STATUS.md.
   =========================================================================== */

/* ---------- 1. Response: feedback on pointer-down, never on release ------- */
/* Apple: "the moment lag appears, the feeling of directness falls off a
   cliff." Every touchable surface now answers the press itself. */
/* Not .cf__slide: the coverflow's spring writes its transform every frame,
   and a CSS transition on it chased each value 160ms late, which read as
   stutter and skipped frames (26 Sep). Its press feedback is on the img. */
.btn, .card, .post, .chip, .icon-btn, .cat__link, .cf__slide img,
.row-nav button, .qty button, .social a, .share a, .share button,
.policy__nav a, .artnav__item, .wa, .hero__dots button, .cf__dots button {
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--d-micro) var(--ease), opacity var(--d-micro) var(--ease),
              background-color var(--d-micro) var(--ease), color var(--d-micro) var(--ease),
              border-color var(--d-micro) var(--ease);
}
.btn:active, .wa:active { transform: scale(0.97); }
.card:active, .post:active { transform: scale(0.985); }
.chip:active, .row-nav button:active, .qty button:active,
.social a:active, .share a:active, .share button:active,
.policy__nav a:active { transform: scale(0.95); }
.icon-btn:active { transform: scale(0.9); background: var(--tint); }
.cf__slide:active img { transform: scale(0.985); }
.artnav__item:active { opacity: 0.6; }
.hero__dots button:active, .cf__dots button:active { transform: scale(1.4); }
/* A press must never be swallowed by a scroll-reveal transform. */
.card, .post { will-change: auto; }

/* ---------- 3. Touch targets: 44x44pt minimum ---------------------------- */
/* Hit area is expanded with an overlay so the visual size is untouched —
   the dots stay hairlines, they just stop being unhittable. */
.hero__dots button, .cf__dots button { position: relative; }
.hero__dots button::before { content: ""; position: absolute; inset: -21px -7px; }
.wordmark { position: relative; }
a.wordmark::before { content: ""; position: absolute; inset: -5px -8px; }

/* Discrete controls get 44px at every width. On a laptop these were 40-42px,
   so the change is a couple of pixels and costs nothing, while a trackpad at
   the edge of a 40px pill is genuinely fiddly. 2.75rem = 44px. */
.icon-btn { width: 2.75rem; height: 2.75rem; }
.chip { min-height: 2.75rem; }
.row-nav button { width: 2.75rem; height: 2.75rem; }
.qty button { width: 2.75rem; height: 3rem; }
/* .footer .social a is (0,3,0) and beat a bare .social a override. */
.footer .social a, ul.social a { width: 2.75rem; height: 2.75rem; }
.share a, .share button { width: 2.75rem; height: 2.75rem; }
.select select { min-height: 2.75rem; }
.shop-search button, .menu__search button { width: 2.75rem; height: 2.75rem; }
.policy__nav a { min-height: 2.75rem; display: flex; align-items: center; }
.link-arrow { min-height: 2.75rem; }

/* Text links are the exception. Making a footer link or a breadcrumb 44px tall
   and full-cell-wide is right for a thumb but adds a lot of dead vertical
   space for a cursor, so the row expansion stays touch-only. */
@media (pointer: coarse) {
  .footer nav ul a, .footer__contact ul a { min-height: 2.75rem; display: flex; align-items: center; width: 100%; }
  .menu__links a { min-height: 2.75rem; display: flex; align-items: center; }
  .crumbs a { min-height: 2.75rem; display: inline-flex; align-items: center; }
}

/* ---------- 4. Safe areas: clear the home indicator and the notch --------- */
.wa { bottom: calc(clamp(0.85rem, 2vw, 1.5rem) + env(safe-area-inset-bottom, 0px));
      right: calc(clamp(0.85rem, 2vw, 1.5rem) + env(safe-area-inset-right, 0px)); }
.toast { bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px)); }
.menu { padding-bottom: calc(2rem + env(safe-area-inset-bottom, 0px));
        padding-right: calc(var(--gutter) + env(safe-area-inset-right, 0px)); }
.footer__inner { padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px)); }
.container { padding-left: max(var(--gutter), env(safe-area-inset-left, 0px));
             padding-right: max(var(--gutter), env(safe-area-inset-right, 0px)); }

/* ---------- 9. Material: translucent chrome, content scrolls under -------- */
/* Apple treats nav as a floating functional layer, not an opaque strip. */
.site-header { background: rgba(255, 253, 252, 0.72); backdrop-filter: blur(20px) saturate(180%);
               -webkit-backdrop-filter: blur(20px) saturate(180%); border-bottom: 0; }
/* Scroll edge effect instead of a hard 1px divider — it only appears once
   content is actually passing underneath. */
.site-header::after {
  content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 14px;
  background: linear-gradient(180deg, rgba(23, 20, 15, 0.06), rgba(23, 20, 15, 0));
  opacity: 0; transition: opacity var(--d-ui) var(--ease); pointer-events: none;
}
.site-header.is-compact::after { opacity: 1; }
.site-header.is-compact { box-shadow: none; }

/* ---------- 10. Typography: tracking is size-specific -------------------- */
/* Large text reads too loose as it grows, small text too tight. One fixed
   value is wrong at one end. */
.hero__title { letter-spacing: 0.015em; }
.page-hero h1, .article__title, .feature__title, .pdp__title, .lost h1 { letter-spacing: -0.015em; }
.card__name, .post__title { letter-spacing: 0.01em; }

/* ---------- 11. Gesture ownership --------------------------------------- */
/* Horizontal drags belong to the carousel; vertical stays with the page. */
.cf__stage { touch-action: pan-y; }
.row, .article__gal { touch-action: pan-x pan-y; }

/* ---------- 12. Rubber-band, don't hard-stop ---------------------------- */
.row, .cf.is-flat .cf__stage { overscroll-behavior-x: contain; }
body { overscroll-behavior-y: none; }

/* ---------- 14. Reduced transparency and increased contrast -------------- */
@media (prefers-reduced-transparency: reduce) {
  .site-header { background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none;
                 border-bottom: 1px solid var(--line); }
  .hero__nav { background: var(--surface); backdrop-filter: none; color: var(--ink); }
  .menu__scrim { background: rgba(23, 20, 15, 0.7); }
}
@media (prefers-contrast: more) {
  :root { --line: rgba(23, 20, 15, 0.4); --line-2: rgba(23, 20, 15, 0.6); --muted: #4b443b; }
  .site-header { background: var(--surface); backdrop-filter: none; -webkit-backdrop-filter: none;
                 border-bottom: 2px solid var(--ink); }
  .btn--ghost, .chip, .field input, .field textarea { border-width: 2px; }
  .card__flag { outline: 1px solid var(--ink); }
}

/* ---------- 15. Motion blur on the one genuinely fast move --------------- */
/* Apple: for very fast motion a subtle blur encodes speed better than a
   hard sharp streak. Only the coverflow drag moves fast enough to matter. */
/* (The 0.4px blur while dragging is gone: a filter on 13 images repainted
   every frame and caused the stutter, 25 Sep.) */

/* ---------- 17. Tap hysteresis: a press can be cancelled ---------------- */
/* ~10px of slop around the target, so a slightly sloppy tap still lands and
   dragging away from it reads as a cancel rather than a mis-hit. */
.btn, .chip, .icon-btn, .row-nav button, .qty button { position: relative; }
.btn::after { content: ""; position: absolute; inset: -6px; border-radius: inherit; }
/* Dense controls get less slop than Apple's ~10px ideal on purpose: chips sit
   8px apart, so a -6px overlay on each would overlap by 4px and start
   stealing taps from its neighbour. Correct hit beats generous hit. */
.chip::after, .row-nav button::after, .qty button::after {
  content: ""; position: absolute; inset: -3px; border-radius: inherit;
}

/* Large moving surfaces should not fight legibility while they travel. */
.cf.is-dragging .cf__caption { opacity: 0.55; }
.cf__caption { transition: opacity var(--d-ui) var(--ease); }

/* Ease the theme ground so a dark/light swap is never an abrupt jump. */
body { transition: background-color var(--d-section) var(--ease); }
@media (prefers-reduced-motion: reduce) { body { transition: none; } }

/* =====================================================================
   Layout pass 2026-09-23: "Our favorites" shelf (after skanvi.com),
   four-across collection grid and strip (after jcojewellery.com),
   and page transitions.
   ===================================================================== */

/* ---- Our favorites ---- */
.favs__head { flex-direction: row; align-items: end; justify-content: space-between; text-align: left; }
.favs__title { font-family: var(--display); font-size: clamp(2rem, 1.2rem + 2.6vw, 3.2rem); font-weight: 500; font-style: italic; letter-spacing: 0.01em; text-transform: none; line-height: 1.1; padding-bottom: 0.06em; }
.favs__lede { max-width: 34rem; margin: 0.6rem 0 0; color: var(--muted); font-size: clamp(0.92rem, 0.88rem + 0.2vw, 1.02rem); }
.link-under { flex: none; padding-block: 0.4rem; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 6px; transition: color var(--d-ui) var(--ease); }
.link-under:hover { color: var(--gold); }
.chips--left { justify-content: flex-start; margin-bottom: clamp(1.25rem, 2.5vw, 1.75rem); }
.favs__shelf { position: relative; }
/* Exactly four cards across the container. cqw is the row's own width, so the
   maths holds at every screen size without media-query guesswork. */
.row--favs { container-type: inline-size; margin-inline: 0; padding-inline: 0; scroll-padding-inline: 0; }
/* phones keep the bleed to the screen edge so the next card peeks in */
@media (max-width: 640px) { .row--favs { margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); scroll-padding-inline: var(--gutter); } }
.row--favs .row__track { display: flex; grid-auto-flow: initial; grid-template-rows: none; gap: clamp(1rem, 1.8vw, 1.6rem); }
.row--favs .row__track > li { width: calc((100cqw - 3 * clamp(1rem, 1.8vw, 1.6rem)) / 4); }
.row--favs .card__media { aspect-ratio: 3 / 4; border-radius: 18px; }
.row--favs .card__body { display: grid; grid-template-columns: 1fr auto; grid-template-areas: "cat cat" "name price"; column-gap: 1rem; padding-top: 1rem; }
.row--favs .card__cat { grid-area: cat; margin: 0 0 0.35rem; font-size: 0.64rem; }
.row--favs .card__name { grid-area: name; min-height: 0; font-size: clamp(0.95rem, 0.9rem + 0.25vw, 1.1rem); font-weight: 600; -webkit-line-clamp: 2; }
.row--favs .card__price { grid-area: price; margin: 0 !important; flex-direction: column; align-items: flex-end; gap: 0.1rem; font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.05rem); font-weight: 500; white-space: nowrap; }
.row--favs .card__flag { top: 0.8rem; left: 0.8rem; padding: 0.3rem 0.62rem; font-size: 0.62rem; }
/* round arrows sitting on the shelf's edges, level with the photos */
.favs__nav { position: absolute; top: 0; z-index: 2; display: grid; place-items: center; width: 3.25rem; height: 3.25rem; border: 1px solid var(--line); border-radius: 50%;
  background: rgba(255, 255, 255, 0.92); color: var(--ink); box-shadow: 0 10px 30px -14px rgba(23, 20, 15, 0.45);
  transition: opacity var(--d-ui) var(--ease), background-color var(--d-ui) var(--ease), color var(--d-ui) var(--ease); }
.favs__nav--prev { left: calc(-1 * clamp(0.5rem, 1.6vw, 1.6rem)); }
.favs__nav--next { right: calc(-1 * clamp(0.5rem, 1.6vw, 1.6rem)); }
.favs__nav:disabled { opacity: 0; pointer-events: none; }
@media (hover: hover) and (pointer: fine) { .favs__nav:hover { background: var(--deep); color: #fff; } }
.favs__nav:active { transform: scale(0.95); }
/* photos are 3:4 of a quarter-width card; centre the arrows on them */
.favs__shelf { --photo-h: calc((min(100vw, var(--max)) - 2 * var(--gutter) - 3 * clamp(1rem, 1.8vw, 1.6rem)) / 4 * 4 / 3); }
.favs__nav { top: calc(var(--photo-h) / 2 - 1.625rem); }
/* the edge fade would dim the first and last photo; the arrows do that job */
.row--favs { -webkit-mask-image: none; mask-image: none; }
@media (max-width: 999px) {
  .row--favs .row__track > li { width: calc((100cqw - 2 * clamp(1rem, 1.8vw, 1.6rem)) / 2.6); }
  .favs__shelf { --photo-h: calc((100vw - 2 * var(--gutter)) / 2.6 * 4 / 3); }
}
@media (max-width: 640px) {
  .favs__head { flex-direction: column; align-items: flex-start; }
  .favs__nav { display: none; }
  .row--favs .row__track > li { width: 68vw; }
  .row--favs .card__body { grid-template-columns: 1fr; grid-template-areas: "cat" "name" "price"; }
  .row--favs .card__price { align-items: flex-start; flex-direction: row; margin-top: 0.35rem !important; }
}

/* ---- Collection grid: four across, square photos ---- */
.grid { grid-template-columns: repeat(2, 1fr); gap: clamp(2rem, 3.5vw, 3rem) clamp(0.75rem, 1.4vw, 1.25rem); }
@media (min-width: 700px) { .grid { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 1000px) { .grid { grid-template-columns: repeat(4, 1fr); } }
.grid .card__media { aspect-ratio: 1; border-radius: 4px; }
.grid .card__body { padding-top: 1.05rem; }
.grid .card__name { font-size: clamp(0.92rem, 0.88rem + 0.2vw, 1.02rem); min-height: 0; -webkit-line-clamp: 2; }
.grid .card__cat { margin: 0.3rem 0 0.45rem; }
.grid .card__price { font-weight: 500; }
.grid .card__flag { border-radius: 0; background: rgba(255, 255, 255, 0.94); color: var(--ink); top: auto; bottom: 0.8rem; left: auto; right: 0.8rem; letter-spacing: 0.14em; }
.grid .card__flag--out { background: var(--deep); color: #fff; }
/* sale: struck MRP first, then the price in the sale colour */
.card__price s { order: 0; }
.card__now { color: var(--sale); }

/* ---- Collection strip + ruled toolbar (shop page) ---- */
.cat-strip { position: relative; display: flex; flex-wrap: wrap; justify-content: center; gap: 0.25rem clamp(1rem, 3vw, 2.5rem); padding-block: 0.4rem; border-bottom: 1px solid var(--line); }
.cat-tab { position: relative; min-height: 2.75rem; padding: 0.5rem 0.15rem; font-size: 0.8rem; font-weight: 500; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-2);
  transition: color var(--d-ui) var(--ease); }
.cat-tab::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0.45rem; height: 1px; background: var(--ink); transform: scaleX(0); transition: transform var(--d-pop) var(--ease); }
.cat-tab[aria-pressed="true"] { color: var(--ink); }
.cat-tab[aria-pressed="true"]::after { transform: scaleX(1); }
@media (hover: hover) and (pointer: fine) { .cat-tab:hover { color: var(--ink); } }
.cat-tab:active { transform: scale(0.97); }
.shop .toolbar { border-top: 0; padding-block: 0.9rem; }
@media (max-width: 640px) {
  .cat-strip { flex-wrap: nowrap; justify-content: flex-start; overflow-x: auto; scrollbar-width: none; margin-inline: calc(-1 * var(--gutter)); padding-inline: var(--gutter); }
  .cat-strip::-webkit-scrollbar { display: none; }
  .cat-tab { flex: none; }
}

/* ---- Page transitions: tile dissolve (29 Sep) ----
   Cross-document View Transitions, so there is no JS click-interceptor and
   no wait before a link starts loading. vt.js lays a sheet of tiles over the
   whole screen (header included, like the reference reels): the tiles cover
   the old page in random order, the pages swap underneath at the halfway
   mark, then the tiles clear off the new one. Browsers without support just
   navigate. */
@view-transition { navigation: auto; }
::view-transition-group(root) { animation: none; }
::view-transition-old(root) { animation: var(--d-tiles) linear both vt-tile-old; }
::view-transition-new(root) { animation: var(--d-tiles) linear both vt-tile-new; }
@keyframes vt-tile-old { 0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes vt-tile-new { 0%, 49.9% { opacity: 0; } 50%, 100% { opacity: 1; } }
.vt-tiles { position: fixed; inset: 0; z-index: 2147483000; display: grid; overflow: hidden; pointer-events: none; view-transition-name: vt-tiles; }
.vt-tiles i { display: block; background: var(--bg); opacity: 0; }
/* the tiles animate themselves inside a live layer; the layer itself holds still */
::view-transition-group(vt-tiles), ::view-transition-new(vt-tiles) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* ---- Scroll story (motion.js: revealWords, heroHandoff, pinStory) ---- */
/* the hero's photo layer sinks as it leaves; keep it inside the hero */
.hero { overflow: clip; }

.manifesto { padding-block: clamp(4rem, 10vw, 8.5rem); background: var(--bg); }
.manifesto__text {
  max-width: 54rem; margin: 0 auto; text-align: center;
  font-family: var(--display); font-weight: 500; font-style: italic;
  font-size: clamp(1.55rem, 0.95rem + 2.7vw, 3.1rem); line-height: 1.28; letter-spacing: 0.005em; color: var(--ink);
  text-wrap: balance;
}
.manifesto__text em { font-style: normal; color: var(--gold); }
.nobr { white-space: nowrap; }
.manifesto__mark { font-family: var(--wordmark); font-style: normal; font-weight: 900; font-size: 0.72em; letter-spacing: 0.06em; text-transform: uppercase; }
/* One word of the manifesto. --p (0-1) is set per word from scroll; the
   finished state is plain type. */
/* Inline, not inline-block: Chrome lets a line break after any inline-block,
   which pushed the comma after </em> onto its own line. Opacity only, so
   the sentence wraps exactly like normal text. */
.wr { opacity: calc(0.16 + 0.84 * var(--p, 1)); }

/* Pinned craft chapter: the figure's clip and the image scale are driven by
   GSAP; this only keeps the rounded corners crisp while it opens. */


/* ---- Offers (admin/offers.php, priced by api/offers.php) ---- */
.card__flag--offer, .grid .card__flag--offer { background: var(--deep); color: var(--gold-bright); }
.pdp__offer { display: flex; align-items: center; gap: 0.55rem; margin: -0.35rem 0 1.2rem; padding: 0.6rem 0.85rem; border: 1px solid var(--line-gold);
  border-radius: var(--radius-sm); background: var(--champagne); font-size: 0.86rem; color: var(--ink-2); }
.pdp__offer .i { flex: none; color: var(--gold); }
.pdp__offer b { color: var(--ink); font-weight: 700; }

/* ---- Photo swipes (app.js gallery + lightbox) ---- */
/* the next photo riding alongside the current one while a swipe is in progress */
.pdp__ghost { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
.lightbox__count { position: absolute; top: max(1.05rem, env(safe-area-inset-top)); left: 1rem; z-index: 1; margin: 0; padding: 0.3rem 0.7rem;
  border-radius: 999px; background: rgba(255, 255, 255, 0.92); box-shadow: var(--shadow); font-size: 0.75rem; font-weight: 700;
  letter-spacing: 0.08em; font-variant-numeric: tabular-nums; color: var(--ink); }
.lightbox__count[hidden] { display: none; }

/* ---- Bag drawer (Phase 5; app.js bagUI) ---- */
.bag__scrim { position: fixed; inset: 0; z-index: 129; background: rgba(23, 20, 15, 0.45); }
.bag { position: fixed; inset: 0 0 0 auto; z-index: 130; display: flex; flex-direction: column; width: min(94vw, 27rem);
  background: var(--surface); box-shadow: -18px 0 48px -22px rgba(23, 20, 15, 0.45);
  padding-right: env(safe-area-inset-right, 0px); overscroll-behavior: contain; }
.bag[hidden], .bag__scrim[hidden] { display: none; }
body.bag-open { overflow: hidden; }
.bag__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.75rem 0.75rem 0.75rem 1.4rem; border-bottom: 1px solid var(--line); }
.bag__title { margin: 0; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.bag__n { color: var(--muted); letter-spacing: 0.06em; }
.bag__ship { padding: 0.85rem 1.4rem; background: var(--champagne); border-bottom: 1px solid var(--line-gold); font-size: 0.84rem; color: var(--ink-2); }
.bag__ship p { margin: 0 0 0.5rem; }
.bag__ship[hidden] { display: none; }
.bag__bar { display: block; height: 3px; border-radius: 3px; background: rgba(139, 100, 19, 0.15); overflow: hidden; }
.bag__bar span { display: block; height: 100%; background: var(--gold-soft); transform-origin: left; transform: scaleX(0); transition: transform var(--d-section) var(--ease); }
.bag__notices:empty { display: none; }
.bag__notices { padding: 0.75rem 1.4rem 0; display: grid; gap: 0.5rem; }
.bag__notice { margin: 0; padding: 0.6rem 0.8rem; border-radius: var(--radius-sm); background: var(--tint); font-size: 0.82rem; color: var(--ink-2); }
.bag__lines { flex: 1; margin: 0; padding: 0.5rem 1.4rem; overflow-y: auto; list-style: none; -webkit-overflow-scrolling: touch; }
.bag__empty { display: grid; justify-items: center; gap: 1rem; padding: 3rem 0; text-align: center; color: var(--muted); }
.bag__empty p { margin: 0; }
.bag-line { display: grid; grid-template-columns: 5.5rem 1fr auto; gap: 0.9rem; padding: 1rem 0; border-bottom: 1px solid var(--line); }
.bag-line:last-child { border-bottom: 0; }
.bag-line__img { display: block; aspect-ratio: 1; border-radius: var(--radius-sm); overflow: hidden; background: var(--photo-ground); }
.bag-line__img img { width: 100%; height: 100%; object-fit: cover; }
.bag-line__main { min-width: 0; display: grid; align-content: start; gap: 0.25rem; }
.bag-line__name { font-size: 0.9rem; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.bag-line__unit { margin: 0; font-size: 0.82rem; color: var(--ink-2); }
.bag-line__unit s { color: var(--muted); }
.bag-line__offer { margin: 0; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; color: var(--gold); }
.bag-line__row { display: flex; align-items: center; gap: 0.75rem; margin-top: 0.35rem; }
.qty--sm button { width: 2.2rem; height: 2.2rem; font-size: 1rem; }
.qty--sm output { min-width: 1.4rem; font-size: 0.88rem; }
.bag-line__remove { min-height: 2.75rem; font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
  text-decoration: underline; text-underline-offset: 4px; }
@media (hover: hover) and (pointer: fine) { .bag-line__remove:hover { color: var(--ink); } }
.bag-line__total { margin: 0; font-size: 0.92rem; font-weight: 700; white-space: nowrap; }
.bag__foot { padding: 1rem 1.4rem calc(1.2rem + env(safe-area-inset-bottom, 0px)); border-top: 1px solid var(--line); background: var(--bg); }
.bag__foot[hidden] { display: none; }
.bag__code { display: flex; gap: 0.5rem; }
.bag__code input { flex: 1; min-width: 0; min-height: 2.75rem; padding: 0 1rem; border: 1px solid var(--line-2); border-radius: 999px; background: var(--surface);
  font-size: 16px; letter-spacing: 0.06em; text-transform: uppercase; }
.bag__code input::placeholder { text-transform: none; letter-spacing: 0; }
.bag__code-msg { margin: 0.4rem 0 0; min-height: 1.1em; font-size: 0.8rem; color: var(--muted); }
.bag__code-msg.is-ok { color: #1e6b34; }
.bag__code-msg.is-bad { color: var(--rose-hi); }
.bag__sum { display: grid; gap: 0.35rem; margin: 0.6rem 0 1rem; font-size: 0.88rem; }
.bag__sum div { display: flex; justify-content: space-between; gap: 1rem; }
.bag__sum dt { color: var(--ink-2); }
.bag__sum dd { margin: 0; font-variant-numeric: tabular-nums; }
.bag__sum .is-save dd { color: #1e6b34; }
.bag__sum .is-total { margin-top: 0.35rem; padding-top: 0.6rem; border-top: 1px solid var(--line); font-size: 1rem; font-weight: 700; }
.bag__sum .is-total dt { color: var(--ink); }
.bag__note { margin: 0.7rem 0 0; text-align: center; font-size: 0.74rem; color: var(--muted); }
/* while a new price is on its way, the numbers dim rather than jump */
.bag.is-pricing .bag__sum, .bag.is-pricing .bag-line__total { opacity: 0.45; transition: opacity var(--d-micro) var(--ease); }

/* Floating things never cover each other (playbook Phase 5): the WhatsApp
   button steps up while a toast is showing on narrow screens, and hides while
   the bag is open so it cannot sit on top of Checkout. */
.wa { transition: background-color 0.3s, scale 0.3s var(--ease), translate var(--d-pop) var(--ease), opacity var(--d-ui) var(--ease); }
@media (max-width: 760px) { body:has(.toast.is-on) .wa { translate: 0 -4.4rem; } }
body.bag-open .wa, body.menu-open .wa { opacity: 0; pointer-events: none; }

/* ---- Checkout (Phase 6; app.js checkout) ---- */
.checkout__wrap { padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(3rem, 6vw, 5rem); }
.checkout__title { margin: 0 0 1rem; font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(1.9rem, 1.3rem + 2vw, 2.8rem); line-height: 1.1; padding-bottom: 0.06em; }
.steps { display: flex; gap: clamp(0.75rem, 3vw, 2rem); margin: 0 0 clamp(1.25rem, 3vw, 2rem); padding: 0 0 0.9rem; border-bottom: 1px solid var(--line); list-style: none;
  font-size: 0.72rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.steps[hidden] { display: none; }
.steps li { display: flex; align-items: center; gap: 0.5rem; }
.steps span { display: grid; place-items: center; width: 1.6rem; height: 1.6rem; border: 1px solid var(--line-2); border-radius: 50%; font-size: 0.7rem; letter-spacing: 0; }
.steps [aria-current="step"] { color: var(--ink); }
.steps [aria-current="step"] span { background: var(--deep); border-color: var(--deep); color: #fff; }
.steps .is-done span { background: var(--gold-soft); border-color: var(--gold-soft); color: #fff; }
.checkout__grid { display: grid; gap: clamp(1.5rem, 3vw, 3rem); align-items: start; }
@media (min-width: 900px) {
  .checkout__grid { grid-template-columns: minmax(0, 1fr) minmax(19rem, 25rem); }
  .checkout__side { position: sticky; top: calc(var(--top) + 1rem); order: 2; }
}
@media (max-width: 899px) { .checkout__side { order: -1; } }
.checkout__side[hidden] { display: none; }
.checkout__h { margin: 0 0 1rem; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; }
.checkout__h:focus { outline: none; }
.checkout__empty { display: grid; justify-items: start; gap: 1rem; padding: 2rem 0; color: var(--muted); }
.checkout__empty p { margin: 0; }

.co-form { display: grid; gap: 1.5rem; }
.co-form fieldset { display: grid; gap: 1rem; margin: 0; padding: 0; border: 0; min-width: 0; }
.co-form legend { margin-bottom: 0.9rem; padding: 0; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.co-row { display: grid; gap: 1rem; }
@media (min-width: 640px) { .co-row { grid-template-columns: 1fr 1fr; } .co-row--3 { grid-template-columns: 9rem 1fr 1fr; } }
.co-field { display: grid; gap: 0.35rem; align-content: start; min-width: 0; }
.co-field label { font-size: 0.82rem; font-weight: 600; color: var(--ink-2); }
.co-opt { font-weight: 400; color: var(--muted); }
.co-field input, .select--block select { width: 100%; min-height: 3rem; padding: 0 0.95rem; border: 1px solid var(--line-2); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink); font: inherit; font-size: 16px; transition: border-color var(--d-ui) var(--ease), box-shadow var(--d-ui) var(--ease); }
.co-field input:focus-visible, .select--block select:focus-visible { outline: none; border-color: var(--deep); box-shadow: 0 0 0 3px rgba(201, 162, 74, 0.35); }
.co-field.has-error input, .co-field.has-error select { border-color: var(--rose-hi); }
.co-err { margin: 0; font-size: 0.8rem; font-weight: 600; color: var(--rose-hi); }
.co-hint { margin: 0; min-height: 1em; font-size: 0.76rem; color: var(--muted); }
.co-hint:empty { display: none; }
.co-hint.is-warn { color: var(--rose-hi); }
.co-prefix { position: relative; }
.co-prefix span { position: absolute; left: 0.95rem; top: 50%; transform: translateY(-50%); font-size: 16px; color: var(--muted); pointer-events: none; }
.co-prefix input { padding-left: 3.1rem; }
.select--block { display: block; width: 100%; }
.select--block select { padding-right: 2.4rem; border-radius: var(--radius-sm); font-size: 16px; }
.co-note { display: flex; align-items: center; gap: 0.5rem; margin: 0; font-size: 0.82rem; color: var(--muted); }
.co-note .i { color: var(--gold); }
.co-banner { margin: 0 0 1rem; padding: 0.8rem 1rem; border-radius: var(--radius-sm); background: #fbeceb; color: var(--rose-hi); font-size: 0.88rem; font-weight: 600; }
/* Payment choice (cash on delivery, Oct 2026) and the WhatsApp code. */
.co-pay { display: grid; gap: 0.6rem; margin: 0.4rem 0 0; padding: 0; border: 0; }
.co-pay__opt { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.85rem 1rem; border: 1px solid var(--line-2); border-radius: var(--radius-sm); cursor: pointer;
  transition: border-color var(--d-ui) var(--ease), box-shadow var(--d-ui) var(--ease); }
.co-pay__opt:has(input:checked) { border-color: var(--deep); box-shadow: 0 0 0 1px var(--deep); }
.co-pay__opt input { flex: none; margin: 0.2rem 0 0; accent-color: var(--deep); }
.co-pay__opt > span { display: grid; gap: 0.15rem; }
.co-pay__opt small { font-size: 0.78rem; color: var(--muted); }
.co-pay__opt.is-off { opacity: 0.6; cursor: not-allowed; }
.co-otp { display: grid; gap: 0.9rem; margin-top: 0.8rem; }
.co-otp input { font-size: 1.25rem; letter-spacing: 0.45em; text-align: center; }
.co-otp__again { margin: 0.7rem 0 0; }
.co-card { margin-bottom: 1rem; padding: 1rem 1.15rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.co-card p { margin: 0; font-size: 0.9rem; line-height: 1.6; color: var(--ink-2); }
.co-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: 0.4rem; }
.co-card__head h3 { margin: 0; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); }
.co-card--total .bag__sum { margin: 0 0 0.5rem; }
.co-card--done { display: flex; align-items: center; gap: 0.8rem; background: var(--champagne); border-color: var(--line-gold); }
.co-card--done .i { flex: none; color: var(--gold); width: 1.4rem; height: 1.4rem; }
.co-small { margin: 0.75rem 0 1rem; font-size: 0.8rem; color: var(--muted); text-align: center; }
[data-place].is-busy, [data-pay].is-busy { opacity: 0.7; cursor: progress; }
.co-done-text { margin: 0 0 1.25rem; color: var(--ink-2); font-size: 0.95rem; }
.co-spin { flex: none; width: 1.4rem; height: 1.4rem; border-radius: 50%; border: 2px solid var(--line-gold); border-top-color: var(--gold); animation: co-spin 0.9s linear infinite; }
@keyframes co-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .co-spin { animation-duration: 2.4s; } }

/* order summary */
.osum { padding: 1.1rem 1.2rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.osum > summary { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 2.75rem; cursor: pointer; list-style: none;
  font-size: 0.8rem; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; }
.osum > summary::-webkit-details-marker { display: none; }
.osum > summary small { font-weight: 400; letter-spacing: 0.04em; text-transform: none; color: var(--muted); }
.osum > summary b { font-size: 1rem; letter-spacing: 0; }
.osum > summary::after { content: ""; width: 0.45rem; height: 0.45rem; margin-left: 0.25rem; border-right: 1.5px solid var(--ink); border-bottom: 1.5px solid var(--ink); transform: rotate(45deg); transition: transform var(--d-ui) var(--ease); }
.osum[open] > summary::after { transform: rotate(-135deg); }
.osum__lines { display: grid; gap: 0.85rem; margin: 0.9rem 0 1rem; padding: 0; list-style: none; }
.osum__lines li { display: grid; grid-template-columns: 3.5rem 1fr auto; gap: 0.8rem; align-items: center; font-size: 0.86rem; }
.osum__img { position: relative; display: block; aspect-ratio: 1; border-radius: var(--radius-sm); background: var(--photo-ground); }
.osum__img img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.osum__img i { position: absolute; top: -0.4rem; right: -0.4rem; display: grid; place-items: center; min-width: 1.25rem; height: 1.25rem; padding: 0 0.3rem;
  border-radius: 1rem; background: var(--deep); color: #fff; font-size: 0.66rem; font-style: normal; font-weight: 700; }
.osum__name { display: grid; line-height: 1.35; }
.osum__name small { color: var(--gold); font-size: 0.72rem; font-weight: 600; }
.osum__price { font-weight: 700; white-space: nowrap; }
.osum__code { margin-top: 0.25rem; }
.osum__gst { margin: 0; font-size: 0.76rem; color: var(--muted); }
.osum__edit { display: block; margin-top: 0.9rem; }
.osum--loading { display: grid; gap: 0.6rem; }

/* Collection intro under the shop grid (Phase 11, copy in assets/data/seo.json) */
.shop-about { max-width: 44rem; margin: clamp(3rem, 6vw, 5rem) 0 0; padding-top: clamp(1.5rem, 3vw, 2rem); border-top: 1px solid var(--line); }
.shop-about__title { margin: 0 0 0.75rem; font-size: 1.1rem; font-weight: 600; letter-spacing: 0.02em; }
.shop-about__body p { margin: 0 0 0.75rem; color: var(--ink-2); line-height: 1.7; }

/* ---------- Phase 11: save, share, reviews, consent ---------- */
.pdp__tools { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 1.4rem; }
.pdp__tool { display: inline-flex; align-items: center; gap: 0.45rem; min-height: 44px; padding: 0 1rem; border: 1px solid var(--line-2);
  border-radius: 999px; font-size: 0.85rem; font-weight: 600; color: var(--ink); transition: border-color var(--d-ui), background-color var(--d-ui), color var(--d-ui); }
.pdp__tool:hover { border-color: var(--ink); }
.pdp__tool:active { transform: scale(0.97); }
.pdp__tool.is-on { border-color: var(--rose); color: var(--rose-hi); background: var(--tint); }
.pdp__tool .i { width: 1.05rem; height: 1.05rem; }
.stars { color: var(--gold-soft); letter-spacing: 0.08em; }
.pdp__rating { display: inline-flex; align-items: center; gap: 0.4rem; margin: -0.2rem 0 0.7rem; font-size: 0.88rem; text-decoration: none; color: var(--ink-2); }
.pdp__rating:hover { color: var(--ink); }

.reviews { margin-block: clamp(3rem, 7vw, 5rem); }
.reviews__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem 1.5rem; padding-bottom: 1.25rem; border-bottom: 1px solid var(--line); }
.reviews__head .section-title { margin: 0; }
.reviews__summary { flex: 1 1 16rem; margin: 0; color: var(--ink-2); }
.reviews__list { list-style: none; margin: 0; padding: 0; }
.review { padding: 1.4rem 0; border-bottom: 1px solid var(--line); }
.review p { margin: 0; }
.review__body { margin: 0.5rem 0 0.6rem !important; max-width: 46rem; line-height: 1.7; color: var(--ink); }
.review__who { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.6rem; font-size: 0.86rem; color: var(--ink-2); }
.review__who time { color: var(--muted); }
.review__verified { padding: 0.1rem 0.55rem; border-radius: 999px; background: var(--champagne); color: var(--gold); font-size: 0.72rem; font-weight: 700; }

.review-form { display: grid; gap: 1rem; max-width: 40rem; margin: 1.5rem 0; padding: clamp(1.1rem, 3vw, 1.6rem); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.review-form textarea { width: 100%; padding: 0.75rem 0.95rem; border: 1px solid var(--line-2); border-radius: var(--radius-sm); font: inherit; resize: vertical; }
.review-form textarea:focus-visible { outline: none; border-color: var(--deep); box-shadow: 0 0 0 3px rgba(201, 162, 74, 0.35); }
.review-form__stars { margin: 0; padding: 0; border: 0; }
.review-form__stars legend { margin-bottom: 0.35rem; font-size: 0.82rem; font-weight: 600; color: var(--ink-2); }
.review-form__done { margin: 0; font-weight: 600; }
/* 1 -> 5 in the markup (arrow keys move the way they look). Choosing or hovering
   a star lights it and every star to its left, via :has(). */
.stars-input { display: inline-flex; gap: 0.15rem; }
.stars-input input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.stars-input label { display: grid; place-items: center; width: 44px; height: 44px; font-size: 1.6rem; line-height: 1; color: var(--line-2); cursor: pointer; transition: color var(--d-ui); }
.stars-input:has(input:nth-of-type(1):checked) label:nth-of-type(-n+1),
.stars-input:has(label:nth-of-type(1):hover) label:nth-of-type(-n+1),
.stars-input:has(input:nth-of-type(2):checked) label:nth-of-type(-n+2),
.stars-input:has(label:nth-of-type(2):hover) label:nth-of-type(-n+2),
.stars-input:has(input:nth-of-type(3):checked) label:nth-of-type(-n+3),
.stars-input:has(label:nth-of-type(3):hover) label:nth-of-type(-n+3),
.stars-input:has(input:nth-of-type(4):checked) label:nth-of-type(-n+4),
.stars-input:has(label:nth-of-type(4):hover) label:nth-of-type(-n+4),
.stars-input:has(input:nth-of-type(5):checked) label:nth-of-type(-n+5),
.stars-input:has(label:nth-of-type(5):hover) label:nth-of-type(-n+5) { color: var(--gold-soft); }
/* while hovering, the hovered count wins over the chosen one */
.stars-input:has(label:hover) label:hover ~ label { color: var(--line-2); }
.stars-input input:focus-visible + label { outline: 2px solid var(--gold-soft); outline-offset: 2px; border-radius: 6px; }
.stars-input.has-error label { color: var(--rose); }
/* honeypot: off-screen for people and screen readers, still in the form for bots */
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }

.home-reviews__list { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 18rem), 1fr)); margin: 0; padding: 0; list-style: none; }
.review--card { padding: 1.4rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.review__piece { display: inline-block; margin-top: 0.6rem; }

.consent { position: fixed; z-index: 60; left: 1rem; right: 1rem; bottom: 1rem; display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.25rem;
  max-width: 34rem; margin-inline: auto; padding: 1rem 1.1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.consent p { flex: 1 1 16rem; margin: 0; font-size: 0.88rem; color: var(--ink-2); }
.consent p a { color: var(--ink); }
.consent__actions { display: flex; gap: 0.5rem; }
.footer__consent { margin-left: auto; color: inherit; }

/* ---------- Phase 12: placeholders sized like the real content ---------- */
.grid .sk-media { aspect-ratio: 1; border-radius: 4px; }
.pdp .sk-media.pdp-sk__img { aspect-ratio: 4 / 3; border-radius: var(--radius); }
.pdp-sk__info { min-height: 26rem; }
.pdp-sk__title { height: 1.8rem; width: 80%; margin-top: 1rem; }
.pdp .sk-media.pdp-sk__buy { aspect-ratio: auto; height: 3rem; margin-top: 2rem; border-radius: 999px; }
/* The count ("11 pieces") is filled in by the script: keep its room from the
   start, or the sort control wraps to a new row and pushes the grid down. */
.toolbar .count { display: inline-block; min-width: 5rem; text-align: right; }
/* The collection strip is filled by the script: hold one row of tabs' height from the start. */
.cat-strip { min-height: calc(2.75rem + 0.8rem + 1px); }
/* Pages whose main content arrives from the script: hold the space while it
   loads (aria-busy is removed once it is in), so the footer never starts on
   screen and then jumps. */
.feature .feature__media.sk-media { aspect-ratio: 4 / 3; }
.feature-sk__title { height: 1.8rem; width: 85%; margin-top: 1rem; }
.article[aria-busy="true"], .policy__body[aria-busy="true"] { min-height: 100svh; }
/* Checkout: the form, the review or the empty-bag note all arrive from the
   script; the area keeps its height so the footer stays below the fold. */
.checkout__wrap { min-height: 75svh; }

/* =========================================================================
   Phone audit against Apple's guidelines (27 Sep). Desktop is unchanged
   except where noted.
   ========================================================================= */

/* 1. iOS Safari zooms the page into any field under 16px when it is tapped
   (every field here was 12.8-15.2px). 16px on phones and touch screens. */
@media (max-width: 767px), (pointer: coarse) {
  /* :not([data-x]) lifts select/textarea to (0,1,1), so they beat component
     rules like `.select select` (the shop's sort menu stayed at 12.8px). */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), select:not([data-x]), textarea:not([data-x]) { font-size: 16px; }
}

/* 2. Legible type on a phone: body 16px (was 14.15px; iOS body is 17pt), no
   uppercase label under 11.5px and no readable small text under 12px (some
   were 9-10px). The logo's "Bejewelled with" line is part of the lockup and
   keeps its size. */
@media (max-width: 699px) {
  :root { --fs-body: 1rem; }
  .eyebrow, .card__cat, .row__track .card__cat, .row--favs .card__cat, .footer h3, .pdp__specs dt,
  .reel__kicker, .cat__count, .cf__view, .post__tag, .artnav__item span, .steps, .steps span, .osum__img i,
  .chip, .crumbs, .tags__label, .share__label, .demo-bar, .team__role, .contact__card h3, .pdp__codes dt,
  .pdp__deliver label, .co-form legend, .co-card__head h3, .hero__kicker { font-size: 0.72rem; }
  .card__flag, .row__track .card__flag, .row--favs .card__flag, .card__save, .pdp__save, .post__meta,
  .link-arrow, .link-under, .signup__note, .bag-line__offer, .bag-line__remove, .bag__note,
  .osum__name small, .osum > summary small, .review__verified, .tags li, .artnav__back, .lightbox__hint { font-size: 0.75rem; }
}

/* 8. The last targets under 44pt: "View all" / "Keep browsing" / "Edit bag"
   (.link-under, 32px tall), breadcrumb words (37-39px wide), the shop search
   field (40px), short chips ("All", 34px wide) and the coverflow dots (24px). */
@media (pointer: coarse), (max-width: 699px) {
  .link-under { min-height: 2.75rem; display: inline-flex; align-items: center; }
  .crumbs a { min-width: 2.75rem; justify-content: center; }
  .chip { min-width: 2.75rem; }
  /* the tab's underline spans the element, so widen only the hit area */
  .cat-tab::before { content: ""; position: absolute; inset: 0 -6px; }
  .shop-search input { min-height: 2.75rem; }
  .cf__dots button::before { content: ""; position: absolute; inset: -10px; }
}

/* 4-5. Horizontal drags on the hero and the side panels are handled in JS;
   vertical movement stays the page's (and the panel's own) native scroll. */
/* The bag's list scrolls on its own, and a scroll container starts a fresh
   touch-action ("auto") instead of inheriting, so it needs its own pan-y or
   the browser claims the horizontal drag (pointercancel). */
.hero__stage, .menu, .bag, .bag__lines { touch-action: pan-y; }

/* 9. Large mixed-case display type tightens as it grows (Apple: tracking is
   size-specific). Uppercase labels keep their positive tracking. */
.favs__title { letter-spacing: -0.01em; }

/* 6. The WhatsApp button steps aside while reading (scrolling down) and comes
   back on scrolling up, instead of sitting over the page's bottom corner. */
.wa.is-away { opacity: 0; translate: 0 140%; pointer-events: none; }

/* 7. Product page on a phone: the buy button was ~700px down. A slim bar with
   the price and the page's own button appears while that button is off screen. */
.pdp-bar { display: none; }
@media (max-width: 699px) {
  .pdp-bar {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    display: flex; align-items: center; gap: 0.75rem;
    padding: 0.6rem var(--gutter) calc(0.6rem + env(safe-area-inset-bottom, 0px));
    background: rgba(255, 253, 252, 0.86); -webkit-backdrop-filter: blur(20px) saturate(1.8); backdrop-filter: blur(20px) saturate(1.8);
    border-top: 1px solid var(--line);
    translate: 0 110%; opacity: 0; pointer-events: none;
    transition: translate var(--d-pop) var(--ease), opacity var(--d-ui) var(--ease);
  }
  .pdp-bar.is-on { translate: 0 0; opacity: 1; pointer-events: auto; }
  .pdp-bar__info { min-width: 0; flex: 1; display: grid; }
  .pdp-bar__name { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 0.8rem; color: var(--ink-2); }
  .pdp-bar__price { font-weight: 700; font-size: 1rem; }
  .pdp-bar .btn { flex: none; min-height: 2.75rem; padding-inline: 1.3rem; }
  /* the WhatsApp button rides above the bar instead of covering it */
  body.pdp-bar-on .wa { translate: 0 calc(-3.9rem - env(safe-area-inset-bottom, 0px)); }
  body.pdp-bar-on .footer { padding-bottom: 5rem; }
}
@media (prefers-reduced-transparency: reduce) { .pdp-bar { background: var(--surface); -webkit-backdrop-filter: none; backdrop-filter: none; } }
@media (prefers-reduced-motion: reduce) { .pdp-bar, .wa { transition: opacity var(--d-ui) linear; } .pdp-bar { translate: 0 0; } }

/* =====================================================================
   Home opening, 29 Sep (after represent.com and bershka.com).
   The hero fills the screen with the SMITHLLERY lockup large in the middle;
   the header floats over it, see-through with white type. Scrolling flies
   the lockup up into the header's own wordmark slot (motion.js heroStack)
   while the hero stays put (sticky) and the sheet holding "Our favorites"
   and the manifesto slides over it like a page. Once the sheet reaches the
   header, the header turns back into the usual frosted bar (app.js header).
   No top bar on the home page, so --bar-h is 0 there.
   ===================================================================== */
[data-page="home"] { --bar-h: 0px; }
.site-header[data-over-hero] { position: fixed; top: 0; left: 0; right: 0;
  transition: background-color var(--d-section) var(--ease), box-shadow 0.45s var(--ease); }
.nav__links > a, .nav__drop-btn, .icon-btn, .wordmark__name { transition: color var(--d-section) var(--ease), background-color 0.3s; }
/* over the photo (JS only: without it the header keeps its frosted look) */
.js .site-header[data-over-hero]:not(.is-solid) { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
.js .site-header[data-over-hero]:not(.is-solid)::after { opacity: 0; }
.js .site-header[data-over-hero]:not(.is-solid) :is(.nav__links > a, .nav__drop-btn, .icon-btn, .wordmark__name) { color: #fff; }
.js .site-header[data-over-hero]:not(.is-solid) .icon-btn:hover { background: rgba(255, 255, 255, 0.14); }
.js .site-header[data-over-hero]:not(.is-solid) :is(.wordmark__name, .wordmark__tag) { background: var(--logo-gold-bright); }
.js .site-header[data-over-hero]:not(.is-solid) .bag-count { background: #fff; color: var(--ink); }
/* the header's own wordmark waits for the big lockup to land in its slot */
html.has-motion .site-header[data-over-hero]:not(.is-solid) .wordmark { opacity: 0; }

.stack { position: relative; }
.stack .hero { position: sticky; top: 0; z-index: 0; height: 100vh; height: 100svh; background: #0b0a08; }
.stack .hero__stage { height: 100%; }
.stack__sheet { position: relative; z-index: 1; background: var(--bg); box-shadow: 0 -30px 60px -34px rgba(14, 12, 9, 0.6); }
/* darker at the top for the header, and at the bottom for the line of copy */
.stack .hero__slide::after { background: linear-gradient(180deg, rgba(14, 12, 9, 0.36) 0%, rgba(14, 12, 9, 0.1) 26%, rgba(14, 12, 9, 0.12) 58%, rgba(14, 12, 9, 0.58) 100%); }
.stack .hero__slide { align-items: end; }
.stack .hero__inner { justify-content: flex-start; padding-bottom: clamp(3.4rem, 9vh, 5.5rem); }
.stack .hero__text { max-width: 30rem; text-align: left; }
.stack .hero__title { margin-bottom: 0.8rem; font-size: clamp(1.3rem, 0.95rem + 1.4vw, 2.3rem); }
.hero__link { display: inline-flex; align-items: center; gap: 0.55rem; padding-bottom: 0.35rem; border-bottom: 1px solid rgba(255, 255, 255, 0.6);
  color: #fff; font-size: 0.74rem; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase;
  transition: color var(--d-ui) var(--ease), border-color var(--d-ui) var(--ease); }
.hero__link .i { transition: transform 0.45s var(--ease); }
.hero__link:hover { color: var(--gold-bright); border-color: var(--gold-bright); }
.hero__link:hover .i { transform: translateX(4px); }

/* The big lockup (29 Sep, second pass: smaller so the photo shows, no gold
   rule, the tagline centred and brighter). SMITHLLERY sits on a champagne
   extrusion (stacked text-shadows, in em so it scales with the flight) and
   tilts gently towards the pointer (motion.js heroStack, .hero__brand-3d);
   the tagline floats a little in front of it, so the tilt reads as depth.
   The flight lines the name up with the header's own SMITHLLERY; the
   tagline fades out on the way up and the header's fades in on landing. */
.hero__brand { position: absolute; inset: 0; z-index: 3; width: fit-content; height: fit-content; margin: auto;
  line-height: 1; color: #fff; pointer-events: none; perspective: 900px;
  font-size: clamp(1.35rem, 0.55rem + 2.7vw, 3.3rem); will-change: transform; }
/* the logo is about 7.5em tall: cap it by the screen's height as well, so a short
   laptop window keeps it clear of the caption (Rigved, 9 Oct: "too big, covering
   the text"; then "a little smaller, at the top": about 80% of the first size) */
.hero__brand { font-size: min(clamp(1.1rem, 0.45rem + 2.15vw, 2.6rem), 3.8vh); }
@supports (height: 1svh) { .hero__brand { font-size: min(clamp(1.1rem, 0.45rem + 2.15vw, 2.6rem), 3.8svh); } }
.hero__brand-3d { display: flex; flex-direction: column; align-items: center; transform-style: preserve-3d; }
/* The owner's gold logo (9 Oct; final polished artwork 13 Oct, which adds a
   reflection under the name) replaced the typeset lockup: five images cut
   from it by scripts/process-logo.py, each sized from its pixel size so they
   stack back into the artwork (--k = em per source pixel; the name is 1.3em
   tall, as the typeset name was). The rows are nudged sideways to the
   artwork's own centres, by `left`, never a transform on the name: motion.js
   measures the name for the flight. */
.hero__brand { --k: calc(1.3em / 104); }
.hero__brand-3d img { display: block; max-width: none; height: auto;
  filter: drop-shadow(0 0.03em 0.08em rgba(14, 12, 9, 0.5)); }
.hero__brand-wings { position: relative; left: calc(0.5 * var(--k)); width: calc(819 * var(--k)); margin-bottom: calc(14 * var(--k)); }
.hero__brand-rule { position: relative; left: calc(6.5 * var(--k)); width: calc(805 * var(--k)); margin-bottom: calc(16 * var(--k)); }
.hero__brand-name { width: calc(818 * var(--k)); }
.hero__brand-reflect { position: relative; left: calc(-18 * var(--k)); width: calc(782 * var(--k)); }
.hero__brand-sub { position: relative; left: calc(0.5 * var(--k)); width: calc(819 * var(--k)); margin-top: calc(49 * var(--k)); }
/* Every screen (9 Oct, Rigved: "at the top"): the logo sits centred just under
   the header, clear of the caption at the bottom left. Positioned with margins,
   not a transform, so motion.js heroStack still measures the real spot. */
.stack .hero__brand { margin: calc(var(--header-h) + 3vh) auto auto; margin-top: calc(var(--header-h) + 3svh); }
/* on landing, the header's lockup has no rule either (its tag hides once the bar turns solid) */
.js .site-header[data-over-hero]:not(.is-solid) .wordmark__tag::before { display: none; }

/* "Our favorites", first on the sheet: title and View all only */
@media (max-width: 640px) { .favs__head { flex-direction: row; align-items: baseline; } }

/* ---- "You may also love": a slow endless strip (product page, 29 Sep) ----
   app.js drift() repeats the pieces until one run is wider than the screen,
   then doubles it, so sliding by -50% loops without a seam. Each card carries
   its gap as margin (a flex gap would leave the loop half a gap off). Hover
   or focus holds it still; reduced motion gets a normal sideways scroll. */
.related { padding-bottom: clamp(3.5rem, 7vw, 6rem); }
.drift { overflow: hidden; }
.drift__track { display: flex; width: max-content; margin: 0; padding: 0; list-style: none;
  animation: drift var(--drift-dur, 60s) linear infinite; }
.drift__track > li { flex: none; width: clamp(13rem, 21vw, 19rem); margin-right: clamp(0.9rem, 1.6vw, 1.4rem); }
/* Keeps moving under the mouse (owner, 1 Oct); holds for keyboard users. */
.drift:has(:focus-visible) .drift__track { animation-play-state: paused; }
@keyframes drift { to { transform: translateX(-50%); } }
.drift .card__media { aspect-ratio: 1; border-radius: 4px; }
.drift .card__body { padding-top: 1.05rem; }
.drift .card__name { font-size: clamp(0.92rem, 0.88rem + 0.2vw, 1.02rem); min-height: 0; -webkit-line-clamp: 2; }
.drift .card__cat { margin: 0.3rem 0 0.45rem; }
.drift .card__price { font-weight: 500; }
.drift.is-static { overflow-x: auto; scrollbar-width: none; }
.drift.is-static .drift__track { animation: none; padding-inline: var(--gutter); }
@media (prefers-reduced-motion: reduce) {
  .drift { overflow-x: auto; scrollbar-width: none; }
  .drift__track { animation: none; padding-inline: var(--gutter); }
}

/* ---- Product page layout (every piece since 30 Sep; app.js product) ----
   From 900px: name and description pinned on the left, price and bag button
   pinned on the right, the photos stacked in the middle. Each photo keeps its
   own shape (the studio shots are square, the satin ones 3:2), no taller than
   the screen. Phones: the photos run full width, one under another. */
.pdp__stack { display: none; }
/* Phones: the photos run full width, one under another, instead of the swipe
   gallery; name, price and bag follow, and the slim buy bar (pdp-bar) rides
   at the foot while the button is off screen. A tap opens the lightbox. */
@media (max-width: 899px) {
  .pdp--ed .pdp__gallery { display: none; }
  .pdp--ed .pdp__stack { display: grid; gap: 0.35rem; margin-inline: calc(-1 * var(--gutter)); }
  .pdp--ed .pdp__shot { margin: 0; background: #fff; }
  .pdp--ed .pdp__shot img { display: block; width: 100%; height: auto; }
}
@media (min-width: 900px) {
  .pdp--ed { grid-template-columns: minmax(0, 1fr) minmax(0, 1.75fr) minmax(0, 1fr); gap: clamp(1.5rem, 3.5vw, 4rem); }
  .pdp--ed .pdp__gallery { display: none; }
  .pdp--ed .pdp__stack { display: grid; gap: clamp(1rem, 2vw, 1.75rem); grid-column: 2; grid-row: 1; }
  .pdp--ed .pdp__about { grid-column: 1; grid-row: 1; align-self: start; position: sticky; top: calc(var(--top) + 2rem); }
  .pdp--ed .pdp__info { grid-column: 3; grid-row: 1; }
  .pdp__shot { margin: 0; overflow: hidden; border-radius: 4px; background: #fff; }
  .pdp__shot img { display: block; width: 100%; height: auto; max-height: calc(100vh - var(--top) - 4rem); object-fit: contain; }
  .pdp--ed .pdp__title { font-size: clamp(1.15rem, 1rem + 0.5vw, 1.45rem); }
  .pdp--ed .pdp__price { font-size: 1.2rem; }
}

/* ---- Home opening, scroll-driven (30 Sep) ----
   The browser runs the hero's scroll motion itself, in step with the scroll
   (html.sda, set by motion.js heroStack when supported). JS only supplies
   the landing spot, --fly-x/-y/-s, measured on load and resize. Ranges are
   scroll distance from the top: the flight takes the first half-screen,
   the sheet covers the hero over the first full screen. */
@keyframes hero-fly { to { transform: translate(var(--fly-x, 0px), var(--fly-y, 0px)) scale(var(--fly-s, 1)); } }
@keyframes hero-fly-fade { 0%, 90% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hero-fade-out { to { opacity: 0; } }
@keyframes hero-fade-in { from { opacity: 0; } to { opacity: 1; } }
/* dim only: shrinking the photo (it was scale 0.92) opened a band of the
   hero's ground round it and dropped its top edge onto the header (30 Sep) */
@keyframes hero-recede { to { opacity: 0.4; } }
@keyframes hero-copy-out { to { opacity: 0; transform: translateY(-24px); } }
/* How far you scroll while the lockup flies: half a screen on wide screens,
   most of one on a phone, where half felt like it shot off (30 Sep). Keep
   in step with FLY_RANGE in motion.js. */
html { --fly-range: 50vh; }
@media (max-width: 699px) { html { --fly-range: 85vh; } }
html.has-motion.sda .stack .hero__brand {
  transform-origin: 0 0;
  animation: hero-fly ease-in-out both, hero-fly-fade linear both;
  animation-timeline: scroll(root), scroll(root);
  animation-range: 0 var(--fly-range), 0 var(--fly-range);
}
html.has-motion.sda .stack .hero__brand-tag {
  animation: hero-fade-out linear both; animation-timeline: scroll(root); animation-range: 0 calc(var(--fly-range) * 0.45);
}
html.has-motion.sda .site-header[data-over-hero] .wordmark {
  animation: hero-fade-in linear both; animation-timeline: scroll(root); animation-range: calc(var(--fly-range) * 0.9) var(--fly-range);
}
html.has-motion.sda .stack .hero__stage {
  animation: hero-recede linear both; animation-timeline: scroll(root); animation-range: 0 100vh;
}
html.has-motion.sda .stack :is(.hero__inner, .hero__dots, .hero__scroll) {
  animation: hero-copy-out linear both; animation-timeline: scroll(root); animation-range: 0 30vh;
}

/* Our favorites drifting on phones (app.js favDrift): no snapping and no
   smooth-scroll easing, or every frame's step would be pulled back or eased. */
.row.is-drift { scroll-snap-type: none; scroll-behavior: auto; }

/* ---- Shop by category: expanding panels (30 Sep) ----
   After a 21st.dev "expandable gallery", rebuilt in CSS. Four tall panels in
   a row; every one shows its collection name and count at rest (a soft shade
   at the foot keeps the white type legible). From 700px, hovering or
   focusing one widens it (flex-grow 2 against 0.6) and dims the others; a
   phone has no hover, so one panel is open at a time (app.js catPanels) and
   the narrow ones carry their name upright. flex-grow is a layout property,
   the one exception to transform/opacity-only motion here: four boxes, and
   the widening is the whole effect. */
/* the full container width and most of a screen tall (30 Sep: "fill the page more") */
.cats { display: flex; gap: clamp(0.4rem, 0.7vw, 0.65rem); height: clamp(26rem, 44vw, 42rem); max-height: 78vh; margin: 0; padding: 0; list-style: none; }
.cat { position: relative; flex: 1 1 0; min-width: 0; overflow: hidden; border-radius: 6px; background: var(--deep);
  transition: flex-grow 0.6s var(--ease); }
.cat--sk .sk-media { height: 100%; border-radius: 0; }
.cat__link { position: absolute; inset: 0; display: block; color: #fff; }
.cat__link img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.9s var(--ease); }
.cat__dim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(14, 12, 9, 0) 45%, rgba(14, 12, 9, 0.62) 100%), rgba(14, 12, 9, 0.12);
  transition: background-color 0.45s var(--ease); }
.cat__text { position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; gap: 0.3rem; padding: clamp(1rem, 1.8vw, 1.6rem); }
.cat__name { font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(1.35rem, 1rem + 1vw, 2rem); line-height: 1.1;
  text-shadow: 0 2px 18px rgba(14, 12, 9, 0.35); }
.cat__count { font-size: 0.66rem; font-weight: 700; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255, 255, 255, 0.85); }
.cat__go { display: inline-flex; align-items: center; gap: 0.45rem; margin-top: 0.5rem; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  opacity: 0; transform: translateY(6px); transition: opacity var(--d-ui) var(--ease), transform var(--d-pop) var(--ease); }
.cat__link:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: -4px; }
@media (min-width: 700px) {
  .cats:has(.cat:hover, .cat:focus-within) .cat { flex-grow: 0.6; }
  /* same :has() prefix as the rule above, or that rule outranks this one */
  .cats:has(.cat:hover, .cat:focus-within) .cat:is(:hover, :focus-within) { flex-grow: 2; }
  .cats:has(.cat:hover, .cat:focus-within) .cat:not(:hover, :focus-within) .cat__dim { background-color: rgba(14, 12, 9, 0.38); }
  .cat:is(:hover, :focus-within) .cat__dim { background-color: rgba(14, 12, 9, 0); }
  .cat:is(:hover, :focus-within) img { transform: scale(1.04); }
  .cat:is(:hover, :focus-within) .cat__go { opacity: 1; transform: none; transition-delay: 0.12s; }
}
/* Phones (5 Oct, owner's pick "E"): arch tiles, two by two. Each collection
   photo sits in a dome-topped frame with a fine gold outline, the name in the
   display italic and the piece count below it on the page ground. Same 4:5
   box as the skeleton (which takes the arch too), so nothing jumps. Laptops
   keep the expanding panels above. (Pastel cards, option K, are in git
   history: commit 938507d.) */
@media (max-width: 699px) {
  .cats { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem 0.9rem; height: auto; max-height: none; padding: 0.35rem 0.3rem 0; }
  .cat { aspect-ratio: 4 / 5; border-radius: 0; overflow: visible; transition: none; background: transparent; }
  .cat__link { display: flex; flex-direction: column; align-items: stretch; gap: 0.6rem; padding: 0; color: var(--ink); }
  .cat__link img { flex: 1 1 0; min-height: 0; width: 100%; height: auto; border-radius: 999px 999px 8px 8px; object-fit: cover; transition: none;
    outline: 1px solid var(--line-gold); outline-offset: 4px; }
  .cat--sk .sk-media { border-radius: 999px 999px 8px 8px; }
  .cat__dim { display: none; }
  .cat__text { position: static; align-items: center; gap: 0.1rem; padding: 0; text-align: center; }
  .cat__name { font-family: var(--display); font-style: italic; font-weight: 500; font-size: 1.12rem; line-height: 1.15;
    letter-spacing: 0.01em; text-transform: none; color: var(--ink); text-shadow: none; }
  .cat__count { display: block; font-size: 0.58rem; letter-spacing: 0.18em; color: var(--muted); }
  .cat__go { display: none; }
  .cat__link:focus-visible { outline: none; }
  .cat__link:focus-visible img { outline: 2px solid var(--deep); }
}
@media (prefers-reduced-motion: reduce) { .cat, .cat__link img, .cat__go { transition: none; } }

/* ---- Craft section on laptops (30 Sep): a full-screen film ----
   The film fills the screen and plays on its own (app.js craftFilm); only
   the title and the three points sit over it, bottom left, on a soft shade,
   and rise in once when the section is reached (motion.js craftStage). The
   label, paragraph and button stay for phones only. */
@media (min-width: 1000px) {
  #story { position: relative; padding: 0; }
  #story .story { position: relative; display: block; max-width: none; height: 100vh; height: 100svh; min-height: 36rem; padding: 0; }
  #story .story__figure { position: absolute; inset: 0; border-radius: 0; }
  #story .story__figure .story__film { width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; }
  #story .story__figure::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(90deg, rgba(14, 12, 9, 0.72) 0%, rgba(14, 12, 9, 0.44) 36%, rgba(14, 12, 9, 0) 64%),
                linear-gradient(0deg, rgba(14, 12, 9, 0.5) 0%, rgba(14, 12, 9, 0) 50%); }
  #story .story__copy { position: absolute; z-index: 2; bottom: clamp(3rem, 10vh, 6.5rem);
    left: max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter))); max-width: 32rem; color: #fff; }
  #story .story__copy :is(.eyebrow, .lede, .btn) { display: none; }
  #story .story__copy .section-title { margin: 0 0 1.4rem; color: #fff; text-transform: none; letter-spacing: 0.01em;
    font-family: var(--display); font-style: italic; font-weight: 500; font-size: clamp(2.4rem, 1.4rem + 2.4vw, 3.8rem); line-height: 1.1;
    text-wrap: balance; text-shadow: 0 2px 30px rgba(14, 12, 9, 0.45); }
  #story .story__copy .section-title em { font-style: italic; color: #f6d77e; }
  #story .story__list { gap: 0.75rem; margin: 0; color: rgba(255, 255, 255, 0.92); font-size: 1rem; text-shadow: 0 1px 14px rgba(14, 12, 9, 0.5); }
  #story .story__list .i { color: #f6d77e; }
}

/* ---- Product page: name, price and folded bars (30 Sep, after nofaithstudios.com) ----
   The name a touch heavier; description, shipping and returns each behind a
   bar with a plus that turns to a minus; app.js foldBars animates the
   opening in every browser. */
.pdp--ed .pdp__title { margin-bottom: 0.5rem; font-weight: 600; letter-spacing: 0; }
.pdp--ed .pdp__price { margin-bottom: 1.4rem; }
.pdp__accs { margin-top: 0.4rem; border-bottom: 1px solid var(--line); }
.acc { border-top: 1px solid var(--line); }
.acc summary { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 3.1rem; padding-block: 0.6rem;
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink); cursor: pointer; list-style: none; }
.acc summary::-webkit-details-marker { display: none; }
.acc summary:hover { color: var(--gold); }
.acc__plus { position: relative; flex: none; width: 0.75rem; height: 0.75rem; }
.acc__plus::before, .acc__plus::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1.5px; margin-top: -0.75px; background: currentColor;
  transition: transform var(--d-pop) var(--ease); }
.acc__plus::after { transform: rotate(90deg); }
.acc[open] .acc__plus::after { transform: rotate(0deg); }
.acc.is-closing .acc__plus::after { transform: rotate(90deg); }
.acc__body { padding: 0 0 1.2rem; font-size: 0.9rem; line-height: 1.65; color: var(--ink-2); }
.acc__body .pdp__desc { margin: 0 0 1rem; padding: 0; border: 0; white-space: pre-line; }
.acc__body .pdp__specs { margin: 0; padding: 0; border: 0; }
.acc__body ul { display: grid; gap: 0.45rem; margin: 0 0 0.9rem; padding-left: 1.05rem; }
.acc__more { font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; }
.acc__more:hover { color: var(--gold); }

/* Hero scroll cue (30 Sep): "Scroll" over a hairline with a glint running
   down it, centred at the foot of the hero; the slide dots move to the left,
   under the line of copy (the WhatsApp button owns the bottom right). It fades with the hero copy as the page moves, and a tap
   glides to "Our favorites" (Lenis follows anchor links). */
.stack .hero__dots { left: max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter))); right: auto; justify-content: flex-start; }
.hero__scroll { position: absolute; left: 50%; bottom: clamp(1rem, 3vh, 1.8rem); z-index: 4; translate: -50% 0;
  display: flex; flex-direction: column; align-items: center; gap: 0.55rem; padding: 0.4rem 0.6rem;
  color: #fff; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.3em; text-indent: 0.3em; text-transform: uppercase;
  text-shadow: 0 1px 10px rgba(14, 12, 9, 0.5); }
.hero__scroll-line { position: relative; width: 1px; height: 2.4rem; overflow: hidden; background: rgba(255, 255, 255, 0.32); }
.hero__scroll-line::after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 40%; background: #fff;
  animation: hero-scroll-cue 1.9s var(--ease) infinite; }
@keyframes hero-scroll-cue { from { transform: translateY(-100%); } to { transform: translateY(260%); } }
@media (prefers-reduced-motion: reduce) { .hero__scroll-line::after { animation: none; transform: translateY(75%); } }

/* ---- Product page, laptops (30 Sep, after valeforever.com) ----
   Both side columns hold still beside the photos and sit in the middle of
   the screen: name and price centred over the folded bars on the left;
   on the right the quantity, a full-width Add to bag bar under it, and
   Save / Share under that. Phones stack the same buy block. */
.pdp--ed .pdp__buy { grid-template-columns: 1fr; justify-items: center; gap: 0.9rem; }
.pdp--ed .pdp__buy .btn { width: 100%; }
.pdp--ed .pdp__tools { justify-content: center; }
@media (min-width: 900px) {
  .pdp--ed .pdp__about, .pdp--ed .pdp__info {
    position: sticky; top: var(--top); align-self: start; min-height: calc(100vh - var(--top));
    display: flex; flex-direction: column; justify-content: center; padding-block: 1.5rem; }
  .pdp--ed .pdp__about { text-align: center; }
  .pdp--ed .pdp__about .pdp__price { justify-content: center; }
  .pdp--ed .pdp__about .pdp__offer { justify-content: center; }
  .pdp--ed .pdp__accs { text-align: left; }
}
/* Phones (30 Sep): the wider slide links ("Shop pendants", "Shop the
   collection") reached the centred Scroll cue. The copy sits a little
   higher and the cue lower and shorter, so they never meet on any slide. */
@media (max-width: 699px) {
  .stack .hero__inner { padding-bottom: 6.4rem; }
  .hero__scroll { bottom: 0.7rem; gap: 0.45rem; }
  .hero__scroll-line { height: 1.6rem; }
}
