/* =========================================================================
   Bellwood & Ash
   One stylesheet, no framework, no build step for the CSS itself.

   Order: tokens, reset, base, layout primitives, components, utilities.
   Everything is driven by custom properties so the dark theme is a token swap
   rather than a second set of rules. Any colour that only exists inside a media
   query is a colour that disappears when someone toggles the theme by hand, so
   every token is declared on bare :root first and only overridden below.
   ========================================================================= */

/* --- 1. Tokens ---------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Palette. Warm neutrals with a single ember accent; brass and sage are
     support colours used sparingly, mostly on rules and small type. */
  --bone: #f6f2ec;
  --bone-deep: #ece5da;
  --bone-edge: #ddd2c2;
  --ash: #1d1b19;
  --ash-soft: #4a4540;
  --ash-mute: #6b6259;
  --ember: #9a4a2f;
  --ember-deep: #7d3a23;
  --ember-wash: #f2e2d9;
  --sage: #6d7a63;
  --brass: #a07c43;

  /* Semantic aliases. Components reference these, never the palette directly,
     which is what makes the dark override below a six-line change. */
  --surface: var(--bone);
  --surface-raised: #fffdfa;
  --surface-sunk: var(--bone-deep);
  --border: var(--bone-edge);
  --border-strong: #c9bca8;
  --text: var(--ash);
  --text-soft: var(--ash-soft);
  --text-mute: var(--ash-mute);
  --accent: var(--ember);
  --accent-hover: var(--ember-deep);
  --accent-wash: var(--ember-wash);
  --accent-on: #fffdfa;
  --focus: var(--ember);

  --shadow-sm: 0 1px 2px rgb(29 27 25 / 0.04), 0 2px 8px rgb(29 27 25 / 0.04);
  --shadow-md: 0 4px 12px rgb(29 27 25 / 0.06), 0 12px 32px rgb(29 27 25 / 0.07);
  --shadow-lg: 0 8px 24px rgb(29 27 25 / 0.08), 0 24px 64px rgb(29 27 25 / 0.12);

  /* Type. Instrument Serif for display, Work Sans for everything else.
     Deliberately not the Fraunces/Inter pairing used elsewhere: this is a
     client brand, not a house style. */
  --font-display: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  --font-body: "Work Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* Fluid scale, 320px to 1440px viewport. */
  --step--1: clamp(0.83rem, 0.81rem + 0.09vw, 0.89rem);
  --step-0: clamp(1rem, 0.96rem + 0.18vw, 1.11rem);
  --step-1: clamp(1.2rem, 1.14rem + 0.31vw, 1.39rem);
  --step-2: clamp(1.44rem, 1.34rem + 0.49vw, 1.73rem);
  --step-3: clamp(1.73rem, 1.57rem + 0.76vw, 2.17rem);
  --step-4: clamp(2.07rem, 1.85rem + 1.14vw, 2.71rem);
  --step-5: clamp(2.49rem, 2.16rem + 1.66vw, 3.39rem);
  --step-6: clamp(2.99rem, 2.51rem + 2.36vw, 4.24rem);

  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-s: 1rem;
  --space-m: 1.5rem;
  --space-l: 2rem;
  --space-xl: 3rem;
  --space-2xl: 4.5rem;
  --space-3xl: 7rem;

  --radius-s: 4px;
  --radius-m: 8px;
  --radius-l: 16px;
  --radius-pill: 999px;

  --measure: 68ch;
  --page: 1220px;
  --page-narrow: 760px;

  --ease: cubic-bezier(0.22, 0.8, 0.36, 1);
}

