/* ==========================================================================
   DIRECTION 04 — ATLANTIC · skin

   THE SIGNATURE: the horizon, and the weather crossing it.
   One continuous horizontal line runs the length of the site. Content sits
   above it or below it, never straddling. A haar — sea fog — drifts across
   the page and thins as you scroll, so the site behaves like a view rather
   than a document.
   ========================================================================== */

/* --------------------------------------------------------------------------
   THE WORDMARK
   Real SVG paths from assets/brand/, not set type — see build-wordmark.py.
   It inherits colour, so it reverses for free inside .evening.
   -------------------------------------------------------------------------- */
/* Painted as a mask rather than an <img>, so the mark inherits currentColor
   and reverses automatically inside .evening — one cached request, no inline
   SVG repeated on every page. */
.mark {
  display: block;
  width: var(--mark-w, 150px);
  aspect-ratio: 5234 / 641;
  background-color: currentColor;
  -webkit-mask: url("/assets/brand/glenda-wordmark.svg") no-repeat center / contain;
  mask: url("/assets/brand/glenda-wordmark.svg") no-repeat center / contain;
}
.mark--stacked {
  aspect-ratio: 5234 / 1103;
  -webkit-mask-image: url("/assets/brand/glenda-wordmark-stacked.svg");
  mask-image: url("/assets/brand/glenda-wordmark-stacked.svg");
}
.mark--g {
  aspect-ratio: 563 / 641;
  width: var(--mark-w, 40px);
  -webkit-mask-image: url("/assets/brand/glenda-g.svg");
  mask-image: url("/assets/brand/glenda-g.svg");
}

.nav__mark { display: flex; align-items: center; }
.nav__mark .mark { --mark-w: clamp(118px, 12vw, 158px); }

/* Legacy type-set fallback, kept for the style guide's comparison section. */
.at-mark {
  font-family: var(--f-editorial);
  font-weight: 300;
  letter-spacing: var(--ls-mark);
  text-transform: uppercase;
  text-indent: var(--ls-mark);
}

/* --------------------------------------------------------------------------
   EVENING MODE
   The same token contract, re-pointed for night. Scope it to any section and
   everything inside re-skins — nav, buttons, cards, the wordmark.
   -------------------------------------------------------------------------- */
.evening {
  --c-canvas:   #101828;   /* deep navy */
  --c-surface:  #172034;
  --c-ink:      #F4EBDF;   /* warm light on navy      15.1:1 */
  --c-ink-soft: #A7AFC0;   /*                          7.1:1 */
  --c-line:     #2A3550;
  --c-accent:   #E9A94B;   /* warm amber carries on navy  9.4:1 */
  --c-accent-2: #F2C98A;
  --c-accent-3: #E08A78;
  --c-on-accent: #101828;
  --c-focus:    #E9A94B;

  background: var(--c-canvas);
  color: var(--c-ink);
  color-scheme: dark;
}

/* The haar is daylight weather — it has no place at night. */
.evening .haar { display: none; }
.evening .duo { --duo: 0.4; }

/* --------------------------------------------------------------------------
   THE HAAR
   A fixed veil of sea fog over the whole page. It is faint, it moves slowly,
   and it thins as the reader descends — the way haar burns off through a
   morning. Fixed rather than per-section so it feels like one climate.
   -------------------------------------------------------------------------- */