:root:not([data-theme="light"]) {
  @media (prefers-color-scheme: dark) {
    color-scheme: dark;
    --surface: #161412;
    --surface-raised: #1f1c19;
    --surface-sunk: #100e0d;
    --border: #332e29;
    --border-strong: #4a433c;
    --text: #f2ece3;
    --text-soft: #c4bbaf;
    --text-mute: #9b9187;
    --accent: #d4784f;
    --accent-hover: #e08c64;
    --accent-wash: #2c2019;
    --accent-on: #161412;
    --focus: #d4784f;
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3), 0 2px 8px rgb(0 0 0 / 0.24);
    --shadow-md: 0 4px 12px rgb(0 0 0 / 0.36), 0 12px 32px rgb(0 0 0 / 0.32);
    --shadow-lg: 0 8px 24px rgb(0 0 0 / 0.4), 0 24px 64px rgb(0 0 0 / 0.44);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface: #161412;
  --surface-raised: #1f1c19;
  --surface-sunk: #100e0d;
  --border: #332e29;
  --border-strong: #4a433c;
  --text: #f2ece3;
  --text-soft: #c4bbaf;
  --text-mute: #9b9187;
  --accent: #d4784f;
  --accent-hover: #e08c64;
  --accent-wash: #2c2019;
  --accent-on: #161412;
  --focus: #d4784f;
  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.3), 0 2px 8px rgb(0 0 0 / 0.24);
  --shadow-md: 0 4px 12px rgb(0 0 0 / 0.36), 0 12px 32px rgb(0 0 0 / 0.32);
  --shadow-lg: 0 8px 24px rgb(0 0 0 / 0.4), 0 24px 64px rgb(0 0 0 / 0.44);
}

/* --- 2. Reset ----------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

* {
  margin: 0;
}

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

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

body {
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--text);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

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

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

button {
  cursor: pointer;
  background: none;
  border: none;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

p,
li {
  text-wrap: pretty;
}

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: 2px;
}

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

/* --- 3. Base type ------------------------------------------------------- */

.display-xl {
  font-size: var(--step-6);
}
.display-l {
  font-size: var(--step-5);
}
.display-m {
  font-size: var(--step-4);
}
.display-s {
  font-size: var(--step-3);
}
.title {
  font-size: var(--step-2);
}

.eyebrow {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-mute);
  line-height: 1.4;
}

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--text-soft);
  max-width: 46ch;
}

.prose {
  max-width: var(--measure);
}
.prose > * + * {
  margin-top: var(--space-s);
}
.prose h2 {
  font-size: var(--step-3);
  margin-top: var(--space-xl);
}
.prose h3 {
  font-size: var(--step-1);
  font-family: var(--font-body);
  font-weight: 600;
  letter-spacing: 0;
  margin-top: var(--space-l);
}
.prose p,
.prose li {
  color: var(--text-soft);
}
.prose ul,
.prose ol {
  padding-left: 1.2em;
}
.prose li + li {
  margin-top: var(--space-2xs);
}
.prose a {
  color: var(--text);
  text-decoration-color: var(--accent);
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
}
.prose a:hover {
  color: var(--accent);
}

/* --- 4. Layout primitives ----------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--page);
  margin-inline: auto;
  padding-inline: var(--space-m);
}
.wrap--narrow {
  max-width: var(--page-narrow);
}

.section {
  padding-block: var(--space-2xl);
}
.section--tight {
  padding-block: var(--space-xl);
}
.section--sunk {
  background: var(--surface-sunk);
}

.stack > * + * {
  margin-top: var(--space-s);
}
.stack-l > * + * {
  margin-top: var(--space-l);
}

.cluster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
}

.grid {
  display: grid;
  gap: var(--space-m);
}
.grid--3 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
.grid--4 {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}
/* Three that must stay three. auto-fit inside the narrow editorial column
   drops the third card onto its own row and it reads as an afterthought. */
.grid--trio {
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .grid--trio {
    grid-template-columns: repeat(3, 1fr);
  }
}

.rule {
  height: 1px;
  background: var(--border);
  border: 0;
}

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: var(--space-m);
  margin-bottom: var(--space-l);
}
.section-head p {
  color: var(--text-soft);
  max-width: 46ch;
}