.haar {
  position: fixed;
  inset: -20vh -20vw;
  z-index: 1;
  pointer-events: none;
  opacity: var(--haar, 0.55);
  background:
    radial-gradient(60% 40% at 20% 30%, color-mix(in oklab, var(--c-warm, #E9A94B) 26%, transparent), transparent 70%),
    radial-gradient(50% 36% at 78% 62%, color-mix(in oklab, var(--c-surface) 88%, transparent), transparent 72%),
    radial-gradient(70% 44% at 50% 92%, color-mix(in oklab, var(--c-warm, #E9A94B) 18%, transparent), transparent 74%);
  filter: blur(24px);
  will-change: transform, opacity;
}

/* Everything real sits above the weather. The nav is deliberately NOT in this
   list — it must keep position:fixed from shell.css so it can overlay the hero
   photograph. Listing it here silently pushed the hero down by the nav height. */
main, .foot, .gbar { position: relative; z-index: 2; }

/* --------------------------------------------------------------------------
   THE HORIZON
   One rule, full bleed, that recurs down the page. Sections declare whether
   they sit above it or below it.
   -------------------------------------------------------------------------- */
.horizon {
  position: relative;
  height: 1px;
  border: 0;
  background: var(--c-ink);
  opacity: 0.55;
  transform-origin: left center;
}
.horizon--soft { background: var(--c-line); opacity: 1; }

.above { padding-bottom: var(--s6); }
.below { padding-top: var(--s6); }

/* --------------------------------------------------------------------------
   Duotone — photography is graded into the palette rather than dropped in raw
   -------------------------------------------------------------------------- */
.duo { position: relative; }
.duo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background: linear-gradient(196deg,
    color-mix(in oklab, var(--c-warm, #E9A94B) 26%, transparent),
    transparent 48%,
    color-mix(in oklab, var(--c-ink) 22%, transparent));
  mix-blend-mode: multiply;
  opacity: var(--duo, 0.65);
  transition: opacity var(--d-slow) var(--e-signature);
}
.duo:hover { --duo: 0.3; }

/* --------------------------------------------------------------------------
   Nav
   -------------------------------------------------------------------------- */
.nav.is-stuck {
  background: color-mix(in oklab, var(--c-canvas) 88%, transparent);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--c-line);
  padding-block: 0.9rem;
}
.nav.is-hidden { translate: 0 -110%; }
.nav { transition: translate var(--d-base) var(--e-signature), background var(--d-base) var(--e-out), padding var(--d-base) var(--e-out); }

/* --------------------------------------------------------------------------
   Forecast strip — the shop's actual argument, expressed as a forecast
   -------------------------------------------------------------------------- */
.forecast { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s4); }
.fc { display: flex; flex-direction: column; gap: var(--s2); }
.fc__key { font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-ink-soft); }
.fc__val { font-family: var(--f-display); font-weight: var(--fw-display); font-size: var(--fs-h2); line-height: 1.1; }
.fc__note { font-size: var(--fs-small); color: var(--c-ink-soft); line-height: 1.5; }
@media (max-width: 760px) { .forecast { grid-template-columns: 1fr 1fr; gap: var(--s5); } }

/* --------------------------------------------------------------------------
   Appointment band
   -------------------------------------------------------------------------- */
.at-band {
  position: relative;
  text-align: center;
  padding-block: clamp(6rem, 14vw, 11rem);
}

/* --------------------------------------------------------------------------
   Guide-page adjustments
   -------------------------------------------------------------------------- */
.swatch__chip { border-radius: var(--r-md); }
.bench__item, .motion, .dodont__col, .face, .gridviz, .promptbox { border-radius: var(--r-lg); }
.media__ph { --ph-mark: 0.09; }

/* ==========================================================================
   SITE COMPONENTS — added for the finished build
   ========================================================================== */

/* --------------------------------------------------------------------------
   Filter bar (collections)
   -------------------------------------------------------------------------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: center;
  padding-block: var(--s3);
  border-block: var(--border-w) solid var(--c-line);
  margin-bottom: var(--s6);
}
.filter {
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: var(--fw-ui);
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  padding: 0.65em 1.15em;
  border: var(--border-w) solid transparent;
  border-radius: var(--r-pill);
  color: var(--c-ink-soft);
  cursor: pointer;
  transition: color var(--d-fast) var(--e-out),
              border-color var(--d-fast) var(--e-out),
              background var(--d-fast) var(--e-out);
}
.filter:hover { color: var(--c-ink); border-color: var(--c-line); }
.filter[aria-pressed="true"] {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-on-accent);
}
.filters__count { margin-left: auto; font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-ink-soft); }
@media (max-width: 700px) { .filters__count { margin-left: 0; width: 100%; } }

/* A card hidden by filtering — animated out by GSAP, then removed from flow */
.prod[hidden] { display: none; }

/* --------------------------------------------------------------------------
   Product card additions
   -------------------------------------------------------------------------- */
/* The card is a white card. The photograph sits inside a white frame — the
   padding IS the border — and the name, price and note sit on white rather
   than on the page, so the bottom corners curve to match the top. */
.prod {
  position: relative;
  --prod-pad: 0.5rem;
  background: #FFFFFF;
  border: 1px solid #FFFFFF;
  border-radius: var(--r-lg);
  padding: var(--prod-pad);
}
.prod__link::after { content: ""; position: absolute; inset: 0; z-index: 3; }
.prod__media { border-radius: calc(var(--r-lg) - var(--prod-pad) / 2); }
/* Breathing room beyond the frame itself, and a floor under the note. */
.prod__meta,
.prod__note { padding-inline: 0.4rem; }
.prod__note { padding-bottom: 0.55rem; }
.prod:hover .prod__name { color: var(--c-accent); }
.prod__name { transition: color var(--d-fast) var(--e-out); }
.prod__tag {
  position: absolute;
  top: var(--s2); left: var(--s2);
  z-index: 2;
  font-family: var(--f-ui);
  font-size: 0.5625rem;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  padding: 0.4em 0.7em;
  border-radius: var(--r-pill);
  background: color-mix(in oklab, var(--c-canvas) 88%, transparent);
  backdrop-filter: blur(6px);
  color: var(--c-ink);
}

/* --------------------------------------------------------------------------
   Product detail
   -------------------------------------------------------------------------- */
.pdp { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); gap: clamp(1.5rem, 5vw, 5rem); align-items: start; }
@media (max-width: 900px) { .pdp { grid-template-columns: 1fr; } }

.pdp__gallery { display: grid; gap: var(--s2); }
.pdp__gallery .media { border-radius: var(--r-md); }
.pdp__gallery--grid { grid-template-columns: 1fr 1fr; }
.pdp__gallery--grid > :first-child { grid-column: 1 / -1; }

.pdp__panel { position: sticky; top: calc(var(--nav-h, 5rem) + var(--s3)); display: flex; flex-direction: column; gap: var(--s3); }
@media (max-width: 900px) { .pdp__panel { position: static; } }

.pdp__price { font-family: var(--f-display); font-weight: var(--fw-display); }
.pdp__row { display: flex; flex-direction: column; gap: var(--s2); padding-top: var(--s3); border-top: var(--border-w) solid var(--c-line); }
.pdp__rowhead { font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-ink-soft); }

.detail-list { display: grid; gap: 0.55em; }
.detail-list div { display: flex; justify-content: space-between; gap: 1em; font-size: var(--fs-small); padding-bottom: 0.55em; border-bottom: var(--border-w) dotted var(--c-line); }
.detail-list dt { color: var(--c-ink-soft); }
.detail-list dd { text-align: right; }

/* --------------------------------------------------------------------------
   Journal
   -------------------------------------------------------------------------- */
.jrn { display: grid; gap: var(--s3); }
.jrn__media { --ar: 3 / 2; border-radius: var(--r-md); }
.jrn__kicker { font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-accent); }
.jrn__title { font-family: var(--f-display); font-weight: var(--fw-display); font-size: var(--fs-h2); line-height: 1.15; }
.jrn--lead .jrn__media { --ar: 16 / 9; }
.jrn--lead .jrn__title { font-size: var(--fs-d2); }

/* --------------------------------------------------------------------------
   Appointment form
   -------------------------------------------------------------------------- */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s4); }
.form-grid .field--wide { grid-column: 1 / -1; }
@media (max-width: 640px) { .form-grid { grid-template-columns: 1fr; } }

.field__input:user-invalid { border-color: var(--c-accent-3); }
.field__error { font-size: var(--fs-micro); color: var(--c-accent-3); display: none; }
.field__input:user-invalid ~ .field__error { display: block; }