/* --- 5. Buttons and links ----------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 0.85em 1.6em;
  border-radius: var(--radius-pill);
  font-size: var(--step--1);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition:
    background-color 0.25s var(--ease),
    border-color 0.25s var(--ease),
    color 0.25s var(--ease),
    transform 0.25s var(--ease);
}
.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--accent);
  color: var(--accent-on);
}
.btn--primary:hover {
  background: var(--accent-hover);
}

.btn--ink {
  background: var(--text);
  color: var(--surface);
}
.btn--ink:hover {
  background: var(--accent);
  color: var(--accent-on);
}

.btn--outline {
  border-color: var(--border-strong);
  color: var(--text);
}
.btn--outline:hover {
  border-color: var(--text);
  background: var(--surface-raised);
}

.btn--block {
  width: 100%;
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.link-quiet {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px solid var(--border-strong);
  padding-bottom: 2px;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.link-quiet:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.skip-link {
  position: absolute;
  left: var(--space-s);
  top: var(--space-s);
  z-index: 200;
  padding: 0.7em 1.2em;
  background: var(--text);
  color: var(--surface);
  border-radius: var(--radius-s);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform 0.2s var(--ease);
}
.skip-link:focus {
  transform: translateY(0);
}

/* --- 6. Header ---------------------------------------------------------- */

.banner {
  background: var(--text);
  color: var(--surface);
  text-align: center;
  font-size: var(--step--1);
  padding: 0.6em var(--space-s);
}
.banner a {
  color: inherit;
}

.header {
  position: sticky;
  top: 0;
  z-index: 90;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
}
.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  min-height: 68px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  color: var(--text);
  flex-shrink: 0;
}
.wordmark svg {
  width: 26px;
  height: 26px;
  color: var(--accent);
}
.wordmark span {
  font-family: var(--font-display);
  font-size: 1.32rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.nav {
  display: flex;
  gap: var(--space-m);
  align-items: center;
}
.nav a {
  text-decoration: none;
  font-size: var(--step--1);
  color: var(--text-soft);
  padding-block: 0.4em;
  position: relative;
  transition: color 0.2s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--accent);
  scale: 0 1;
  transform-origin: left;
  transition: scale 0.28s var(--ease);
}
.nav a:hover,
.nav a[aria-current="page"] {
  color: var(--text);
}
.nav a:hover::after,
.nav a[aria-current="page"]::after {
  scale: 1 1;
}

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
}

.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  color: var(--text-soft);
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
  position: relative;
}
.icon-btn:hover {
  background: var(--surface-sunk);
  color: var(--text);
}
.icon-btn svg {
  width: 20px;
  height: 20px;
}

.cart-count {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding-inline: 5px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-on);
  font-size: 0.66rem;
  font-weight: 600;
  display: grid;
  place-items: center;
  line-height: 1;
}
.cart-count[hidden] {
  display: none;
}

.nav-toggle {
  display: none;
}

/* Slide-in panels are parked off-screen at translate:100%. A position:fixed
   element is laid out against the viewport, so parking one to the right of it
   widens the layout viewport: on a 390px phone the page reported 710px and
   Safari and Chrome both rendered the whole site zoomed out to fit. Neither
   overflow-x on body nor on html contains it, because neither is the panel's
   containing block.

   The fix is a host that IS the containing block. `contain: paint` on a fixed,
   viewport-sized host makes it the containing block for the absolutely
   positioned panel inside it, and clips whatever hangs outside. On desktop the
   host is display:contents, so the header's flex row is unaffected. */
.nav-host {
  display: contents;
}

@media (max-width: 900px) {
  .nav-toggle {
    display: inline-grid;
  }
  .nav-host {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 95;
    contain: paint;
    pointer-events: none;
  }
  .nav {
    position: absolute;
    inset: 0 0 0 auto;
    pointer-events: auto;
    width: min(320px, 84vw);
    background: var(--surface-raised);
    border-left: 1px solid var(--border);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: calc(68px + var(--space-l)) var(--space-m) var(--space-m);
    translate: 100% 0;
    transition: translate 0.32s var(--ease);
    box-shadow: var(--shadow-lg);
  }
  .nav[data-open="true"] {
    translate: 0 0;
  }
  .nav a {
    font-size: var(--step-1);
    padding-block: var(--space-s);
    border-bottom: 1px solid var(--border);
  }
  .nav a::after {
    display: none;
  }
  /* No-JS: the panel would be unreachable, so it becomes a plain inline row. */
  html:not(.js) .nav-host {
    display: contents;
    position: static;
    contain: none;
    pointer-events: auto;
  }
  html:not(.js) .nav {
    position: static;
    width: auto;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-s);
    padding: 0;
    translate: none;
    border: 0;
    box-shadow: none;
    background: none;
  }
  html:not(.js) .nav a {
    font-size: var(--step--1);
    padding-block: 0.4em;
    border: 0;
  }
  html:not(.js) .nav-toggle {
    display: none;
  }
  html:not(.js) .header__inner {
    flex-wrap: wrap;
    padding-block: var(--space-2xs);
  }
}

/* --- 7. Hero ------------------------------------------------------------ */

.hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: var(--space-2xl);
  padding-block: var(--space-2xl);
}
@media (max-width: 900px) {
  .hero {
    grid-template-columns: 1fr;
    gap: var(--space-xl);
  }
}
.hero__copy {
  max-width: 34ch;
}
.hero h1 {
  font-size: var(--step-6);
  margin-top: var(--space-s);
}
.hero .lede {
  margin-top: var(--space-m);
}
.hero .cluster {
  margin-top: var(--space-l);
}
.hero__media {
  position: relative;
  border-radius: var(--radius-l);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  /* 3:2 throughout, because that is the shape the photographs are. See the
     note in data/images.mjs. */
  aspect-ratio: 3 / 2;
}
.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__badge {
  position: absolute;
  bottom: var(--space-m);
  left: var(--space-m);
  right: var(--space-m);
  background: color-mix(in srgb, var(--surface-raised) 92%, transparent);
  backdrop-filter: blur(8px);
  border-radius: var(--radius-m);
  padding: var(--space-s) var(--space-m);
  font-size: var(--step--1);
  color: var(--text-soft);
  box-shadow: var(--shadow-sm);
}

/* --- 8. Product card ---------------------------------------------------- */

.card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition:
    transform 0.35s var(--ease),
    box-shadow 0.35s var(--ease),
    border-color 0.35s var(--ease);
}
.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
}

.card__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--surface-sunk);
}
.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 0.6s var(--ease);
}
.card:hover .card__media img {
  scale: 1.04;
}

.card__body {
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  flex: 1;
}
.card__title {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.1;
}
.card__title a {
  text-decoration: none;
}
.card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
.card__notes {
  font-size: var(--step--1);
  color: var(--text-mute);
}
.card__foot {
  margin-top: auto;
  padding-top: var(--space-s);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
}
/* Size label above, price below. Side by side, "Signature jar, 9 oz $48"
   breaks after the 9 and reads as a different number. */
.card__price {
  display: grid;
  gap: 1px;
  font-size: var(--step--1);
  color: var(--text-mute);
  line-height: 1.35;
}
.card__price b {
  color: var(--text);
  font-weight: 600;
  font-size: var(--step-0);
}
.card__size {
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.card--linked {
  position: relative;
}
.card__foot .btn {
  position: relative;
  z-index: 2;
}

.tag {
  display: inline-block;
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.35em 0.8em;
  border-radius: var(--radius-pill);
  background: var(--accent-wash);
  color: var(--accent);
}
.tag--float {
  position: absolute;
  top: var(--space-s);
  left: var(--space-s);
  z-index: 2;
  background: color-mix(in srgb, var(--surface-raised) 92%, transparent);
  backdrop-filter: blur(6px);
  color: var(--text);
}

/* --- 9. Filters --------------------------------------------------------- */

.filters {
  border-block: 1px solid var(--border);
  padding-block: var(--space-m);
  margin-bottom: var(--space-l);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  justify-content: space-between;
}
.filter-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: center;
}
.filter-group > .eyebrow {
  margin-right: var(--space-2xs);
}

.chip {
  padding: 0.5em 1em;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-strong);
  font-size: var(--step--1);
  color: var(--text-soft);
  background: transparent;
  transition:
    background-color 0.2s var(--ease),
    color 0.2s var(--ease),
    border-color 0.2s var(--ease);
}
.chip:hover {
  border-color: var(--text);
  color: var(--text);
}
.chip[aria-pressed="true"] {
  background: var(--text);
  border-color: var(--text);
  color: var(--surface);
}
/* The volume sits inside the chip, so it has to survive the chip inverting
   under aria-pressed. A fixed muted grey passed on the light chip and failed
   at 2.6:1 on the dark one; inheriting keeps it legible in both states and the
   smaller size still reads as secondary. */
.chip .muted {
  color: inherit;
  font-size: 0.9em;
}