select.field__input { appearance: none; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 18px) 55%, calc(100% - 13px) 55%; background-size: 5px 5px, 5px 5px; background-repeat: no-repeat; padding-right: 2.5em; }

.form-done {
  display: none;
  padding: var(--s5);
  border: var(--border-w) solid var(--c-accent);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, var(--c-accent) 8%, transparent);
}
.form-done.is-shown { display: block; }

/* --------------------------------------------------------------------------
   Page header used by every inner page
   -------------------------------------------------------------------------- */
.phead { padding-block: calc(var(--s9) + 2rem) var(--s6); }
.phead__title { font-family: var(--f-display); font-weight: var(--fw-display); font-size: var(--fs-d1); line-height: 1.02; letter-spacing: var(--ls-display); max-width: 18ch; margin-block: var(--s3) var(--s4); }

/* --------------------------------------------------------------------------
   Breadcrumb
   -------------------------------------------------------------------------- */
.crumb { display: flex; gap: 0.6em; font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-ink-soft); }
.crumb a:hover { color: var(--c-ink); }

/* --------------------------------------------------------------------------
   Mobile menu
   -------------------------------------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--c-canvas);
  padding: var(--s6) var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
  translate: 0 -100%;
  visibility: hidden;
  transition: translate var(--d-slow) var(--e-signature), visibility var(--d-slow);
}
.menu.is-open { translate: 0 0; visibility: visible; }
.menu__link { font-family: var(--f-display); font-weight: var(--fw-display); font-size: var(--fs-h1); }
.menu__close { align-self: flex-end; font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; }

/* --------------------------------------------------------------------------
   The bag — a real online shop needs somewhere for things to go
   -------------------------------------------------------------------------- */
.bag-btn { position: relative; }
.bag-count {
  display: inline-grid; place-items: center;
  min-width: 1.35em; height: 1.35em; padding-inline: 0.3em;
  margin-left: 0.5em;
  border-radius: var(--r-pill);
  /* Bright green, and green ONLY here — nothing else on the site uses it, so
     it can only ever mean "there is something in your bag". It already hides
     itself at zero, so its presence is half the signal and the colour is the
     other half. 9.0:1 against the navy nav, 10.5:1 for the digit on it. */
  background: #3DDC84;
  color: #0B1220;
  font-weight: 700;
  /* The bar is transparent over the hero and light apricot once stuck. Bright
     green reads at 9:1 on the dark state but only 1.5:1 on the light one, so
     the badge needs its own edge rather than relying on the ground behind it. */
  box-shadow: 0 0 0 1.5px color-mix(in oklab, #3DDC84 55%, #06331B);
  font-size: 0.625rem; line-height: 1;
}
.bag-count:empty, .bag-count[data-n="0"] { display: none; }

.bag {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(28rem, 100%);
  z-index: 400;
  background: var(--c-surface);
  border-left: var(--border-w) solid var(--c-line);
  padding: var(--s5) var(--s5) var(--s4);
  display: flex; flex-direction: column; gap: var(--s4);
  translate: 100% 0;
  visibility: hidden;
  transition: translate var(--d-base) var(--e-signature), visibility var(--d-base);
}
.bag.is-open { translate: 0 0; visibility: visible; }
.bag__head { display: flex; justify-content: space-between; align-items: center; }
.bag__items { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: var(--s3); }
.bag__row { display: grid; grid-template-columns: 4.5rem 1fr auto; gap: var(--s3); align-items: start; }
.bag__row img { width: 100%; aspect-ratio: 3/4; object-fit: cover; border-radius: var(--r-sm); }
.bag__empty { color: var(--c-ink-soft); font-size: var(--fs-small); }
.bag__foot { border-top: var(--border-w) solid var(--c-line); padding-top: var(--s3); display: flex; flex-direction: column; gap: var(--s3); }
.bag__total { display: flex; justify-content: space-between; font-family: var(--f-display); font-size: var(--fs-h3); }
.bag__scrim { position: fixed; inset: 0; z-index: 390; background: color-mix(in oklab, var(--c-ink) 45%, transparent); opacity: 0; visibility: hidden; transition: opacity var(--d-base), visibility var(--d-base); }
.bag__scrim.is-open { opacity: 1; visibility: visible; }

/* ==========================================================================
   OVERHAUL — heavy masthead type, a header that belongs to the page,
   and calls to action you can actually see.
   ========================================================================== */

/* The previous face carried an optical-size axis that had to be pinned to its
   small-text end or the hairlines dropped out on screen. DM Serif Display has
   no such axis and no weight axis either — it is drawn once, correctly, and
   needs no tuning. Nothing to declare here any more. */

/* Caps are opt-in, never global — product names must stay sentence case. */
.caps {
  text-transform: uppercase;
  letter-spacing: var(--ls-display);
  font-weight: 800;
}

/* --------------------------------------------------------------------------
   HEADER — transparent over the hero, solid once you leave it
   -------------------------------------------------------------------------- */
.nav {
  --nav-fg: var(--c-ink);
  padding-block: clamp(1.1rem, 2vw, 1.6rem);
  color: var(--nav-fg);
  gap: var(--s5);
}

/* Over the hero photograph the header is light and has no background at all. */
.nav--over {
  --nav-fg: #FFF6EA;
  background: transparent;
  border-bottom-color: transparent;
}
.nav--over .mark { color: var(--nav-fg); }

.nav__mark .mark { --mark-w: clamp(140px, 14vw, 190px); }

.nav__links { gap: clamp(1.25rem, 2.4vw, 2.5rem); }

.nav__link {
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  color: var(--nav-fg);
  padding-block: 0.5em;
}

/* Once the hero is behind you the bar becomes solid navy and condenses. */
/* Once you leave the hero the bar goes light, not dark: it then sits on the
   page's own apricot rather than floating as a second dark band. */
.nav.is-stuck {
  --nav-fg: var(--c-ink);
  background: color-mix(in oklab, var(--c-canvas) 92%, transparent);
  backdrop-filter: blur(16px);
  border-bottom-color: var(--c-line);
  padding-block: 0.85rem;
}
.nav.is-stuck .mark { color: var(--c-warm); }

.nav__actions { display: flex; align-items: center; gap: clamp(0.75rem, 1.6vw, 1.5rem); }

.nav__icon {
  display: inline-flex; align-items: center; gap: 0.5em;
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  color: var(--nav-fg);
  padding-block: 0.5em;
}
.nav__icon:hover { opacity: 0.72; }

.nav__toggle { font-size: var(--fs-micro); font-weight: 600; color: var(--nav-fg); }

/* Keep the real navigation for as long as it genuinely fits. At full size the
   bar needs 1111px, but most of that is the wordmark, 70px gutters and a
   "Shop all" link that duplicates the menu — so trim those first and only
   fall back to a hamburger when the links themselves would collide. */
@media (max-width: 1200px) {
  .nav { gap: var(--s3); padding-inline: clamp(1.25rem, 3vw, 2.25rem); }
  .nav__mark .mark { --mark-w: 150px; }
  .nav__actions > .nav__icon:not(.bag-btn) { display: none; }
  .nav__links { gap: clamp(0.85rem, 1.7vw, 1.5rem); }
  .nav__link { font-size: 0.8125rem; letter-spacing: 0.07em; }
}
@media (max-width: 880px) {
  .nav__links { display: none; }
  .nav__toggle { display: inline-flex; }
}

/* --------------------------------------------------------------------------
   HERO — one photograph, one masthead, two actions
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding-block: clamp(7rem, 14vh, 10rem) clamp(3rem, 7vh, 5rem);
  overflow: clip;
  background: #101828;
  color: #FFF6EA;
  isolation: isolate;
}

.hero__bg { position: absolute; inset: 0; z-index: 0; }
.hero__bg img, .hero__bg .media__ph {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 65% 30%;
}

/* Two scrims doing different jobs: a floor so the bottom copy always holds,
   and a soft left wash so the masthead never fights the figure. */
.hero__bg::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(10,16,28,0.94) 0%, rgba(10,16,28,0.74) 30%, rgba(10,16,28,0.30) 62%, rgba(10,16,28,0.48) 100%),
    linear-gradient(to right, rgba(10,16,28,0.88) 0%, rgba(10,16,28,0.66) 34%, rgba(10,16,28,0.26) 62%, rgba(10,16,28,0.04) 100%);
}