select.chip {
  padding-right: 2em;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.1em top 55%, right 0.85em top 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.filter-status {
  font-size: var(--step--1);
  color: var(--text-mute);
}

/* JS hides non-matching cards by setting hidden; without JS nothing is hidden
   and the full grid stands, which is the correct degraded state for a shop. */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: var(--space-m);
}

/* The library holds nine scents. Four across leaves a lone card stranded on a
   third row; three across lands 3/3/3 and buys the photography more width. */
.product-grid--3 {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
}
@media (min-width: 1000px) {
  .product-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}
.product-grid > [hidden] {
  display: none;
}

.empty-state {
  padding: var(--space-2xl) var(--space-m);
  text-align: center;
  color: var(--text-mute);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-l);
}

/* --- 10. Product page --------------------------------------------------- */

.pdp {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: var(--space-2xl);
  align-items: start;
  padding-block: var(--space-xl);
}
@media (max-width: 900px) {
  .pdp {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }
}

/* Images stacked, not one main plus thumbnails.
   With portrait photography a single tall frame filled this column. The
   photography is landscape, so one frame left roughly 600px of dead space
   beside the buy panel. Three stacked landscapes fill the column, need no
   JavaScript, and show every shot at full size instead of hiding two behind
   80px thumbnails. */
.gallery {
  display: grid;
  gap: var(--space-xs);
  align-content: start;
}
.gallery figure {
  border-radius: var(--radius-l);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--surface-sunk);
  box-shadow: var(--shadow-sm);
}
.gallery figure:first-child {
  box-shadow: var(--shadow-md);
}
.gallery figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pdp__buy {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}
.pdp h1 {
  font-size: var(--step-5);
}

.rating {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: var(--step--1);
  color: var(--text-mute);
}
.rating svg {
  width: 14px;
  height: 14px;
  color: var(--brass);
}

.size-options {
  display: grid;
  gap: var(--space-2xs);
  border: 0;
  padding: 0;
  margin: 0;
}
.size-options legend {
  padding: 0;
  margin-bottom: var(--space-2xs);
}
.size-option {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-m);
  cursor: pointer;
  background: var(--surface-raised);
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}
.size-option:hover {
  border-color: var(--border-strong);
}
.size-option:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-wash);
}
.size-option:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.size-option input {
  accent-color: var(--accent);
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
.size-option__text {
  flex: 1;
  min-width: 0;
}
.size-option__text b {
  display: block;
  font-weight: 600;
  font-size: var(--step-0);
}
.size-option__text span {
  font-size: var(--step--1);
  color: var(--text-mute);
}
.size-option__price {
  font-weight: 600;
  white-space: nowrap;
}

.price-live {
  font-family: var(--font-display);
  font-size: var(--step-4);
  line-height: 1;
}

.notes-pyramid {
  display: grid;
  gap: var(--space-s);
}
.notes-pyramid div {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: var(--space-s);
  align-items: baseline;
  padding-bottom: var(--space-s);
  border-bottom: 1px solid var(--border);
}
.notes-pyramid dt {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.notes-pyramid dd {
  margin: 0;
  color: var(--text-soft);
}

.spec-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-s);
  padding: var(--space-m);
  background: var(--surface-sunk);
  border-radius: var(--radius-m);
  font-size: var(--step--1);
}
.spec-list div {
  display: grid;
  gap: 2px;
}
.spec-list dt {
  color: var(--text-mute);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.spec-list dd {
  margin: 0;
  font-weight: 500;
}

/* --- 11. Cart drawer ---------------------------------------------------- */

/* Same containment problem, same answer. See .nav-host above. */
.overlay-host {
  position: fixed;
  inset: 0;
  z-index: 100;
  contain: paint;
  pointer-events: none;
}

.scrim {
  position: absolute;
  inset: 0;
  background: rgb(29 27 25 / 0.42);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--ease);
}
.scrim[data-open="true"] {
  opacity: 1;
  pointer-events: auto;
}

.drawer {
  position: absolute;
  inset-block: 0;
  right: 0;
  width: min(420px, 92vw);
  background: var(--surface-raised);
  border-left: 1px solid var(--border);
  z-index: 110;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  translate: 100% 0;
  transition: translate 0.35s var(--ease);
  box-shadow: var(--shadow-lg);
}
.drawer[data-open="true"] {
  translate: 0 0;
}
.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-m);
  border-bottom: 1px solid var(--border);
}
.drawer__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-m);
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}
.drawer__foot {
  border-top: 1px solid var(--border);
  padding: var(--space-m);
  display: grid;
  gap: var(--space-s);
  background: var(--surface-raised);
}

.line-item {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: var(--space-s);
  align-items: start;
}
.line-item__media {
  border-radius: var(--radius-m);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  background: var(--surface-sunk);
}
.line-item__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.line-item__name {
  font-weight: 500;
  line-height: 1.3;
}
.line-item__size {
  font-size: var(--step--1);
  color: var(--text-mute);
}
.line-item__controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  margin-top: var(--space-2xs);
}

.stepper {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  overflow: hidden;
}
.stepper button {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  color: var(--text-soft);
  transition: background-color 0.2s var(--ease);
}
.stepper button:hover {
  background: var(--surface-sunk);
  color: var(--text);
}
.stepper output {
  min-width: 2ch;
  text-align: center;
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
}

.ship-meter {
  display: grid;
  gap: var(--space-2xs);
  font-size: var(--step--1);
  color: var(--text-soft);
}
.ship-meter__track {
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--surface-sunk);
  overflow: hidden;
}
.ship-meter__fill {
  height: 100%;
  background: var(--accent);
  border-radius: var(--radius-pill);
  transition: width 0.4s var(--ease);
}

.totals {
  display: grid;
  gap: var(--space-2xs);
  font-size: var(--step--1);
}
.totals div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-s);
}
.totals .totals__grand {
  font-size: var(--step-0);
  font-weight: 600;
  padding-top: var(--space-2xs);
  border-top: 1px solid var(--border);
  margin-top: var(--space-2xs);
}
.totals span:last-child {
  font-variant-numeric: tabular-nums;
}

/* --- 12. Forms ---------------------------------------------------------- */

.field {
  display: grid;
  gap: var(--space-3xs);
}
.field label {
  font-size: var(--step--1);
  font-weight: 500;
}
.field .hint {
  font-size: 0.78rem;
  color: var(--text-mute);
}
.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 0.75em 0.95em;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-m);
  background: var(--surface-raised);
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.field textarea {
  min-height: 8rem;
  resize: vertical;
}
.field .error {
  font-size: 0.8rem;
  color: var(--accent);
  min-height: 1.2em;
}
.field[data-invalid="true"] input,
.field[data-invalid="true"] textarea,
.field[data-invalid="true"] select {
  border-color: var(--accent);
}

.form-grid {
  display: grid;
  gap: var(--space-m);
}
@media (min-width: 640px) {
  .form-grid--2 {
    grid-template-columns: 1fr 1fr;
  }
  .form-grid .span-2 {
    grid-column: 1 / -1;
  }
}

.form-note {
  font-size: var(--step--1);
  color: var(--text-mute);
  border-left: 2px solid var(--border-strong);
  padding-left: var(--space-s);
}

.form-status {
  border-radius: var(--radius-m);
  padding: var(--space-m);
  background: var(--accent-wash);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
}
.form-status:empty {
  display: none;
}

/* --- 13. Checkout mock -------------------------------------------------- */

/* Deliberately reproduces the two-column Stripe Checkout layout so a visitor
   recognises the pattern. It is a mock: no keys, no SDK, inert inputs, and a
   demo notice that cannot be dismissed. */