.hero__inner { position: relative; z-index: 2; }

.hero__eyebrow {
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--c-warm);
  display: flex; align-items: center; gap: 0.9em;
}
.hero__eyebrow::before { content: ""; width: 2.5rem; height: 1px; background: currentColor; }

.hero__title {
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(2.4rem, 6.1vw, 5.5rem);
  line-height: 0.9;
  letter-spacing: -0.028em;
  text-transform: uppercase;
  margin-block: clamp(0.9rem, 1.6vw, 1.4rem) clamp(0.9rem, 1.6vw, 1.25rem);
  max-width: 15ch;
  /* A masthead never breaks a word. */
  overflow-wrap: normal;
  hyphens: none;
}
.hero__title em {
  display: block;
  font-style: italic;
  font-weight: var(--fw-display);
  /* Subordinate to the line above, not competing with it. */
  font-size: 0.72em;
  margin-top: 0.18em;
  color: var(--c-warm);
}

.hero__lede {
  font-size: clamp(1.0625rem, 1.35vw, 1.3rem);
  line-height: 1.5;
  color: rgba(255, 246, 234, 0.82);
  max-width: 42ch;
}

.hero__cta { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: clamp(1.75rem, 3vw, 2.75rem); }

.hero__meta {
  margin-top: clamp(1.75rem, 3.5vw, 3rem);
  display: flex; flex-wrap: wrap; gap: clamp(1.5rem, 3vw, 3rem);
  padding-top: var(--s3);
  border-top: 1px solid rgba(255, 246, 234, 0.18);
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  color: rgba(255, 246, 234, 0.66);
}

/* --------------------------------------------------------------------------
   BUTTONS — the old ones were 72px wide and 11px tall. These are actions.
   -------------------------------------------------------------------------- */
.btn {
  --btn-py: 1.15em;
  --btn-px: 2.4em;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: var(--ls-ui);
  min-width: 12rem;
  justify-content: center;
}
.btn--lg { --btn-py: 1.3em; --btn-px: 3em; min-width: 15rem; font-size: 1rem; letter-spacing: 0.1em; }
.btn--text { font-size: 0.9375rem; }

.hero .btn { --btn-bg: var(--c-warm); --btn-bd: var(--c-warm); --btn-fg: #16203A; }
.hero .btn:hover { --btn-bg: #FFF6EA; --btn-bd: #FFF6EA; --btn-fg: #16203A; }
/* Ghost buttons are outlined, not filled — so the outline has to carry the
   whole button. 1px disappeared against photography; 2px is the floor. */
.btn--ghost { --border-w: 2px; }

/* Amber outline and amber text wherever the button sits on something dark.
   Deliberately NOT applied on the light apricot canvas: #E9A94B on #F8EDDF is
   about 1.8:1, which is unreadable — there the ghost button keeps navy. */
.hero .btn--ghost,
.evening .btn--ghost,
.seq .btn--ghost,
.at-band--bg .btn--ghost,
.lastcall .btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--c-warm);
  --btn-bd: var(--c-warm);
}
.hero .btn--ghost:hover,
.evening .btn--ghost:hover,
.seq .btn--ghost:hover,
.at-band--bg .btn--ghost:hover,
.lastcall .btn--ghost:hover {
  --btn-bg: var(--c-warm);
  --btn-fg: #16203A;
  --btn-bd: var(--c-warm);
}