.checkout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100vh;
}
@media (max-width: 860px) {
  .checkout {
    grid-template-columns: 1fr;
    min-height: 0;
  }
}
.checkout__summary {
  background: var(--surface-sunk);
  border-right: 1px solid var(--border);
  padding: var(--space-xl) var(--space-l);
}
.checkout__summary-inner {
  max-width: 420px;
  margin-left: auto;
  display: grid;
  gap: var(--space-l);
}
.checkout__pay {
  padding: var(--space-xl) var(--space-l);
}
.checkout__pay-inner {
  max-width: 420px;
  margin-right: auto;
  display: grid;
  gap: var(--space-m);
}
.checkout__amount {
  font-family: var(--font-display);
  font-size: var(--step-5);
  line-height: 1;
}
.checkout__lines {
  display: grid;
  gap: var(--space-m);
}
.demo-notice {
  border: 1px solid var(--accent);
  background: var(--accent-wash);
  border-radius: var(--radius-m);
  padding: var(--space-s) var(--space-m);
  font-size: var(--step--1);
  color: var(--text);
}
.demo-notice b {
  color: var(--accent);
}
.pay-fields {
  display: grid;
  gap: var(--space-s);
}
.pay-card {
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-m);
  overflow: hidden;
  background: var(--surface-raised);
}
.pay-card input {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0.75em 0.95em;
  width: 100%;
}
.pay-card__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-top: 1px solid var(--border);
}
.pay-card__row input + input {
  border-left: 1px solid var(--border);
}
.pay-brands {
  display: flex;
  gap: 6px;
  align-items: center;
}
.pay-brands span {
  width: 30px;
  height: 20px;
  border-radius: 3px;
  background: var(--surface-sunk);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text-mute);
}
.checkout__foot {
  font-size: 0.78rem;
  color: var(--text-mute);
  display: flex;
  gap: var(--space-s);
  align-items: center;
  justify-content: center;
  padding-top: var(--space-s);
  border-top: 1px solid var(--border);
}

/* --- 14. Editorial and misc components ---------------------------------- */

.breadcrumbs {
  font-size: var(--step--1);
  color: var(--text-mute);
  padding-block: var(--space-m) 0;
}
.breadcrumbs ol {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em;
}
.breadcrumbs a {
  color: var(--text-soft);
  text-decoration: none;
}
.breadcrumbs a:hover {
  color: var(--accent);
}
.breadcrumbs li + li::before {
  content: "/";
  margin-right: 0.5em;
  color: var(--border-strong);
}

.feature {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-2xl);
  align-items: center;
}
@media (max-width: 900px) {
  .feature {
    grid-template-columns: 1fr;
    gap: var(--space-l);
  }
}
.feature__media {
  border-radius: var(--radius-l);
  overflow: hidden;
  aspect-ratio: 3 / 2;
  box-shadow: var(--shadow-md);
}
.feature__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.feature--flip .feature__media {
  order: 2;
}
@media (max-width: 900px) {
  .feature--flip .feature__media {
    order: 0;
  }
}

.step-list {
  counter-reset: step;
  display: grid;
  gap: var(--space-m);
  list-style: none;
  padding: 0;
}
.step-list li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: var(--space-s);
}
.step-list li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--step-1);
  color: var(--accent);
  line-height: 1.2;
}
.step-list h3 {
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: 0;
}
.step-list p {
  color: var(--text-soft);
  font-size: var(--step--1);
  margin-top: 2px;
}

.quote {
  border-left: 2px solid var(--accent);
  padding-left: var(--space-m);
  font-family: var(--font-display);
  font-size: var(--step-3);
  line-height: 1.3;
}
.quote footer {
  font-family: var(--font-body);
  font-size: var(--step--1);
  color: var(--text-mute);
  margin-top: var(--space-s);
}

.accordion {
  border-top: 1px solid var(--border);
}
.accordion details {
  border-bottom: 1px solid var(--border);
}
.accordion summary {
  cursor: pointer;
  padding: var(--space-m) 0;
  font-weight: 500;
  display: flex;
  justify-content: space-between;
  gap: var(--space-m);
  align-items: center;
  list-style: none;
}
.accordion summary::-webkit-details-marker {
  display: none;
}
.accordion summary::after {
  content: "+";
  font-size: 1.4em;
  color: var(--accent);
  line-height: 1;
  transition: rotate 0.25s var(--ease);
}
.accordion details[open] summary::after {
  rotate: 45deg;
}
.accordion details > p {
  padding-bottom: var(--space-m);
  color: var(--text-soft);
  max-width: var(--measure);
}

.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-l);
}
table.data {
  width: 100%;
  min-width: 480px;
  border-collapse: collapse;
  font-size: var(--step--1);
  background: var(--surface-raised);
}
table.data th,
table.data td {
  padding: var(--space-s) var(--space-m);
  text-align: left;
  border-bottom: 1px solid var(--border);
}
table.data thead th {
  background: var(--surface-sunk);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
}
table.data tbody tr:last-child th,
table.data tbody tr:last-child td {
  border-bottom: 0;
}

.cta-band {
  background: var(--text);
  color: var(--surface);
  border-radius: var(--radius-l);
  padding: var(--space-2xl) var(--space-l);
  text-align: center;
}
.cta-band h2 {
  font-size: var(--step-4);
}
.cta-band p {
  margin: var(--space-s) auto 0;
  max-width: 46ch;
  color: color-mix(in srgb, var(--surface) 78%, transparent);
}
.cta-band .cluster {
  justify-content: center;
  margin-top: var(--space-l);
}
.cta-band .btn--primary {
  background: var(--surface);
  color: var(--text);
}
.cta-band .btn--primary:hover {
  background: var(--accent);
  color: var(--accent-on);
}
.cta-band .btn--outline {
  border-color: color-mix(in srgb, var(--surface) 50%, transparent);
  color: var(--surface);
}
.cta-band .btn--outline:hover {
  background: color-mix(in srgb, var(--surface) 12%, transparent);
  border-color: var(--surface);
}

/* --- 15. Footer --------------------------------------------------------- */

.footer {
  margin-top: auto;
  border-top: 1px solid var(--border);
  background: var(--surface-sunk);
  padding-block: var(--space-2xl) var(--space-l);
}
.footer__grid {
  display: grid;
  grid-template-columns: 1.4fr repeat(3, 1fr);
  gap: var(--space-l);
}
@media (max-width: 860px) {
  .footer__grid {
    grid-template-columns: 1fr 1fr;
  }
}
@media (max-width: 520px) {
  .footer__grid {
    grid-template-columns: 1fr;
  }
}
.footer h2 {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: var(--space-s);
}
.footer ul {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--space-2xs);
  font-size: var(--step--1);
}
.footer a {
  color: var(--text-soft);
  text-decoration: none;
}
.footer a:hover {
  color: var(--accent);
}
address {
  font-style: normal;
  font-size: var(--step--1);
  color: var(--text-soft);
  display: grid;
  gap: var(--space-3xs);
}
address a {
  color: var(--text);
  text-decoration-color: var(--accent);
  text-underline-offset: 3px;
}
.footer__base {
  margin-top: var(--space-xl);
  padding-top: var(--space-m);
  border-top: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--text-mute);
}

.newsletter {
  display: flex;
  gap: var(--space-2xs);
  margin-top: var(--space-s);
}
.newsletter input {
  flex: 1;
  min-width: 0;
  padding: 0.7em 0.9em;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
}
.newsletter input:focus {
  outline: none;
  border-color: var(--accent);
}

/* --- 16. Image placeholders --------------------------------------------- */

/* Until the photography lands, build.mjs renders this in place of an <img>.
   It carries the expected filename so the shoot list and the site never drift. */
.ph {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-height: 120px;
  background:
    repeating-linear-gradient(
      45deg,
      transparent 0 12px,
      color-mix(in srgb, var(--text) 3%, transparent) 12px 24px
    ),
    var(--surface-sunk);
  color: var(--text-mute);
  text-align: center;
  padding: var(--space-m);
}
.ph__inner {
  display: grid;
  gap: 6px;
  max-width: 100%;
}
.ph svg {
  width: 28px;
  height: 28px;
  margin-inline: auto;
  opacity: 0.5;
}
.ph code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.68rem;
  word-break: break-all;
  opacity: 0.75;
}

/* --- 17. Motion --------------------------------------------------------- */

/* Gated on html.js so a no-JS visitor and any crawler get full opacity content.
   The observer adds .in; without JS the rule never applies at all. */
.js .reveal {
  opacity: 0;
  translate: 0 20px;
  transition:
    opacity 0.7s var(--ease),
    translate 0.7s var(--ease);
}
.js .reveal.in {
  opacity: 1;
  translate: 0 0;
}

/* --- 18. Utilities ------------------------------------------------------ */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.text-center {
  text-align: center;
}
.mt-l {
  margin-top: var(--space-l);
}
.mt-xl {
  margin-top: var(--space-xl);
}
.muted {
  color: var(--text-mute);
}
.soft {
  color: var(--text-soft);
}
[hidden] {
  display: none !important;
}