/* --------------------------------------------------------------------------
   CATEGORY TILES — the clearest call to action on the page
   -------------------------------------------------------------------------- */
.tiles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(0.5rem, 1vw, 1rem);
}
@media (max-width: 820px) { .tiles { grid-template-columns: 1fr; } }

.tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: var(--r-md);
  isolation: isolate;
  background: #101828;
}
.tile .media { --ar: 3 / 4; border-radius: 0; }
.tile .media::after {
  content: "";
  position: absolute; inset: 0; z-index: 2;
  background: linear-gradient(to top, rgba(10,16,28,0.86) 0%, rgba(10,16,28,0.32) 42%, transparent 70%);
  transition: opacity var(--d-base) var(--e-out);
}
.tile img, .tile .media__ph { transition: scale var(--d-slow) var(--e-signature); }
.tile:hover img, .tile:hover .media__ph { scale: 1.045; }

.tile__body {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 3;
  padding: clamp(1.25rem, 2.4vw, 2rem);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s3);
  color: #FFF6EA;
}
.tile__label {
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(1.75rem, 3.2vw, 2.75rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.tile__go {
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--ls-ui);
  text-transform: uppercase;
  white-space: nowrap;
  padding-bottom: 0.35em;
  border-bottom: 2px solid var(--c-warm);
  transition: color var(--d-fast) var(--e-out);
}
.tile:hover .tile__go { color: var(--c-warm); }

/* On a phone the nav can carry the mark, the bag and the menu — nothing more.
   "Shop all" wrapped to two lines and crowded the other two; it lives in the
   menu panel regardless. */
@media (max-width: 700px) {
  .nav__mark .mark { --mark-w: 124px; }
  .nav__actions { gap: var(--s3); }
}

/* Nav items sized as navigation, not as fine print. */
.nav__link, .nav__icon, .nav__toggle { font-size: 0.9375rem; letter-spacing: 0.09em; }
@media (max-width: 1200px) { .nav__link { font-size: 0.875rem; } .nav__links { gap: clamp(1rem, 1.8vw, 1.75rem); } }

/* --------------------------------------------------------------------------
   INVERTED FOOTER — the page closes on navy, mirroring the hero
   Re-points the same tokens rather than hard-coding colours, so every
   component inside (links, rules, the stacked wordmark) follows automatically.
   -------------------------------------------------------------------------- */
.foot {
  --c-canvas:   #101828;
  --c-surface:  #172034;
  --c-ink:      #F4EBDF;
  --c-ink-soft: #A7AFC0;
  --c-line:     #2A3550;
  --c-accent:   #E9A94B;
  --c-on-accent: #101828;

  background: var(--c-canvas);
  color: var(--c-ink);
  border-top: 0;
  padding-block: clamp(3.5rem, 7vw, 6rem) clamp(2rem, 4vw, 3rem);
  margin-top: clamp(3rem, 7vw, 6rem);
}
.foot .mark { color: var(--c-ink); }
.foot__head { color: var(--c-ink-soft); }
.foot__list a { color: var(--c-ink); }
.foot__list a:hover { color: var(--c-accent); }
.foot .horizon { background: var(--c-line); opacity: 1; }

@media (max-width: 560px) { .btn--lg { font-size: 0.9375rem; } }

/* --------------------------------------------------------------------------
   Prices in maroon. A price is the one number on the page that should catch
   the eye without shouting, and navy-on-apricot made it disappear into the
   body copy.
   -------------------------------------------------------------------------- */
.prod__price, .pdp__price, .bag__total span:last-child, .price {
  color: var(--c-price);
  font-family: var(--f-display);
  font-weight: var(--fw-display);
}
.pdp__price { font-size: clamp(1.5rem, 2.4vw, 2.1rem); }
.prod__price { font-size: 1.0625rem; }

/* The evening/footer inversions need a maroon that carries on navy. */
.evening, .foot, .hero { --c-price: #E9A0A8; }

/* Product title and stat figures inherit --fw-display rather than naming a
   weight. With a single-weight face any literal number here is either a no-op
   or synthetic bold, and synthetic bold on a high-contrast serif smears. */
.pdp__name { font-weight: var(--fw-display); line-height: 1.02; }
.stat { font-family: var(--f-display); font-weight: var(--fw-display); }

/* The closing band can carry a photograph behind it. Scrimmed heavily —
   this is a call to action, so the type wins and the image sets the mood. */
.at-band--bg { position: relative; overflow: clip; }
.at-band--bg::before {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  background: var(--band-img) center / cover no-repeat;
  opacity: 0.42;
}
.at-band--bg::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(to right, rgba(16,24,40,0.92), rgba(16,24,40,0.62) 55%, rgba(16,24,40,0.86));
}
.at-band--bg > * { position: relative; z-index: 2; }

/* ==========================================================================
   THE RIBBON — an endless band of the house name and the three occasions
   ========================================================================== */
.ribbon {
  overflow: hidden;
  display: flex;
  background: var(--c-ink);
  color: var(--c-canvas);
  padding-block: clamp(0.9rem, 1.8vw, 1.5rem);
  border-block: 1px solid var(--c-ink);
}
.ribbon__track { display: flex; flex: none; align-items: center; will-change: transform; }
.ribbon__item {
  flex: none;
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-right: clamp(1.5rem, 3vw, 3rem);
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(1.5rem, 3.4vw, 3rem);
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ribbon__item i {
  flex: none;
  width: 0.42em; height: 0.42em;
  border-radius: 50%;
  background: var(--c-warm);
}
.ribbon--warm { background: var(--c-warm); color: #16203A; border-color: var(--c-warm); }
.ribbon--warm .ribbon__item i { background: #16203A; }

/* ==========================================================================
   THE PINNED SEQUENCE — the set piece
   ========================================================================== */
.seq {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  overflow: clip;
  background: #101828;
  color: #FFF6EA;
  isolation: isolate;
}
.seq__frames { position: absolute; inset: 0; z-index: 0; }
.seq__frame { position: absolute; inset: 0; opacity: 0; }
.seq__frame:first-child { opacity: 1; }
/* Every one of these is a portrait shot with the subject near the middle, and
   the type is centred over it — so no crop position can win: move her left and
   she meets the descenders, move her right and the headline crosses her face.
   The crop only has to keep heads in frame; the scrim below does the real work
   of separating type from photograph. */
/* These are 3:4 portraits in a ~2.1:1 band, so cover shows only ~35% of each
   image's height — no position can fit a full-length figure, every value just
   picks a different slice. Take the top: a head-and-shoulders crop reads as
   deliberate, where a mid-body band with the head sliced off reads as a
   mistake. The scrim below separates the type. */
.seq__frame img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 0%; }
.seq__frames::after {
  content: "";
  position: absolute; inset: 0; z-index: 2;
  background:
    /* A deep, soft pool centred on the type. Wide and gradual so it reads as
       depth of field rather than a box drawn over the picture — the subject
       stays legible at the edges while the headline sits on near-solid navy. */
    radial-gradient(58% 46% at 50% 46%,
      rgba(10,16,28,0.90) 0%, rgba(10,16,28,0.74) 45%, transparent 100%),
    linear-gradient(to top, rgba(10,16,28,0.94), rgba(10,16,28,0.62) 45%, rgba(10,16,28,0.82));
}

.seq__inner { position: relative; z-index: 3; text-align: center; padding: var(--gutter); width: 100%; }
.seq__kicker {
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  font-weight: 600;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--c-warm);
}
.seq__words { position: relative; height: clamp(2.75rem, 11vw, 10rem); margin-block: clamp(0.75rem, 2vw, 1.5rem); }
.seq__word {
  position: absolute; inset: 0;
  opacity: 0;
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(2.75rem, 11vw, 10rem);
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  display: grid; place-items: center;
}
.seq__word:first-child { opacity: 1; }

/* One CTA per frame, stacked in the same spot and swapped with the word, so
   the button always points at the category currently on screen. Mirrors the
   word mechanism exactly, including the safe default: with no JS at all the
   first one is visible and the rest are transparent but still in the layout,
   which is what keeps the section from collapsing. */
.seq__ctas { position: relative; display: grid; place-items: center; min-height: 3.4rem; margin-top: var(--s3); }
/* visibility, not just opacity: three links stacked in one grid cell would all
   stay clickable at opacity 0, and the last in source order would win every
   click. GSAP drives these with autoAlpha, which sets visibility for us. */
.seq__cta { grid-area: 1 / 1; opacity: 0; visibility: hidden; }
.seq__cta:first-child { opacity: 1; visibility: visible; }
.seq__note { font-size: clamp(1rem, 1.3vw, 1.2rem); color: rgba(255,246,234,0.82); max-width: 44ch; margin-inline: auto; }
.seq__bar { width: min(320px, 60vw); height: 2px; margin: clamp(1.5rem,3vw,2.5rem) auto 0; background: rgba(255,246,234,0.22); }
.seq__bar span { display: block; height: 100%; background: var(--c-warm); transform-origin: left center; }

/* Reduced motion never gets the pin, so it must never see the stack either. */
@media (prefers-reduced-motion: reduce) {
  .seq { min-height: 0; padding-block: clamp(3rem, 8vw, 5rem); }
  .seq__frames { position: relative; height: 60vh; }
  .seq__frame:not(:first-child) { display: none; }
  .seq__words { height: auto; }
  .seq__word { position: relative; }
  .seq__word:not(:first-child) { display: none; }
  .seq__cta:not(:first-child) { display: none; }
}

/* Below the pin breakpoint the sequence becomes an ordinary stack. */
@media (max-width: 1023px) {
  .seq { min-height: 0; padding-block: clamp(3rem, 8vw, 5rem); }
  .seq__frames { position: relative; height: 60vh; }
  .seq__frame { position: absolute; }
  .seq__frame:not(:first-child) { display: none; }
  .seq__words { height: auto; }
  .seq__word { position: relative; }
  .seq__word:not(:first-child) { display: none; }
  .seq__cta:not(:first-child) { display: none; }
}

/* ==========================================================================
   REVIEWS — social proof between the closing call and the footer
   ========================================================================== */
.reviews { padding-block: clamp(3.5rem, 8vw, 7rem); }
.reviews__head {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: var(--s4);
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.reviews__score { display: flex; align-items: center; gap: var(--s3); }
.reviews__num {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: clamp(2.5rem, 5vw, 4rem); line-height: 1;
  color: var(--c-ink);
}
.reviews__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1rem, 2vw, 2rem); }
@media (max-width: 900px) { .reviews__grid { grid-template-columns: 1fr; } }

.review {
  display: flex; flex-direction: column; gap: var(--s3);
  padding: clamp(1.5rem, 2.6vw, 2.25rem);
  border: 1px solid var(--c-line);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.review__quote {
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(1.15rem, 1.7vw, 1.4rem);
  line-height: 1.3;
}
.review__meta { margin-top: auto; display: flex; flex-direction: column; gap: 0.2em; }
.review__who { font-family: var(--f-ui); font-size: var(--fs-small); font-weight: 600; }
.review__what { font-family: var(--f-ui); font-size: var(--fs-micro); letter-spacing: var(--ls-ui); text-transform: uppercase; color: var(--c-ink-soft); }

.stars { display: flex; gap: 0.18em; color: var(--c-price); font-size: 1rem; line-height: 1; }
.stars[data-stars] span { opacity: 0.22; }
.stars[data-stars="5"] span { opacity: 1; }

/* The final call, sitting directly above the footer */
.lastcall {
  display: grid; grid-template-columns: 1.2fr 1fr; gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  padding: clamp(2rem, 4vw, 3.5rem);
  border-radius: var(--r-lg);
  background: var(--c-ink);
  color: #FFF6EA;
  --c-ink-soft: rgba(255,246,234,0.72);
}
@media (max-width: 820px) { .lastcall { grid-template-columns: 1fr; } }
.lastcall__title {
  font-family: var(--f-display); font-weight: var(--fw-display);
  font-size: clamp(1.75rem, 3.4vw, 2.9rem); line-height: 1.02;
  letter-spacing: -0.02em;
}
.lastcall__actions { display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: flex-end; }
@media (max-width: 820px) { .lastcall__actions { justify-content: flex-start; } }
.lastcall .btn { --btn-bg: var(--c-warm); --btn-bd: var(--c-warm); --btn-fg: #16203A; }
.lastcall .btn:hover { --btn-bg: #FFF6EA; --btn-bd: #FFF6EA; }
.lastcall .btn--ghost { --btn-bg: transparent; --btn-fg: #FFF6EA; --btn-bd: rgba(255,246,234,0.45); }
.lastcall .btn--ghost:hover { --btn-bg: #FFF6EA; --btn-fg: #16203A; --btn-bd: #FFF6EA; }

/* The footer now butts straight onto the last call. */
.foot { margin-top: 0; }
/* ==========================================================================
   HOLOGRAPHIC CARDS

   Rebuilt for cost, not for looks — the looks are unchanged.

   The first version animated background-position on layers that each carried
   mix-blend-mode, a filter, and background-blend-mode across three layers, one
   of them a live feTurbulence SVG. background-position cannot be composited,
   so every pointer move repainted all of it: a Chrome trace showed ~480 paint
   events for ONE card hover, and Safari is far worse — WebKit has no fast path
   for background-blend-mode and drops color-dodge to software compositing.

   The rules now:
     - the texture is ONE baked bitmap (assets/img/holo-cosmos.jpg); no SVG
       filter, no background-blend-mode, nothing to re-rasterise
     - only transform and opacity change per frame, both compositor-only
     - exactly one mix-blend-mode per overlay, and no filter on anything moving
     - the moving layer is oversized and clipped by its parent, so translating
       it never exposes an edge

   THE REST STATE IS STILL THE CSS DEFAULT: flat and invisible until JS raises
   --holo, so reduced motion and a JS failure are both correct with no script.
   ========================================================================== */
[data-holo] {
  /* Unitless: quickTo/springs cannot interpolate a unit string on a custom
     property, so the numbers animate and the unit is applied in calc(). */
  --rx: 0;             /* degrees   */
  --ry: 0;
  --mx: 50;            /* pointer, percent */
  --my: 50;
  --bx: 50;
  --by: 50;
  --holo: 0;           /* 0 at rest, 1 while hovered */
  --holo-tilt: 1;

  position: relative;
  transform-style: preserve-3d;
  isolation: isolate;
}

/* Decoration only — these must never intercept the card's link. */
.holo__foil,
.holo__glare {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  border-radius: inherit;
  /* Clips the oversized child below. Also stops a card's repaint spilling. */
  overflow: hidden;
}

/* Sit on the photograph, not over the name and price. */
[data-holo] .holo__foil,
[data-holo] .holo__glare { inset: 0 0 auto 0; aspect-ratio: var(--holo-ar, 3 / 4); }
.prod .holo__foil,
.prod .holo__glare {
  inset: var(--prod-pad) var(--prod-pad) auto;
  border-radius: calc(var(--r-lg) - var(--prod-pad) / 2);
}
.tile .holo__foil, .tile .holo__glare,
.review .holo__foil, .review .holo__glare { inset: 0; aspect-ratio: auto; }

/* One blended surface each. The blend lives on the clipping parent so the
   moving child underneath is a plain, unblended texture. */
.holo__foil  { mix-blend-mode: color-dodge; opacity: calc(var(--holo) * 0.5); }
.holo__glare { mix-blend-mode: hard-light;  opacity: calc(var(--holo) * 0.5); }

/* The only thing that moves. Oversized by half in every direction so a
   translate can never drag an edge into view, and animated purely by
   transform — no paint, no blend, no filter. */
.holo__foil::after,
.holo__glare::after {
  content: "";
  position: absolute;
  inset: -50%;
}

.holo__foil::after {
  background: url("/assets/img/holo-cosmos.jpg") center / 150% 150%;
  /* Drifts slower than the cursor; that lag is what reads as depth. */
  transform: translate3d(calc((var(--mx) - 50) * -0.22%), calc((var(--my) - 50) * -0.22%), 0);
}

.holo__glare::after {
  /* Tone baked into the stops rather than applied with filter(). */
  background: radial-gradient(circle at 50% 50%,
    rgba(255, 252, 245, 0.9) 0%,
    rgba(160, 160, 160, 0.22) 30%,
    rgba(28, 30, 38, 0.8) 72%);
  transform: translate3d(calc((var(--mx) - 50) * 0.5%), calc((var(--my) - 50) * 0.5%), 0);
}

/* Hover-capable, fine-pointer devices only. A tilt that needs a cursor should
   never be inherited by a phone. */
@media (hover: hover) and (pointer: fine) {
  [data-holo] {
    /* 600px and rotateY-before-rotateX, matching the reference exactly. The
       springs write --rx/--ry already scaled to a ±14.29deg maximum, so the
       magnitude lives in the JS, not here. */
    transform:
      perspective(600px)
      rotateY(calc(var(--ry) * 1deg * var(--holo-tilt)))
      rotateX(calc(var(--rx) * 1deg * var(--holo-tilt)));
    /* Static. box-shadow is not a compositable property, so driving its offset
       and blur from --rx/--ry repainted the whole card on every pointer move —
       the last per-frame paint left after the overlays were fixed. The tilt
       already carries the sense of lift; the shadow only has to ground it. */
    box-shadow: 0 14px 34px rgba(22, 32, 58, 0.10);
  }
  /* Deliberately NO transform on any direct child of the card. Two traps:
     preserve-3d orders children by depth rather than z-index, so nudging the
     photograph forward puts it in front of the link covering the card; and any
     transform makes that element the containing block for absolutely
     positioned descendants, collapsing .prod__link::after from the whole card
     to whatever it is nested in. Either silently swallows clicks. The
     overlays' ::after children are exempt — they are inside a clipping,
     pointer-events:none layer and contain no links. */
}

/* Large surfaces tilt less — a 430×570 tile pitching hard looks wobbly. */
[data-holo="gentle"] { --holo-tilt: 0.5; }

/* Blend cost scales with area, and the tiles are the biggest surfaces on the
   site. They get the glare only: no texture layer at all. */
[data-holo="gentle"] .holo__foil { display: none; }
[data-holo="gentle"] .holo__glare { opacity: calc(var(--holo) * 0.34); }

/* Reviews have no photograph under them; color-dodge against a light card
   surface clips straight to white. */
.review .holo__foil { mix-blend-mode: overlay; opacity: calc(var(--holo) * 0.3); }
.review .holo__glare { mix-blend-mode: soft-light; }

/* ==========================================================================
   AMBER PASS — the accent doing more work
   ========================================================================== */

/* The wordmark is painted with currentColor via a mask, so it takes the
   accent for free in both the header and the footer. */
.nav__mark { color: var(--c-warm); }
.foot .mark { color: var(--c-warm); }

/* Footer base line. */
.foot__base .micro { color: var(--c-warm); opacity: 0.85; }

/* The pressed filter: amber label on the navy pill. */
.filter[aria-pressed="true"] { color: var(--c-warm); }

/* Ghost buttons: outline the same colour as the label, always. A ghost button
   whose border is lighter than its text reads as disabled. */
.btn--ghost { --btn-bd: var(--btn-fg); }

/* Menu overlay headings — larger, and amber so they carry against the navy. */
.menu__link {
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  color: var(--c-warm);
  line-height: 1.08;
}
.menu__link:hover { color: var(--c-accent-2); }

/* Prices sit beside a display-size product name and were losing to it. */
.prod__price {
  font-size: clamp(1.35rem, 1.9vw, 1.75rem);
  letter-spacing: -0.01em;
}

/* Keep each label on one line. Forcing the ROW not to wrap just squeezed the
   buttons until their text wrapped instead, which is worse — two ragged
   three-line pills. Let the row wrap as it likes; the buttons stay whole. */
.btn { white-space: nowrap; }

/* The menu opens from a navy header, so it should be navy. It also has to be:
   amber on the light canvas measures 1.77:1, which fails even the 3:1 bar for
   large text. On this ground the same amber is 8.65:1. */
.menu {
  --c-canvas:   #101828;
  --c-surface:  #172034;
  --c-ink:      #F4EBDF;
  --c-ink-soft: #A7AFC0;
  --c-line:     #2A3550;
  --c-accent:   #E9A94B;
  --c-on-accent: #101828;
  background: #101828;
  color: var(--c-ink);
  color-scheme: dark;
}
.menu .btn { --btn-bg: var(--c-warm); --btn-bd: var(--c-warm); --btn-fg: #16203A; }
.menu .btn:hover { --btn-bg: #FFF6EA; --btn-bd: #FFF6EA; }
.menu__close { color: var(--c-ink); }

/* The wordmark colour, set late and specifically enough to beat
   `.nav--over .mark`, which pins it to the nav foreground. */
.nav .mark,
.nav--over .mark { color: var(--c-warm); }

/* Footer lockup: GLENDA in amber, IRELAND in white beneath it. */
.foot__mark { display: block; }
.foot .mark { color: var(--c-warm); }
.foot__ireland {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--f-ui);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-mark);
  text-transform: uppercase;
  text-indent: var(--ls-mark);
  color: #FFFFFF;
}

/* Footer column headings — bigger and amber. */
.foot__head {
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(1.15rem, 1.6vw, 1.5rem);
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--c-warm);
}

/* ==========================================================================
   CHECKOUT
   ========================================================================== */

/* Fields are the one place the page should read as "fill this in", so they get
   a white well rather than the apricot canvas showing through. */
.field__input { background: #FFFFFF; }
.evening .field__input,
.menu .field__input { background: color-mix(in oklab, #FFFFFF 8%, transparent); }

/* Each step is a real group, and looks like one. */
.checkout__step {
  border: var(--border-w) solid var(--c-line);
  border-radius: var(--r-lg);
  background: color-mix(in oklab, #FFFFFF 55%, transparent);
  padding: clamp(1.25rem, 2.4vw, 2rem);
  display: grid;
  gap: var(--s3);
}
.checkout__step legend {
  font-family: var(--f-display);
  font-weight: var(--fw-display);
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--c-ink);
  padding-inline: 0.5rem;
  margin-inline-start: -0.5rem;
}
.checkout__step legend .num {
  color: var(--c-warm);
  margin-right: 0.4em;
}

/* The bag row is a three-column grid because the slide-out bag has a thumbnail
   in the first column. The checkout and cart summaries have no image, so the
   product name was being forced into that 4.5rem column and wrapping three
   times. Two columns when there is nothing to put in the first. */
.bag__row:not(:has(img)) { grid-template-columns: 1fr auto; }
[data-checkout-summary] .bag__row,
[data-cart-page] .bag__row,
.conf-summary .bag__row { grid-template-columns: 1fr auto; }

/* Room to breathe in the summary panel. */
[data-checkout-summary] .bag__row,
.conf-summary .bag__row { padding-block: 0.55rem; align-items: baseline; }
[data-checkout-summary] .bag__row + .bag__row,
.conf-summary .bag__row + .bag__row { border-top: 1px solid color-mix(in oklab, var(--c-line) 60%, transparent); }

/* Pages that close on a full-bleed band (home, collections, atelier) get their
   breathing room from the band's own padding. Pages that close on a plain wrap
   or header — checkout, cart, confirmation, 404 — had nothing, so the last
   control sat flush against the footer. */
main > .wrap:last-child,
main > .phead:last-child { padding-bottom: var(--sec-y); }
