@charset "UTF-8";

/* =====================================================================
   VELA — style.css
   Shared by every page. The bright system: cream ground, warm ink,
   one sea-blue accent. See DESIGN.md — every value here traces to a
   token defined in §01.

   Performance contract:
   every MOVING property in this file is transform or opacity. Nothing
   animates width, height, top, left or margin, so no interaction here
   can trigger layout. Colour transitions (paint only) are allowed on
   interactive surfaces. will-change is declared on moving layers only.

     01  Tokens
     02  Reset & document
     03  Type & utilities
     04  Reveal primitive & entrances
     05  Buttons
     06  Notice strip
     07  Masthead
     08  Menu sheet
     09  Hero                       (home)
     10  Section heads
     11  Product grid & card        (home)
     12  Promise strip              (home)
     13  Creed                      (home)
     14  The film                   (home)
     15  Lookbook                   (home)
     16  Atelier                    (home)
     17  Product page: layout & gallery
     18  Product page: buy column
     19  The commitment control
     20  Product page: folds, cross-sell, buy bar
     21  Footer
     22  Bag & saved drawer
     23  Static pages
     24  Cookie consent
     25  Interaction feedback
     26  Responsive
     27  Reduced motion, print, forced colours
   ===================================================================== */


/* =====================================================================
   01  Tokens
   ===================================================================== */

:root {
  /* Grounds. Warm cream, never white: #fff behind photographs shot in
     warm light makes every one of them look grey. */
  --paper: #f5f0e8;     /* page                                  */
  --sand:  #ece5d9;     /* raised bands: notice, footer, panels  */
  --well:  #e6ded0;     /* behind images while they load         */

  /* Ink. Measured on the darkest ground text ever sits on (--well):
     ink 12.70, ink-2 7.65, ink-3 5.24 — ink-3 is the TEXT FLOOR. */
  --ink:   #1f1c19;
  --ink-2: #46403a;
  --ink-3: #5f5850;

  /* Lines. --line-strong is the only one that may identify a control on
     its own (inputs, outlined buttons): 3.70:1 on paper, 3.36 on sand. */
  --line:        rgb(31 28 25 / 0.14);
  --line-2:      rgb(31 28 25 / 0.08);
  --line-strong: rgb(31 28 25 / 0.55);

  /* One accent. Sea blue: interaction, focus, confirmation. 8.06:1 on
     paper, and paper text on it holds the same. */
  --sea:    #1e4d63;
  --signal: #b3325f;    /* a saved heart — the Ensign's pink sail, deepened to 5.2:1 */
  --warn:   #a3322c;    /* refusals — 6.07:1 on paper            */
  --film:   #07090c;    /* the one dark surface left: the night film */

  --shadow-1: 0 1px 2px rgb(60 44 28 / 0.06), 0 8px 20px -10px rgb(60 44 28 / 0.22);
  --shadow-2: 0 2px 6px rgb(60 44 28 / 0.07), 0 28px 60px -26px rgb(60 44 28 / 0.42);

  --r-xs: 4px;
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* Hebrew: Cormorant and Jost have no Hebrew letters, so each stack names
     a Hebrew family next (Frank Ruhl Libre, Assistant); the browser takes
     Latin from the first and Hebrew from the second, letter by letter. */
  --serif: "Cormorant Garamond", "Cormorant", "Frank Ruhl Libre", Garamond, "Times New Roman", serif;
  --sans:  "Jost", "Assistant", "Futura", "Avenir Next", -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;

  --t--2: clamp(0.6875rem, 0.66rem + 0.12vw, 0.75rem);
  --t--1: clamp(0.8125rem, 0.78rem + 0.15vw, 0.875rem);
  --t-0:  clamp(0.9375rem, 0.90rem + 0.20vw, 1.0625rem);
  --t-1:  clamp(1.125rem, 1.03rem + 0.45vw, 1.375rem);
  --t-2:  clamp(1.5rem,   1.25rem + 1.20vw, 2.25rem);
  --t-3:  clamp(2.25rem,  1.60rem + 2.60vw, 3.75rem);
  --t-4:  clamp(3rem,     1.80rem + 4.60vw, 6.4rem);

  --track-wide: 0.24em;
  --track-mid:  0.14em;

  /* Which way is forward. 1 left to right, -1 right to left: multiplies
     every slide and nudge, and names the edge growth starts from. */
  --dir: 1;
  --start: left;

  --s-3xs: 0.3125rem;
  --s-2xs: 0.625rem;
  --s-xs:  clamp(0.75rem, 0.71rem + 0.20vw, 0.9375rem);
  --s-sm:  clamp(1rem,    0.95rem + 0.25vw, 1.25rem);
  --s-md:  clamp(1.5rem,  1.40rem + 0.50vw, 2rem);
  --s-lg:  clamp(2rem,    1.75rem + 1.25vw, 3.25rem);
  --s-xl:  clamp(2.75rem, 2.20rem + 2.75vw, 4.5rem);
  --s-2xl: clamp(3.5rem,  2.50rem + 5.00vw, 7rem);

  --pad:   clamp(1rem, 0.6rem + 2vw, 3rem);
  --shell: min(100% - (2 * var(--pad)), 90rem);

  /* The sticky masthead: a 4rem bar plus the 2.75rem section row. Feeds
     scroll-padding so an anchor never lands under it. */
  --nav-h: 6.75rem;

  --ease:   cubic-bezier(0.16, 1, 0.3, 1);
  --spring: cubic-bezier(0.25, 1, 0.5, 1);
  --inout:  cubic-bezier(0.65, 0, 0.35, 1);

  --z-buybar: 50;
  --z-nav:    60;
  --z-veil:   80;
  --z-cart:   90;
  --z-drop:  100;
  --z-skip:  200;

  color-scheme: light;
}


/* =====================================================================
   02  Reset & document
   ===================================================================== */

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

html {
  /* Native smoothing for anchor jumps only. No custom scroll engine:
     intercepting the wheel is what puts a frame of latency on input. */
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 0.5rem);
  scrollbar-gutter: stable;
  background: var(--paper);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  min-height: 100svh;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--t-0);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.005em;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}

/* While the cart or the menu is up. Both elements are pinned:
   overflow:hidden on the root alone still lets iOS Safari rubber-band. */
html.is-locked,
html.is-locked body {
  overflow: hidden;
  touch-action: none;
  overscroll-behavior: none;
}

/* `hidden` must win over any component's own display value. Without
   this, `.cart { display: grid }` outranked the browser's [hidden] rule
   and the closed drawer stayed rendered off-screen — its shadow showing
   at the window edge, and its contents still in the accessibility tree. */
[hidden] { display: none !important; }

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

button, input, textarea, select {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
  background: none;
  border: 0;
}
button { cursor: pointer; -webkit-tap-highlight-color: transparent; }
a { color: inherit; text-decoration: none; -webkit-tap-highlight-color: transparent; }
ul, ol { list-style: none; padding: 0; }

::selection { background: var(--sea); color: var(--paper); }

:focus-visible { outline: 2px solid var(--sea); outline-offset: 3px; }
:focus:not(:focus-visible) { outline: none; }

.skip {
  position: fixed;
  top: var(--s-sm);
  inset-inline-start: var(--s-sm);
  z-index: var(--z-skip);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--s-2xs) var(--s-sm);
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--paper);
  font-size: var(--t--1);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  transform: translateY(-400%);
  transition: transform 0.3s var(--ease);
}
.skip:focus-visible { transform: translateY(0); }


/* =====================================================================
   03  Type & utilities
   ===================================================================== */

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.eyebrow {
  font-size: var(--t--2);
  font-weight: 400;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  -webkit-clip-path: inset(50%);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* A colourway dot. The ring is the reference's "this is the colour you
   are looking at" treatment; the inner hairline keeps a chalk swatch from
   vanishing into the cream behind it. */
.swatch {
  flex: none;
  width: 0.95rem;
  height: 0.95rem;
  border-radius: 50%;
  background: var(--swatch, var(--ink));
  box-shadow: inset 0 0 0 1px rgb(31 28 25 / 0.16),
              0 0 0 2px var(--paper),
              0 0 0 3px var(--line-strong);
}


/* =====================================================================
   04  Reveal primitive & entrances

   [data-reveal] arrives once, driven by the single scroll pass in app.js
   (§10b there) — not an IntersectionObserver, whose missed callbacks once
   left the whole shop at opacity 0. `.js` gates it: with JavaScript off,
   nothing is ever hidden. Layers are released once settled.

   The hero does NOT use it. It animates in with CSS keyframes that need
   no script at all, so the first screen can never wait on one.
   ===================================================================== */

.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 1.25rem, 0);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}
.js [data-reveal].is-in { opacity: 1; transform: translate3d(0, 0, 0); }
.js [data-reveal].is-settled { will-change: auto; }

/* Dealt left to right, not switched on. */
.js .grid [data-reveal]:nth-child(2),
.js .promise__item:nth-child(2),
.js .look__item:nth-child(2) { --reveal-delay: 90ms; }
.js .grid [data-reveal]:nth-child(3),
.js .promise__item:nth-child(3),
.js .look__item:nth-child(3) { --reveal-delay: 180ms; }
.js .grid [data-reveal]:nth-child(4),
.js .promise__item:nth-child(4),
.js .look__item:nth-child(4) { --reveal-delay: 270ms; }
.js .look__item:nth-child(5) { --reveal-delay: 360ms; }
/* Twelve frames: the later rows deal in pairs, not one long wait. */
.js .look__item:nth-child(7),
.js .look__item:nth-child(9),
.js .look__item:nth-child(12) { --reveal-delay: 90ms; }
.js .look__item:nth-child(10) { --reveal-delay: 180ms; }

@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 1.25rem, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes maskUp {
  from { transform: translate3d(0, 105%, 0); }
  to   { transform: translate3d(0, 0, 0); }
}


/* =====================================================================
   05  Buttons

   One language for every action: solid = the commitment, outline = a
   secondary route, text = an inline step onward. Pills throughout, so a
   control reads as pressable before it is read at all.
   ===================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  min-height: 3.25rem;
  padding: 0.95em 1.9em;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--sans);
  font-size: var(--t--1);
  font-weight: 500;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  text-align: center;
  white-space: nowrap;
  transition: transform 0.25s var(--spring),
              background-color 0.3s var(--ease),
              border-color 0.3s var(--ease),
              color 0.3s var(--ease),
              box-shadow 0.3s var(--ease);
}
.btn:active { transform: scale(0.98); }
.btn svg {
  width: 1.15em;
  height: 1.15em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.35s var(--ease);
}

.btn--solid {
  background-color: var(--ink);
  color: var(--paper);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 0.08), 0 10px 24px -14px rgb(31 28 25 / 0.6);
}

.btn--outline {
  border-color: var(--line-strong);
  color: var(--ink);
}

.btn--text {
  min-height: 3rem;
  padding: 0.4em 0.1em;
  border-radius: 0;
  color: var(--ink);
}

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

.btn:disabled { opacity: 0.35; cursor: not-allowed; }
.btn:disabled:active { transform: none; }

@media (hover: hover) {
  .btn--solid:not(:disabled):hover { background-color: var(--sea); }
  .btn--outline:hover { border-color: var(--ink); background-color: var(--sand); }
  .btn--text:hover svg { transform: scaleX(var(--dir)) translateX(4px); }
}


/* =====================================================================
   06  Notice strip
   ===================================================================== */

.notice {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 34rem) 2.75rem;
  justify-content: center;
  align-items: center;
  min-height: 2.5rem;
  background: var(--sand);
  border-bottom: 1px solid var(--line-2);
  color: var(--ink-2);
  font-size: var(--t--2);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  text-align: center;
}

.notice__arrow {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.5rem;
  color: var(--ink-2);
  transition: color 0.2s linear;
}
.notice__arrow svg {
  width: 1rem;
  height: 1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
@media (hover: hover) { .notice__arrow:hover { color: var(--ink); } }

/* All messages share one cell, so the strip never changes height. */
.notice__track { display: grid; overflow: hidden; }
.notice__msg {
  grid-area: 1 / 1;
  padding-block: 0.6rem;
  opacity: 0;
  transform: translate3d(0, 0.7em, 0);
  transition: opacity 0.45s var(--ease), transform 0.6s var(--ease);
}
.notice__msg.is-current { opacity: 1; transform: translate3d(0, 0, 0); }
.notice__msg.is-leaving { transform: translate3d(0, -0.7em, 0); }


/* =====================================================================
   07  Masthead

   Sticky rather than fixed: the notice strip scrolls away above it and
   nothing below needs a compensating offset. It slides out of the way
   while the visitor reads down, and back the moment they reach upward.
   ===================================================================== */

.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-nav);
  background: rgb(245 240 232 / 0.92);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid transparent;
  transform: translate3d(0, 0, 0);
  transition: transform 0.45s var(--ease), border-color 0.3s linear, box-shadow 0.3s linear;
  will-change: transform;
}
.nav.is-solid {
  border-bottom-color: var(--line-2);
  box-shadow: 0 10px 30px -24px rgb(60 44 28 / 0.45);
}
.nav.is-hidden { transform: translate3d(0, -100%, 0); box-shadow: none; }

.nav__bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--s-sm);
  width: var(--shell);
  min-height: 4rem;
  margin-inline: auto;
}
.nav__start { justify-self: start; display: flex; margin-inline-start: -0.6rem; }
.nav__end   { justify-self: end;   display: flex; gap: 0.15rem; margin-inline-end: -0.6rem; }

/* The wordmark, with the mark's own sail beneath it. Trailing tracking
   is cancelled with a negative margin, or the word sits off-centre by
   exactly one letter-space. */
.brand {
  display: grid;
  justify-items: center;
  gap: 0.15rem;
  padding-block: 0.35rem;
  color: var(--ink);
  line-height: 1;
}
.brand__word {
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.65rem, 1.35rem + 1vw, 2.15rem);
  letter-spacing: 0.3em;
  margin-right: -0.3em;
  text-transform: uppercase;
}
.brand__mark {
  width: 1.35rem;
  height: 1.35rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

.iconbtn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0.5rem 0.65rem;
  border-radius: var(--r-pill);
  color: var(--ink);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  transition: background-color 0.25s var(--ease);
}
@media (hover: hover) { .iconbtn:hover { background-color: var(--sand); } }

.iconbtn__icon {
  width: 1.4rem;
  height: 1.4rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Count badge. Hidden at zero — a "0" in the corner is noise — and it
   arrives with a spring when the first piece lands. aria-hidden: the
   button's own name carries the number. */
.badge {
  position: absolute;
  top: 0.2rem;
  inset-inline-start: 1.45rem;
  min-width: 1.15rem;
  height: 1.15rem;
  padding-inline: 0.3rem;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.66rem;
  font-weight: 500;
  line-height: 1.15rem;
  letter-spacing: 0;
  text-align: center;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.2s linear, transform 0.4s var(--spring);
}
[data-carrying="true"] .badge { opacity: 1; transform: scale(1); }
.saved .badge { background: var(--signal); }

.burger__lines {
  position: relative;
  display: inline-block;
  width: 1.35rem;
  height: 0.95rem;
}
.burger__lines i {
  position: absolute;
  inset-inline-start: 0;
  width: 100%;
  height: 1.5px;
  border-radius: 2px;
  background: currentColor;
}
.burger__lines i:nth-child(1) { top: 0; }
.burger__lines i:nth-child(2) { top: calc(50% - 0.75px); width: 70%; }
.burger__lines i:nth-child(3) { bottom: 0; }

/* The section row. Scrolls sideways if it ever outgrows a phone; the
   auto margins centre it without the "safe centring" problem, where a
   centred row that overflows cuts off its own first item. */
.cats {
  width: var(--shell);
  margin-inline: auto;
}
.cats__list {
  display: flex;
  gap: clamp(1.25rem, 3vw, 3rem);
  overflow-x: auto;
  scrollbar-width: none;
}
.cats__list::-webkit-scrollbar { display: none; }
.cats__list li:first-child { margin-left: auto; }
.cats__list li:last-child  { margin-right: auto; }

.cats__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: var(--t--2);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ink-2);
  transition: color 0.2s linear;
}
/* Padded out and pulled back by the same amount: "Shop" is 37px of text,
   and a touch target must be 44. The underline is inset to match, so it
   still runs under the word and not under the padding. */
.cats__link {
  padding-inline: 0.3rem;
  margin-inline: -0.3rem;
}
.cats__link::after {
  content: '';
  position: absolute;
  inset-inline-start: 0.3rem;
  inset-inline-end: calc(0.3rem + var(--track-wide));
  bottom: 0.6rem;
  height: 1.5px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: var(--start) center;
  transition: transform 0.4s var(--ease);
}
.cats__link.is-current { color: var(--ink); }
.cats__link.is-current::after { transform: scaleX(1); }
@media (hover: hover) {
  .cats__link:hover { color: var(--ink); }
  .cats__link:hover::after { transform: scaleX(1); }
}

/* How far down the page the reader is. scaleX only. It hangs just below
   the masthead, so when the masthead slides away while reading, the line
   is left behind at the top of the screen, whole. */
.nav__progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--sea);
  transform-origin: var(--start) center;
  transform: scaleX(var(--progress, 0));
  opacity: 0;
  transition: opacity 0.3s linear;
  pointer-events: none;
}
.nav.is-solid .nav__progress { opacity: 0.85; }


/* =====================================================================
   08  Menu sheet

   A modal from the left on every screen size. The veil and the panel
   are separate layers so each moves on its own compositor property.
   ===================================================================== */

.drop {
  position: fixed;
  inset: 0;
  z-index: var(--z-drop);
}

.drop__veil {
  position: absolute;
  inset: 0;
  background: rgb(31 28 25 / 0.32);
  opacity: 0;
  transition: opacity 0.45s var(--ease);
}

.drop__panel {
  position: absolute;
  inset-block: 0;
  inset-inline: 0 auto;
  width: min(26rem, 88vw);
  display: flex;
  flex-direction: column;
  gap: var(--s-md);
  padding: 0.75rem var(--s-md) var(--s-md);
  background: var(--paper);
  box-shadow: var(--shadow-2);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translate3d(calc(-102% * var(--dir)), 0, 0);
  transition: transform 0.55s var(--ease);
  will-change: transform;
}
.drop.is-open .drop__veil { opacity: 1; }
.drop.is-open .drop__panel { transform: translate3d(0, 0, 0); }

.drop__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-inline-end: -0.6rem;
}
.drop__title {
  font-size: var(--t--2);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.drop__close,
.cart__close {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: var(--ink);
  transition: background-color 0.2s linear;
}
.drop__close svg,
.cart__close svg {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}
@media (hover: hover) {
  .drop__close:hover,
  .cart__close:hover { background-color: var(--sand); }
}

.drop__nav { display: grid; gap: var(--s-md); }

.drop__primary a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding-block: 0.12em;
  font-family: var(--serif);
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.5rem);
  line-height: 1.12;
  color: var(--ink);
  transition: color 0.2s linear, transform 0.35s var(--ease);
}
@media (hover: hover) {
  .drop__primary a:hover { color: var(--sea); transform: translateX(calc(4px * var(--dir))); }
}

.drop__label {
  margin-bottom: -0.6rem;
  font-size: var(--t--2);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}

.drop__pieces {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.6rem;
}
.drop__pieces a {
  display: grid;
  gap: 0.45rem;
  font-size: var(--t--2);
  letter-spacing: 0.06em;
  line-height: 1.3;
  color: var(--ink-2);
}
.drop__pieces img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--r-sm);
  background: var(--well);
  transition: transform 0.6s var(--ease);
}
@media (hover: hover) {
  .drop__pieces a:hover { color: var(--ink); }
  .drop__pieces a:hover img { transform: translateY(-3px); }
}

.drop__secondary {
  display: grid;
  padding-top: var(--s-xs);
  border-top: 1px solid var(--line);
}
.drop__secondary a {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: var(--t--1);
  letter-spacing: 0.04em;
  color: var(--ink-2);
}
@media (hover: hover) { .drop__secondary a:hover { color: var(--ink); } }

.drop__foot {
  margin-top: auto;
  font-size: var(--t--1);
  color: var(--ink-3);
}


/* =====================================================================
   09  Hero                                                      (home)

   An editorial collage after 21st.dev's two-column serif hero: copy on
   the left, two overlapping photographs on the right, each a link to
   its own piece. Shoppable from the first screen.
   ===================================================================== */

.hero {
  width: var(--shell);
  margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: center;
  gap: var(--s-2xl);
  padding-block: var(--s-lg) var(--s-2xl);
}

.hero__copy {
  display: grid;
  justify-items: start;
  gap: var(--s-md);
}

.hero__title {
  font-size: var(--t-4);
  line-height: 0.94;
  letter-spacing: -0.02em;
}
.hero__title em { font-style: italic; color: var(--sea); }

/* The inner span rises out of its own overflow window. Padded on the
   right as well as below, or the italic's overhang is clipped. */
.mask {
  display: block;
  overflow: hidden;
  padding: 0 0.12em 0.1em 0;
  margin: 0 -0.12em -0.1em 0;
}
.mask > span { display: block; }

.hero__lede {
  max-width: 34ch;
  font-size: var(--t-1);
  font-weight: 300;
  line-height: 1.55;
  color: var(--ink-2);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-xs) var(--s-md);
}

.hero__facts {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: var(--s-lg);
  width: 100%;
  margin-top: var(--s-2xs);
  padding-top: var(--s-md);
  border-top: 1px solid var(--line);
}
/* Value above label for the eye; label first in the reading order. */
.hero__facts div { display: flex; flex-direction: column-reverse; gap: 0.3rem; }
.hero__facts dd {
  font-family: var(--serif);
  font-size: clamp(2rem, 1.6rem + 1.4vw, 2.75rem);
  line-height: 1;
  color: var(--ink);
}
.hero__facts small {
  margin-inline-start: 0.15em;
  font-family: var(--sans);
  font-size: 0.38em;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.hero__facts dt {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* The collage. The padding is the room the inset overlaps into. */
.hero__media {
  position: relative;
  padding-block: 0 9%;
  padding-inline: 13% 0;
}

/* Capped to the viewport so the whole hero — facts row included — fits a
   1440×900 laptop screen. When the cap binds the box goes a little wider
   than 4:5 and the plate crops vertically, anchored on the print. */
.collage__main {
  position: relative;
  display: block;
  aspect-ratio: 4 / 5;
  max-height: calc(100svh - 16rem);
  width: 100%;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--well);
  box-shadow: var(--shadow-2);
  isolation: isolate;
}
.collage__main img,
.collage__inset img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.2s var(--ease);
}
.collage__main img { object-position: 50% 40%; }

.collage__inset {
  position: absolute;
  inset-inline-start: 0;
  bottom: 0;
  z-index: 1;
  width: 37%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 6px solid var(--paper);
  border-radius: var(--r-md);
  background: var(--well);
  box-shadow: var(--shadow-2);
  isolation: isolate;
}

/* A price tag pinned on the photograph — the link's visible name. */
.tag {
  position: absolute;
  inset-inline-end: 1rem;
  bottom: 1rem;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding-block: 0.45rem;
  padding-inline: 1.1rem 0.45rem;
  border-radius: var(--r-pill);
  background: rgb(245 240 232 / 0.9);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: var(--shadow-1);
  color: var(--ink);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.tag__price { color: var(--ink-2); letter-spacing: 0.04em; }
.tag__go {
  width: 2rem;
  height: 2rem;
  padding: 0.45rem;
  border-radius: 50%;
  background: var(--ink);
  fill: none;
  stroke: var(--paper);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.35s var(--ease);
}
.tag--small {
  left: 0.5rem;
  right: 0.5rem;
  bottom: 0.5rem;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.45rem 0.8rem;
}

@media (hover: hover) and (pointer: fine) {
  .collage__main:hover img,
  .collage__inset:hover img { transform: scale(1.035); }
  .collage__main:hover .tag__go { transform: scaleX(var(--dir)) translateX(3px); }
}

/* Entrance — CSS only, so the first screen never waits on a script. */
.hero__eyebrow,
.hero__lede,
.hero__actions,
.hero__facts { animation: rise 0.9s var(--ease) both; }
.hero__eyebrow { animation-delay: 0.05s; }
.hero__lede    { animation-delay: 0.35s; }
.hero__actions { animation-delay: 0.45s; }
.hero__facts   { animation-delay: 0.55s; }
.hero__title .mask > span { animation: maskUp 1.1s var(--ease) both; }
.hero__title .mask:nth-child(1) > span { animation-delay: 0.1s; }
.hero__title .mask:nth-child(2) > span { animation-delay: 0.2s; }
.hero__media { animation: rise 1.1s var(--ease) 0.2s both; }


/* =====================================================================
   10  Section heads
   ===================================================================== */

.head {
  width: var(--shell);
  margin: 0 auto var(--s-lg);
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-2xs) var(--s-md);
}
.head__text { display: grid; gap: 0.6rem; }
.head__title { font-size: var(--t-3); }
.head__aside {
  max-width: 36ch;
  font-size: var(--t--1);
  color: var(--ink-3);
}


/* =====================================================================
   11  Product grid & card                                       (home)

   The card is the stretched-link pattern from 21st.dev's product card:
   the name is the one real link, and its ::after covers the whole tile,
   so the image, the price and the name all lead to the piece. The heart
   and the quick-add sizes sit ABOVE that layer as sibling buttons.
   ===================================================================== */

.shop { padding-block: var(--s-xl) var(--s-2xl); }

/* Two shelves, Tees and Long sleeves: twenty-six shirts in one run of
   cards is a wall, and a customer looking for a long sleeve should not
   have to scroll past every tee to find out there are any. The section
   row and the menu link straight to each shelf. */
.shelf + .shelf { margin-top: var(--s-xl); }

.shelf__title {
  width: var(--shell);
  margin: 0 auto var(--s-md);
  padding-bottom: var(--s-2xs);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-family: var(--serif);
  font-size: var(--t-2);
  font-weight: 400;
  line-height: 1.1;
}
.shelf__count {
  font-family: var(--sans);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.grid {
  width: var(--shell);
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-lg) var(--s-md);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

/* Stacking, measured the hard way: the media is its own stacking context
   (isolation keeps the scaled plate clipped to the radius), so the link's
   stretched layer at z-index 1 used to paint over ALL of it — the heart
   and the quick-add sizes included — and every press on them opened the
   product instead. The media now sits above that layer but lets clicks
   through; only its real controls take them back (pointer-events: auto
   on .heart, and on .quick while it is shown). A press on the photograph
   still falls through to the link. */
.card__media {
  order: -1;             /* the photograph first for the eye; the name first in the DOM */
  position: relative;
  z-index: 2;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--well);
  isolation: isolate;
  pointer-events: none;
}

.card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1s var(--ease), opacity 0.6s var(--ease);
}
.card__img--alt { opacity: 0; }

.card__info { display: grid; gap: 0.3rem; }

.card__name {
  font-family: var(--sans);
  font-size: var(--t--1);
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}

.card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--r-sm);
}
.card__link:focus-visible { outline: none; }
.card__link:focus-visible::after { outline: 2px solid var(--sea); outline-offset: 4px; }

.card__price {
  font-size: var(--t-0);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* The design's offer ("3 for ₪480"): a quiet line in the sea accent, the
   colour the bag's own notes use. */
.card__offer,
.pdp__offer {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--sea);
}
.pdp__offer { margin-top: -0.35rem; }

.card__colour {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.15rem;
  font-size: var(--t--1);
  color: var(--ink-3);
}

/* --- Save ----------------------------------------------------------- */
/* A 44px target with a smaller drawn disc inside it: the target is for
   the finger, the disc is for the eye, and on a 170px phone card a full
   44px disc sat on the photograph like a sticker. */
.heart {
  position: absolute;
  top: 0.35rem;
  inset-inline-end: 0.35rem;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  color: var(--ink);
  pointer-events: auto;
  transition: transform 0.25s var(--spring);
}
.heart::before {
  content: '';
  position: absolute;
  inset: 0.3rem;
  z-index: -1;
  border-radius: 50%;
  background: rgb(245 240 232 / 0.86);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  box-shadow: var(--shadow-1);
  transition: background-color 0.25s linear;
}
.heart:active { transform: scale(0.9); }
.heart__icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: transparent;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linejoin: round;
  transition: fill 0.25s linear, stroke 0.25s linear;
}
.heart[aria-pressed="true"] .heart__icon { fill: var(--signal); stroke: var(--signal); }
@media (hover: hover) { .heart:hover::before { background-color: var(--paper); } }

/* The PDP heart carries its word as well as its shape. */
.heart--label {
  position: static;
  display: inline-flex;
  gap: 0.45rem;
  width: auto;
  height: auto;
  min-height: 2.75rem;
  padding: 0.5rem 1rem 0.5rem 0.8rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  transition: transform 0.25s var(--spring), background-color 0.25s linear, border-color 0.25s linear;
}
.heart--label::before { content: none; }
.heart__text { display: grid; }
.heart__off, .heart__on { grid-area: 1 / 1; transition: opacity 0.2s linear; }
.heart__on { opacity: 0; }
.heart[aria-pressed="true"] .heart__off { opacity: 0; }
.heart[aria-pressed="true"] .heart__on { opacity: 1; }
@media (hover: hover) { .heart--label:hover { background-color: var(--sand); border-color: var(--ink); } }

/* --- Quick add ------------------------------------------------------
   Pointer devices only: it rises on hover, and on focus for keyboards.
   Touch has no hover to reveal it with, and a panel parked permanently
   over the photograph would hide the thing being sold — a tap on the
   card goes to the piece instead. */
.quick {
  position: absolute;
  left: 0.6rem;
  right: 0.6rem;
  bottom: 0.6rem;
  z-index: 2;
  display: grid;
  gap: 0.55rem;
  padding: 0.7rem;
  border-radius: var(--r-sm);
  background: rgb(245 240 232 / 0.94);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow-1);
  opacity: 0;
  transform: translate3d(0, 0.75rem, 0);
  pointer-events: none;
  transition: opacity 0.3s var(--ease), transform 0.45s var(--ease);
}
.quick:focus-within,
.quick.is-added { opacity: 1; transform: translate3d(0, 0, 0); pointer-events: auto; }

.quick__label {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  text-align: center;
  color: var(--ink-3);
}
.quick__sizes {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.35rem;
}
.quick__size {
  min-height: 2.5rem;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--paper);
  font-size: var(--t--1);
  letter-spacing: 0.06em;
  color: var(--ink);
  transition: background-color 0.2s linear, color 0.2s linear, border-color 0.2s linear;
}
.quick__size[aria-disabled="true"] {
  background: transparent;
  color: var(--ink-3);
  text-decoration: line-through;
  cursor: not-allowed;
}

.quick__done {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  border-radius: inherit;
  background: var(--paper);
  color: var(--sea);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s linear;
}
.quick__done svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.quick.is-added .quick__done { opacity: 1; }

@media (hover: hover) and (pointer: fine) {
  .card:hover .card__img { transform: scale(1.04); }
  .card:hover .card__img--alt { opacity: 1; }
  .card:hover .quick { opacity: 1; transform: translate3d(0, 0, 0); pointer-events: auto; }
  .quick__size:not([aria-disabled="true"]):hover {
    background: var(--ink);
    border-color: var(--ink);
    color: var(--paper);
  }
}
@media (hover: none), (pointer: coarse) {
  .quick { display: none; }
}

/* --- The run, filling an odd grid --------------------------------- */
.grid__note { display: none; }
@media (max-width: 900px) {
  .grid:has(> .card:last-of-type:nth-of-type(odd)) > .grid__note { display: flex; }
}
.grid__note {
  flex-direction: column;
  justify-content: space-between;
  gap: var(--s-sm);
  padding: clamp(1rem, 0.8rem + 1vw, 1.5rem);
  border-radius: var(--r-sm);
  background: var(--sand);
}
.grid__note svg {
  width: 1.9rem;
  height: 1.9rem;
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.grid__note p {
  font-family: var(--serif);
  font-size: clamp(1.25rem, 1rem + 1.2vw, 1.75rem);
  line-height: 1.15;
}
.grid__note a {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 0.35em;
}


/* =====================================================================
   12  Promise strip                                             (home)
   ===================================================================== */

.promise {
  width: var(--shell);
  margin-inline: auto;
  padding-block: var(--s-lg);
  border-block: 1px solid var(--line);
}
.promise__list {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-md);
}
.promise__item { display: flex; align-items: flex-start; gap: 0.9rem; }
.promise__item svg {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  margin-top: 0.1rem;
  fill: none;
  stroke: var(--sea);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.promise__item strong {
  display: block;
  font-size: var(--t--1);
  font-weight: 500;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.promise__item span {
  display: block;
  margin-top: 0.25rem;
  font-size: var(--t--1);
  line-height: 1.5;
  color: var(--ink-3);
}


/* =====================================================================
   13  Creed                                                     (home)
   ===================================================================== */

.creed {
  display: grid;
  justify-items: center;
  gap: var(--s-md);
  padding: var(--s-2xl) var(--pad);
  text-align: center;
}
.creed__mark {
  width: 2.4rem;
  height: 2.4rem;
  fill: none;
  stroke: var(--ink-3);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.creed__text {
  max-width: 22ch;
  font-family: var(--serif);
  font-size: clamp(2rem, 1.3rem + 3vw, 3.75rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
.creed__text em { color: var(--sea); }


/* =====================================================================
   14  The film                                                  (home)

   The night footage, kept as the one dark surface on a bright site and
   framed like a print on the wall rather than poured edge to edge. The
   run is tall and the pin is sticky, so progress is a layout fact. The
   frame reports how far through it the reader is (the meter), and the
   cue clears as soon as they have started.
   ===================================================================== */

.film { padding-top: var(--s-xl); }

.film__run { position: relative; height: 260vh; }

.film__pin {
  position: sticky;
  top: 0;
  display: flex;
  height: 100svh;
  padding: var(--pad);
}

.film__frame {
  position: relative;
  flex: 1;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--film);
  box-shadow: var(--shadow-2);
  isolation: isolate;
  --film-progress: 0;
}

/* `will-change` is never released here — this layer repaints on every
   frame of the scrub, which is what a moving layer is. `contain: strict`
   fences the repaint inside the box. */
.film__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  contain: strict;
  transform: translateZ(0);
  will-change: transform;
}

.film__cue {
  position: absolute;
  left: 50%;
  bottom: clamp(2.25rem, 4vw, 3.25rem);
  translate: -50% 0;
  color: rgb(245 240 232 / 0.75);
  font-size: var(--t--2);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  opacity: clamp(0, 1 - var(--film-progress) * 10, 1);
  transition: opacity 0.4s linear;
}

.film__meter {
  position: absolute;
  left: clamp(1.25rem, 4vw, 3rem);
  right: clamp(1.25rem, 4vw, 3rem);
  bottom: clamp(1.1rem, 2.5vw, 1.75rem);
  height: 2px;
  border-radius: 2px;
  overflow: hidden;
  background: rgb(245 240 232 / 0.18);
}
.film__meter i {
  display: block;
  height: 100%;
  background: var(--paper);
  transform-origin: var(--start) center;
  transform: scaleX(var(--film-progress));
}


/* =====================================================================
   15  Lookbook                                                  (home)
   ===================================================================== */

.look { padding-block: var(--s-2xl); }

.look__grid {
  width: var(--shell);
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-sm);
}

.look__item {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--well);
  isolation: isolate;
}
.look__item img {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  transition: transform 1.2s var(--ease);
}

/* The lead frame takes two columns and two rows, which is 4:5 again. A wide
   frame takes two columns of one row: 8:5, the height of its neighbours. */
.look__item--lead { grid-column: span 2; grid-row: span 2; }
.look__item--lead img { aspect-ratio: auto; }
.look__item--wide { grid-column: span 2; }
.look__item--wide img { aspect-ratio: 8 / 5; }

.look__item figcaption {
  position: absolute;
  inset-inline-start: 0.75rem;
  bottom: 0.75rem;
  padding: 0.35rem 0.75rem;
  border-radius: var(--r-pill);
  background: rgb(245 240 232 / 0.88);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--ink);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
@media (hover: hover) and (pointer: fine) {
  .look__item:hover img { transform: scale(1.04); }
}


/* =====================================================================
   16  Atelier                                                   (home)
   ===================================================================== */

.atelier {
  width: var(--shell);
  margin-inline: auto;
  padding-bottom: var(--s-2xl);
}

.atelier__panel {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--s-xl);
  padding: clamp(1.5rem, 1rem + 4vw, 5rem);
  border-radius: var(--r-lg);
  background: var(--sand);
}

.atelier__head { display: grid; gap: var(--s-sm); align-content: start; }
.atelier__lede { max-width: 40ch; color: var(--ink-2); }

.spec { border-top: 1px solid var(--line); }
.spec__row,
.facts__row {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  gap: var(--s-md);
  align-items: baseline;
  padding-block: var(--s-xs);
  border-bottom: 1px solid var(--line);
}
.spec__row dt,
.facts__row dt {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}
.spec__row dd,
.facts__row dd { color: var(--ink); }


/* =====================================================================
   17  Product page: layout & gallery

   Which shirt shows is decided by an attribute on <html>, stamped by the
   inline head script before first paint. CSS cannot compare two
   attributes, so every pairing is enumerated — GENERATED from
   products.json by scripts/build-catalog.mjs between the markers below —
   and the correct product is on screen in frame one with no script
   building markup.
   ===================================================================== */

.pdp { display: none; }

/* =====================================================================
   Right to left (the shop is in Hebrew, 7 November 2026)

   Layout mirrors through logical properties (inset-inline, margin-inline,
   padding-inline) and flex/grid order. What cannot be logical is driven by
   two tokens: --dir multiplies every slide and nudge, --start names the edge
   a growing line starts from. Arrows that mean "forward" are flipped.
   Latin wordmark details (.brand__word, .foot__word) stay physical: they
   compensate the letter-spacing of the Latin letters themselves.
   ===================================================================== */

[dir="rtl"] {
  --dir: -1;
  --start: right;
  /* Hebrew has no capitals and does not take wide tracking: the labels
     that are spaced out in Latin are spaced lightly here. */
  --track-wide: 0.06em;
  --track-mid:  0.04em;
}

/* :where() keeps these weaker than the hover nudges, which flip too. */
:where([dir="rtl"]) .btn--text svg,
:where([dir="rtl"]) .tag__go,
:where([dir="rtl"]) .notice__arrow svg { transform: scaleX(-1); }

/* English brand lines (the hero headline, the footer and menu taglines)
   are marked dir="ltr" so their full stop stays at their end; they still
   line up on the right with their Hebrew neighbours. */
[dir="rtl"] :is(.hero__title, .foot__about, .drop__foot)[dir="ltr"] { text-align: right; }

/* Card names mix Hebrew with the prints' English words: capitals would
   make the English shout. */
[dir="rtl"] .card__name { text-transform: none; }

/* pieces:start — generated by build-catalog.mjs */
html[data-piece="houston-tee-black"] .pdp[data-piece="houston-tee-black"],
html[data-piece="houston-tee-white"] .pdp[data-piece="houston-tee-white"],
html[data-piece="everywhere-tee-sky"] .pdp[data-piece="everywhere-tee-sky"],
html[data-piece="adventure-tee-white"] .pdp[data-piece="adventure-tee-white"],
html[data-piece="direction-tee-black"] .pdp[data-piece="direction-tee-black"],
html[data-piece="sail-bike-tee-burgundy"] .pdp[data-piece="sail-bike-tee-burgundy"],
html[data-piece="ensign-tee-black-white-sail"] .pdp[data-piece="ensign-tee-black-white-sail"],
html[data-piece="ensign-tee-black-pink-sail"] .pdp[data-piece="ensign-tee-black-pink-sail"],
html[data-piece="ensign-tee-white-black-sail"] .pdp[data-piece="ensign-tee-white-black-sail"],
html[data-piece="ensign-tee-white-pink-sail"] .pdp[data-piece="ensign-tee-white-pink-sail"],
html[data-piece="ensign-tee-sky"] .pdp[data-piece="ensign-tee-sky"],
html[data-piece="ensign-tee-pink"] .pdp[data-piece="ensign-tee-pink"],
html[data-piece="ensign-tee-burgundy"] .pdp[data-piece="ensign-tee-burgundy"],
html[data-piece="ensign-tee-camel"] .pdp[data-piece="ensign-tee-camel"],
html[data-piece="ensign-tee-red-stripe"] .pdp[data-piece="ensign-tee-red-stripe"],
html[data-piece="sunrise-long-white"] .pdp[data-piece="sunrise-long-white"],
html[data-piece="sunrise-long-sky"] .pdp[data-piece="sunrise-long-sky"],
html[data-piece="mi-amor-long-black"] .pdp[data-piece="mi-amor-long-black"],
html[data-piece="mi-amor-long-pink"] .pdp[data-piece="mi-amor-long-pink"],
html[data-piece="ensign-long-black"] .pdp[data-piece="ensign-long-black"],
html[data-piece="ensign-long-white"] .pdp[data-piece="ensign-long-white"],
html[data-piece="ensign-long-sky"] .pdp[data-piece="ensign-long-sky"],
html[data-piece="ensign-long-pink"] .pdp[data-piece="ensign-long-pink"],
html[data-piece="ensign-long-burgundy"] .pdp[data-piece="ensign-long-burgundy"],
html[data-piece="ensign-long-mocha"] .pdp[data-piece="ensign-long-mocha"],
html[data-piece="ensign-long-red-stripe"] .pdp[data-piece="ensign-long-red-stripe"],
html[data-piece="ensign-long-ecru-stripe"] .pdp[data-piece="ensign-long-ecru-stripe"],
html[data-piece="vela-cap-burgundy"] .pdp[data-piece="vela-cap-burgundy"],
html[data-piece="vela-cap-brown"] .pdp[data-piece="vela-cap-brown"],
html[data-piece="vela-cap-green"] .pdp[data-piece="vela-cap-green"],
html[data-piece="flat-brim-cap-cream"] .pdp[data-piece="flat-brim-cap-cream"] { display: grid; }
/* pieces:end */

/* No JS, no attribute: show the first rather than an empty page. */
html:not([data-piece]) .pdp:first-of-type { display: grid; }

.pdp {
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  column-gap: var(--s-2xl);
  align-items: start;
  width: var(--shell);
  margin-inline: auto;
  padding-block: var(--s-sm) var(--s-2xl);
}

.crumbs {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6em;
  margin-bottom: var(--s-sm);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}
.crumbs a { color: var(--ink-3); transition: color 0.2s linear; }
.crumbs [aria-current] { color: var(--ink); }
@media (hover: hover) { .crumbs a:hover { color: var(--ink); } }

/* Thumbnails down the left, the plate beside them. Sticky, because the
   buy column is the taller of the two: the plates hold while the copy
   scrolls past. A sticky box taller than its viewport cannot stick, so
   the stage is capped to fit. */
.gallery {
  position: sticky;
  top: calc(var(--nav-h) + var(--s-sm));
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: 0.75rem;
  align-items: start;
}

.gallery__stage {
  grid-column: 2;
  grid-row: 1;
  position: relative;
  aspect-ratio: 3 / 4;
  max-height: calc(100svh - var(--nav-h) - 3rem);
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--well);
}
.gallery__plate {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.02);
  transition: opacity 0.5s var(--ease), transform 0.8s var(--ease);
  will-change: opacity, transform;
}
.gallery__plate.is-showing { opacity: 1; transform: scale(1); }

.gallery__thumbs {
  grid-column: 1;
  grid-row: 1;
  display: grid;
  gap: 0.6rem;
}
.thumb {
  position: relative;
  padding: 0;
  overflow: hidden;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-sm);
  background: var(--well);
  opacity: 0.6;
  outline-offset: 2px;
  transition: opacity 0.3s linear, transform 0.35s var(--ease);
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb.is-active { opacity: 1; box-shadow: 0 0 0 1.5px var(--paper), 0 0 0 3px var(--ink); }
@media (hover: hover) {
  .thumb:hover { opacity: 1; transform: translate3d(0, -2px, 0); }
}


/* =====================================================================
   18  Product page: buy column

   No reveal here, ever: name, price, sizes and the add control ARE the
   page, and must never depend on an animation having fired.
   ===================================================================== */

.pdp__detail {
  display: grid;
  gap: var(--s-sm);
  align-content: start;
  padding-top: 0.25rem;
}

.pdp__titlebar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-sm);
}
.pdp__name {
  font-size: clamp(2.4rem, 1.6rem + 2.6vw, 3.75rem);
  line-height: 1;
}

.pdp__price {
  font-size: var(--t-1);
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
}

.pdp__blurb { max-width: 44ch; color: var(--ink-2); }

.pdp__colour {
  display: grid;
  gap: 0.5rem;
  padding-top: var(--s-sm);
  border-top: 1px solid var(--line);
  font-size: var(--t--1);
}
.pdp__colour-now {
  display: flex;
  align-items: center;
  gap: 0.65rem;
}

/* The same design in its other colours: each dot is a link to that
   colourway's own page. A 44px target around a 24px dot, so a row of
   eight still fits a phone. Only the colour on show wears the ring. */
.tones {
  display: flex;
  flex-wrap: wrap;
  margin-left: -0.625rem;
}
.tone {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
}
.tone .swatch {
  width: 1.5rem;
  height: 1.5rem;
  box-shadow: inset 0 0 0 1px rgb(31 28 25 / 0.18);
}
.tone[aria-current="true"] .swatch {
  box-shadow: inset 0 0 0 1px rgb(31 28 25 / 0.18),
              0 0 0 2.5px var(--paper),
              0 0 0 3.5px var(--ink);
}
@media (hover: hover) {
  .tone:not([aria-current]):hover .swatch {
    box-shadow: inset 0 0 0 1px rgb(31 28 25 / 0.18),
                0 0 0 2.5px var(--paper),
                0 0 0 3.5px var(--line-strong);
  }
}
.tone:focus-visible { outline: 2px solid var(--sea); outline-offset: -2px; }
.pdp__colour-label {
  margin-inline-end: 0.35rem;
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}

.picker { display: grid; gap: 0.65rem; width: 100%; }

.picker__top {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-2xs) var(--s-sm);
}
.picker__label {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.picker__guide { font-size: var(--t--1); color: var(--ink-3); }

.picker__row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.5rem;
}

.size {
  min-height: 3rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: var(--t--1);
  letter-spacing: 0.08em;
  color: var(--ink);
  transition: background-color 0.2s linear, border-color 0.2s linear,
              color 0.2s linear, transform 0.25s var(--spring);
}
@media (hover: hover) {
  .size:not([aria-disabled="true"]):not(.is-selected):hover {
    border-color: var(--ink);
    background-color: var(--sand);
  }
}

/* Selected: filled. Visible from across the room, which is the whole
   requirement. */
.size.is-selected {
  border-color: var(--ink);
  background-color: var(--ink);
  color: var(--paper);
}

/* Sold out is information, not chrome: legible text, struck, on a faint
   hatch so it reads as unavailable before it is read at all. */
.size--gone {
  border-color: var(--line);
  background-image: repeating-linear-gradient(135deg, transparent 0 6px, rgb(31 28 25 / 0.06) 6px 7px);
  color: var(--ink-3);
  text-decoration: line-through;
  cursor: not-allowed;
}

.picker.has-error .size:not(.size--gone) { border-color: var(--warn); }

/* The refusal. Multi-axis, 0.3s, purely CSS — JS only adds the class. */
.picker.is-shaking .picker__row { animation: premiumShake 0.3s cubic-bezier(0.36, 0.07, 0.19, 0.97); }

@keyframes premiumShake {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg); }
  15%  { transform: translate3d(-8px, 2px, 0) rotate(-0.7deg); }
  30%  { transform: translate3d(7px, -2px, 0) rotate(0.6deg); }
  45%  { transform: translate3d(-5px, 1px, 0) rotate(-0.45deg); }
  62%  { transform: translate3d(4px, -1px, 0) rotate(0.3deg); }
  82%  { transform: translate3d(-2px, 0, 0) rotate(-0.12deg); }
}

.picker__error {
  min-height: 1.3em;
  font-size: var(--t--1);
  color: var(--warn);
  opacity: 0;
  transform: translateY(-0.25rem);
  transition: opacity 0.3s var(--ease), transform 0.3s var(--ease);
}
.picker.is-shaking .picker__error,
.picker.has-error .picker__error { opacity: 1; transform: translateY(0); }

/* Scarcity, stated plainly above the control. The dot's ring is a
   transform on a pseudo-element — presence, not an alarm. */
.stock {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: var(--t--1);
  color: var(--ink-2);
}
.stock__dot {
  position: relative;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--sea);
}
.stock__dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--sea);
  animation: stockPing 2.8s var(--inout) infinite;
}
@keyframes stockPing {
  0%        { opacity: 0.5; transform: scale(1); }
  70%, 100% { opacity: 0;   transform: scale(2.6); }
}
.stock__count { font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Held invisible until the store has answered, so the placeholder count in
   the markup is never shown. Visibility, not display: the line keeps its
   height and the add control does not jump when the real number lands. */
.stock.is-pending { visibility: hidden; }

/* The model, under the sizes: the client's three lines ("פרטי הדוגמן")
   as one strip of three facts — label over value, hairlines between, the
   values on one line even when a label wraps. Text on paper, no box: it
   must not read as a fourth row of size buttons. */
.model { display: grid; gap: 0.55rem; }
.model__title {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.model__rows {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding-block: 0.7rem;
  border-block: 1px solid var(--line-2);
}
.model__rows div {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.3rem;
  padding-inline: 0.75rem;
}
.model__rows div:first-child { padding-inline-start: 0; }
.model__rows div + div { border-inline-start: 1px solid var(--line-2); }
.model__rows dt { font-size: var(--t--2); line-height: 1.35; color: var(--ink-3); }
.model__rows dd { font-size: var(--t--1); color: var(--ink); font-variant-numeric: tabular-nums; }


/* =====================================================================
   19  The commitment control                               (.acquire)

   The only control on the site that takes money, so the only one
   allowed real weight. A raised dark key after 21st.dev's add-to-cart:
   a top sheen and a bottom recess at rest, sunk on press, settling into
   the sea accent with a check that draws itself once the bag has it.

     the halo     a soft light that follows the pointer (translate only)
     the sheen    one band of light crossing the key on hover
     the press    0.985 and the shadow driven down with the face
     confirmed    sea fill, bag icon out, check drawn, label swapped —
                  both labels share one grid cell, so nothing moves
     refused      shake + a warn ring + a spoken alert

   aria-disabled until a size is picked, never `disabled`: a disabled
   button fires no click, and the refusal needs one to hang on.
   ===================================================================== */

.acquire {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  width: 100%;
  min-height: 3.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1rem 1.5rem;
  border-radius: var(--r-pill);
  background-color: var(--ink);
  color: var(--paper);
  font-size: var(--t--1);
  font-weight: 500;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  box-shadow: 0 1px 1px rgb(0 0 0 / 0.22),
              0 4px 10px -2px rgb(31 28 25 / 0.32),
              0 16px 30px -14px rgb(31 28 25 / 0.55),
              inset 0 1px 1.5px rgb(255 255 255 / 0.16),
              inset 0 -3px 6px rgb(0 0 0 / 0.45);
  transition: transform 0.28s var(--spring),
              background-color 0.35s var(--ease),
              box-shadow 0.3s var(--ease);
}

.acquire::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg, transparent 35%, rgb(255 255 255 / 0.13) 50%, transparent 65%);
  transform: translate3d(-100%, 0, 0);
  transition: transform 0.9s var(--ease);
  pointer-events: none;
}

.acquire__halo {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  width: 14rem;
  height: 14rem;
  margin: -7rem 0 0 -7rem;
  border-radius: 50%;
  background: radial-gradient(circle, rgb(255 255 255 / 0.14) 0%, rgb(255 255 255 / 0) 65%);
  opacity: 0;
  transform: translate3d(var(--hx, 0px), var(--hy, 0px), 0) scale(0.6);
  transition: opacity 0.35s var(--ease), transform 0.5s var(--ease);
  pointer-events: none;
  will-change: transform, opacity;
}

@media (hover: hover) and (pointer: fine) {
  .acquire:hover { background-color: #2b2722; }
  .acquire:hover::before { transform: translate3d(100%, 0, 0); }
  .acquire:hover .acquire__halo {
    opacity: 1;
    transform: translate3d(var(--hx, 0px), var(--hy, 0px), 0) scale(1);
  }
}

.acquire:active {
  transform: translate3d(0, 1px, 0) scale(0.985);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.22),
              inset 0 2px 6px rgb(0 0 0 / 0.55),
              inset 0 -1px 1px rgb(255 255 255 / 0.06);
}

/* Icons share one slot, labels share one cell: no state change can move
   a pixel of the page. */
.acquire__icon {
  position: relative;
  display: grid;
  width: 1.2rem;
  height: 1.2rem;
  flex: none;
}
.acquire__icon svg {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 0.25s linear, transform 0.35s var(--spring);
}
.acquire__check { opacity: 0; stroke-width: 2.2; }
.acquire__check path { stroke-dasharray: 24; stroke-dashoffset: 24; }

.acquire__labels { display: grid; }
.acquire__face {
  grid-area: 1 / 1;
  transition: opacity 0.3s var(--ease), transform 0.4s var(--ease);
}
.acquire__face--done { opacity: 0; transform: translate3d(0, 0.6rem, 0); }

.acquire.is-added { background-color: var(--sea); }
.acquire.is-added .acquire__bag { opacity: 0; transform: scale(0.6); }
.acquire.is-added .acquire__check { opacity: 1; }
.acquire.is-added .acquire__check path { animation: drawCheck 0.5s var(--ease) 0.08s forwards; }
.acquire.is-added .acquire__face--rest { opacity: 0; transform: translate3d(0, -0.6rem, 0); }
.acquire.is-added .acquire__face--done { opacity: 1; transform: translate3d(0, 0, 0); }
@keyframes drawCheck { to { stroke-dashoffset: 0; } }

.acquire.is-denied {
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--warn);
  animation: premiumShake 0.3s cubic-bezier(0.36, 0.07, 0.19, 0.97);
}


/* =====================================================================
   20  Product page: folds, cross-sell, buy bar
   ===================================================================== */

.assure { display: grid; gap: 0.55rem; }
.assure li {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  font-size: var(--t--1);
  color: var(--ink-2);
}
.assure svg {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  fill: none;
  stroke: var(--sea);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.folds { border-top: 1px solid var(--line); }
.fold { border-bottom: 1px solid var(--line); }
.fold summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 3.25rem;
  list-style: none;
  cursor: pointer;
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.fold summary::-webkit-details-marker { display: none; }
.fold summary::after {
  content: '';
  width: 0.55rem;
  height: 0.55rem;
  margin-inline-end: 0.3rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-25%) rotate(45deg);
  transition: transform 0.35s var(--ease);
}
.fold[open] summary::after { transform: translateY(25%) rotate(-135deg); }
.fold > :not(summary) { padding-bottom: var(--s-sm); }
.fold p { font-size: var(--t--1); line-height: 1.65; color: var(--ink-2); }
.fold a { color: var(--ink); text-decoration: underline; text-underline-offset: 0.25em; }

/* The client's paragraphs above the rows (the shirts), and their washing
   list: a short rule for a bullet, in the fold's own size and colour. */
.fold__text { display: grid; gap: 0.55rem; }
.care__steps { display: grid; gap: 0.4rem; }
.care__steps li {
  position: relative;
  padding-inline-start: 1.1rem;
  font-size: var(--t--1);
  line-height: 1.6;
  color: var(--ink-2);
}
.care__steps li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0.1rem;
  top: 0.8em;
  width: 0.45rem;
  height: 1px;
  background: currentColor;
}

.facts .facts__row { grid-template-columns: 6.5rem minmax(0, 1fr); padding-block: 0.6rem; border-bottom-color: var(--line-2); }
.facts .facts__row:last-child { border-bottom: 0; }
.facts dd { font-size: var(--t--1); }

.also { margin-top: var(--s-md); }
.also__title {
  margin-bottom: var(--s-sm);
  font-family: var(--sans);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}
.also__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-sm);
}
.also__card { display: grid; gap: 0.4rem; }
.also__media {
  display: block;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: var(--well);
}
.also__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.8s var(--ease);
}
.also__name {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
}
.also__price { font-size: var(--t--1); color: var(--ink-2); }
@media (hover: hover) and (pointer: fine) {
  .also__card:hover img { transform: scale(1.04); }
}

/* The buy bar exists for single-column layouts only; above that the
   buy column is always beside the plates. */
.buybar { display: none; }


/* =====================================================================
   21  Footer
   ===================================================================== */

.foot {
  background: var(--sand);
  overflow: hidden;
}

.foot__join {
  width: var(--shell);
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: end;
  gap: var(--s-md) var(--s-lg);
  padding-block: var(--s-2xl) var(--s-xl);
  border-bottom: 1px solid var(--line);
}
.foot__title { font-size: var(--t-3); }
.foot__pitch p { max-width: 38ch; margin-top: 0.85rem; color: var(--ink-2); }

.join {
  display: grid;
  gap: 0.4rem;
  width: 100%;
  max-width: 32rem;
  justify-self: end;
}

/* The pill is the field: its edge is the input's only boundary, so it is
   drawn in --line-strong (3.36:1 on sand), and focus turns it sea with a
   soft ring. A refusal outranks focus — the caret is IN the field because
   the refusal sent it there — so both rules are spelled out. */
.join__row {
  display: flex;
  gap: 0.4rem;
  padding: 0.3rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--paper);
  transition: border-color 0.25s linear, box-shadow 0.25s linear;
}
.join:focus-within .join__row {
  border-color: var(--sea);
  box-shadow: 0 0 0 3px rgb(30 77 99 / 0.16);
}
.join__row:has(input[aria-invalid="true"]) { border-color: var(--warn); }
.join:focus-within .join__row:has(input[aria-invalid="true"]) {
  border-color: var(--warn);
  box-shadow: 0 0 0 3px rgb(163 50 44 / 0.14);
}

.join input {
  flex: 1;
  min-width: 0;
  min-height: 2.75rem;
  padding-inline: 1rem;
}
.join input::placeholder { color: var(--ink-3); }
.join input:focus { outline: none; }
.join__go { min-height: 2.75rem; padding-inline: 1.5rem; }

/* Reserved at exactly one rendered line, so a message never shifts the
   footer under the reader's eye. */
.join__note {
  min-height: 1.6em;
  padding-inline-start: 1rem;
  font-size: var(--t--1);
  line-height: 1.6;
  color: var(--ink-2);
}
.join__note[data-state="ok"]    { color: var(--sea); }
.join__note[data-state="error"] { color: var(--warn); }

.foot__top {
  width: var(--shell);
  margin-inline: auto;
  display: grid;
  /* The brand, then three link columns (a fourth, Follow, returns with the
     client's real social handles). */
  grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr));
  gap: var(--s-lg) var(--s-md);
  padding-block: var(--s-xl);
}

.foot__mark {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  min-height: 2.75rem;
  font-family: var(--serif);
  font-size: var(--t-1);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  line-height: 1;
}
.foot__mark svg {
  width: 1.5em;
  height: 1.5em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.foot__about { max-width: 28ch; margin-top: 0.5rem; font-size: var(--t--1); color: var(--ink-3); }

.foot__col { display: grid; gap: 0.85rem; align-content: start; }
.foot__head {
  font-family: var(--sans);
  font-size: var(--t--2);
  font-weight: 500;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}
.foot__col ul { display: grid; gap: 0.55rem; }
.foot__col a {
  position: relative;
  font-size: var(--t--1);
  color: var(--ink-2);
  transition: color 0.2s linear;
}
/* The sweep is a scaleX on a hairline, never a width. */
.foot__col a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.2em;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: var(--start) center;
  transition: transform 0.35s var(--ease);
}
.foot__col a:focus-visible::after { transform: scaleX(1); }
@media (hover: hover) {
  .foot__col a:hover { color: var(--ink); }
  .foot__col a:hover::after { transform: scaleX(1); }
}

.foot__fine {
  width: var(--shell);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-xs) var(--s-md);
  padding-block: var(--s-sm);
  border-top: 1px solid var(--line);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Payment methods are set as wordmarks, not drawn: no request, nobody's
   trademark reproduced. Swap in official SVGs from each brand centre if
   the conventional badges are wanted. */
.pay { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.pay__mark {
  padding: 0.4em 0.75em;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--paper);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
  white-space: nowrap;
}

.foot__cookies {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}
@media (hover: hover) { .foot__cookies:hover { color: var(--ink); } }

/* The wordmark, cropped by the page's own bottom edge — after the giant
   footer wordmark on 21st.dev. Decorative and aria-hidden: a gradient in
   ink that fades into the sand, so it reads as weight, not as text. */
.foot__word {
  margin-bottom: -0.19em;
  padding-left: 0.08em;
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(6rem, 27vw, 26rem);
  line-height: 0.8;
  letter-spacing: 0.08em;
  text-align: center;
  text-transform: uppercase;
  color: transparent;
  background: linear-gradient(to bottom, rgb(31 28 25 / 0.13), rgb(31 28 25 / 0));
  -webkit-background-clip: text;
  background-clip: text;
  user-select: none;
  pointer-events: none;
}


/* =====================================================================
   22  Bag & saved drawer
   ===================================================================== */

.veil {
  position: fixed;
  inset: 0;
  z-index: var(--z-veil);
  background: rgb(31 28 25 / 0.32);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s var(--ease);
  will-change: opacity;
}
.veil.is-open { opacity: 1; pointer-events: auto; }

.cart {
  position: fixed;
  inset-block: 0;
  inset-inline: auto 0;
  z-index: var(--z-cart);
  width: min(28rem, 100vw);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--paper);
  box-shadow: var(--shadow-2);
  /* Slides on transform, never on `right`. */
  transform: translate3d(calc(101% * var(--dir)), 0, 0);
  transition: transform 0.55s var(--ease);
  will-change: transform;
}
.cart.is-open { transform: translate3d(0, 0, 0); }

.cart__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-sm);
  padding: 0.75rem 0.75rem 0.75rem var(--s-md);
  border-bottom: 1px solid var(--line);
}

.cart__tabs { display: flex; gap: 0.3rem; }
.cart__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  min-height: 2.75rem;
  padding: 0.4rem 1rem;
  border-radius: var(--r-pill);
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-2);
  transition: background-color 0.25s linear, color 0.25s linear;
}
.cart__tab.is-active { background: var(--ink); color: var(--paper); }
@media (hover: hover) { .cart__tab:not(.is-active):hover { background: var(--sand); color: var(--ink); } }
.cart__n {
  display: inline-grid;
  place-items: center;
  min-width: 1.35rem;
  height: 1.35rem;
  padding-inline: 0.35rem;
  border-radius: var(--r-pill);
  background: var(--sand);
  color: var(--ink);
  font-size: 0.68rem;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
.cart__tab.is-active .cart__n { background: rgb(245 240 232 / 0.2); color: var(--paper); }

.cart__body {
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;        /* wins scrolling back from the body lock */
  padding-inline: var(--s-md);
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.cart__empty {
  display: grid;
  justify-items: start;
  gap: 0.5rem;
  padding-block: var(--s-xl);
  color: var(--ink-3);
}
.cart__empty-title {
  font-family: var(--serif);
  font-size: var(--t-2);
  line-height: 1.1;
  color: var(--ink);
}
.cart__empty .btn { margin-top: 0.6rem; }

.cart__lines { display: grid; }

.line {
  display: grid;
  grid-template-columns: 5rem minmax(0, 1fr) auto;
  gap: var(--s-sm);
  padding-block: var(--s-sm);
  border-bottom: 1px solid var(--line-2);
}
.line__frame {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: var(--r-xs);
  background: var(--well);
}
.line__frame img { width: 100%; height: 100%; object-fit: cover; }
.line__body { display: grid; gap: 0.25rem; align-content: start; }
.line__name { font-family: var(--serif); font-size: var(--t-1); line-height: 1.15; }
.line__size {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-3);
}
.line__cost { letter-spacing: 0.04em; text-transform: none; font-size: var(--t--1); color: var(--ink-2); }

.line__qty {
  display: inline-flex;
  align-items: center;
  width: max-content;
  margin-top: 0.5rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
}
.line__qty button {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  font-size: var(--t--1);
  color: var(--ink);
  transition: background-color 0.2s linear;
}
@media (hover: hover) { .line__qty button:hover { background-color: var(--sand); } }
.line__n {
  min-width: 1.5rem;
  text-align: center;
  font-size: var(--t--1);
  font-variant-numeric: tabular-nums;
}

.line__end { display: grid; gap: 0.5rem; justify-items: end; align-content: space-between; }
.line__price { font-size: var(--t--1); font-variant-numeric: tabular-nums; white-space: nowrap; }

.line__kill,
.line__view {
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 0.3em;
  transition: color 0.2s linear;
}
.line__kill { color: var(--ink-3); }
.line__view { justify-self: start; margin-top: 0.5rem; color: var(--ink); }
@media (hover: hover) {
  .line__kill:hover { color: var(--ink); }
  .line__view:hover { color: var(--sea); }
}

.cart__foot {
  display: grid;
  gap: 0.65rem;
  padding: var(--s-md);
  border-top: 1px solid var(--line);
}
.cart__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: var(--t--2);
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: var(--ink-2);
}
.cart__row #cart-total {
  font-family: var(--serif);
  font-size: var(--t-2);
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.cart__ship {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.2rem;
  font-size: var(--t--1);
  color: var(--sea);
}
/* The offer in the bag: how close the visitor is, then that it applies. */
.cart__offer {
  margin-bottom: 0.2rem;
  font-size: var(--t--1);
  color: var(--sea);
}

/* Checkout's refusals. Always in the DOM so role="alert" is announced;
   the negative margin cancels the grid gap while it is empty. */
.cart__alert {
  font-size: var(--t--1);
  line-height: 1.45;
  color: var(--warn);
}
.cart__alert:empty { margin-bottom: -0.65rem; }

.btn[aria-busy="true"] { opacity: 0.7; cursor: progress; }

.cart__ship svg {
  width: 1rem;
  height: 1rem;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* =====================================================================
   23  Static pages                    (FAQ, care, contact, legal, 404)
   ===================================================================== */

.page {
  width: min(var(--shell), 44rem);
  margin-inline: auto;
  padding-block: var(--s-md) var(--s-2xl);
  display: grid;
  gap: var(--s-lg);
}

.page__head {
  display: grid;
  gap: 0.75rem;
  padding-bottom: var(--s-md);
  border-bottom: 1px solid var(--line);
}
.page__head .crumbs { margin-bottom: 0.25rem; }
.page__title { font-size: clamp(2.5rem, 1.8rem + 3vw, 4.25rem); }

/* 68ch: past it, the eye loses the start of the next line. */
.prose { max-width: 68ch; display: grid; gap: var(--s-sm); }
.prose h2 {
  margin-top: var(--s-xs);
  font-family: var(--serif);
  font-size: var(--t-2);
  font-weight: 500;
  line-height: 1.15;
}
.prose p,
.prose li { line-height: 1.7; color: var(--ink-2); }
.prose ul,
.prose ol { display: grid; gap: var(--s-2xs); padding-inline-start: 1.25em; list-style: disc; }
.prose li::marker { color: var(--ink-3); }
.prose a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.25em;
  transition: color 0.2s linear;
}
.prose a.btn { text-decoration: none; }
.prose a.btn--solid { color: var(--paper); }
@media (hover: hover) { .prose a:not(.btn):hover { color: var(--sea); } }
.prose strong { font-weight: 500; color: var(--ink); }

/* Copy the site owner still has to write. Visible on purpose: a
   placeholder that looks finished is how placeholder text ships. */
.prose__todo {
  padding: var(--s-sm) var(--s-md);
  border: 1px dashed rgb(122 78 14 / 0.45);
  border-radius: var(--r-md);
  background: #f3e8d2;
  font-size: var(--t--1);
  color: var(--ink-2);
}
.prose__todo b {
  display: block;
  margin-bottom: 0.3rem;
  font-size: var(--t--2);
  font-weight: 500;
  letter-spacing: var(--track-mid);
  text-transform: uppercase;
  color: #7a4e0e;
}

/* Magnetic pull — the transition IS the mechanism (see initMagnetic). */
[data-magnetic] {
  display: inline-flex;
  transition: transform 0.35s var(--spring), background-color 0.3s var(--ease);
  will-change: transform;
}


/* =====================================================================
   24  Cookie consent

   Bottom-anchored card, never a blocker. Accept and Decline are one
   class: if an edit ever makes one louder than the other, that is a
   consent dark pattern, not a design improvement.
   ===================================================================== */

.consent {
  position: fixed;
  left: var(--pad);
  right: var(--pad);
  bottom: calc(var(--pad) + env(safe-area-inset-bottom));
  z-index: var(--z-cart);
  max-width: 46rem;
  margin-inline: auto;
  padding: var(--s-sm) var(--s-md);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--paper);
  box-shadow: var(--shadow-2);
  transform: translate3d(0, calc(100% + 3rem), 0);
  transition: transform 0.5s var(--ease);
  will-change: transform;
}
.consent.is-open { transform: translate3d(0, 0, 0); }
.consent:focus-visible { outline-offset: -3px; }

.consent__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-sm) var(--s-md);
}
.consent__text { max-width: 52ch; }
.consent__title {
  margin-bottom: 0.3rem;
  font-family: var(--sans);
  font-size: var(--t--2);
  font-weight: 500;
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: var(--ink-3);
}
.consent__body { font-size: var(--t--1); line-height: 1.55; color: var(--ink-2); }
.consent__body a { color: var(--ink); text-decoration: underline; text-underline-offset: 0.25em; }

.consent__actions { display: flex; gap: var(--s-2xs); flex: none; }
.consent__btn { min-width: 8.5rem; min-height: 2.75rem; padding-block: 0.6em; }


/* =====================================================================
   25  Interaction feedback

   Everything here reports a state change the visitor caused, on the
   element they caused it with. Transform and opacity only.
   ===================================================================== */

/* A line arriving in the bag tells you where the thing you bought went. */
@keyframes lineIn {
  from { opacity: 0; transform: translate3d(0, 0.75rem, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
.line {
  animation: lineIn 0.45s var(--ease) both;
  animation-delay: calc(var(--line-i, 0) * 60ms);
}

/* The size you took, confirmed with one pop. */
@keyframes sizePop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}
.size.is-selected { animation: sizePop 0.32s var(--spring); }

/* The bag in the masthead lifts as a piece lands; its badge is struck. */
@keyframes bagTake {
  0%   { transform: translate3d(0, 0, 0); }
  40%  { transform: translate3d(0, -0.25rem, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@keyframes badgePulse {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.4); }
  62%  { transform: scale(0.9); }
  100% { transform: scale(1); }
}
.iconbtn.is-pulsing { animation: bagTake 0.5s var(--spring); }
.iconbtn.is-pulsing .badge { animation: badgePulse 0.55s var(--spring); }

/* A heart taken, felt. */
@keyframes heartPop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.3); }
  70%  { transform: scale(0.92); }
  100% { transform: scale(1); }
}
.heart.is-popping .heart__icon { animation: heartPop 0.45s var(--spring); }


/* =====================================================================
   26  Responsive
   ===================================================================== */

@media (max-width: 1024px) {
  /* The split collapses. The gallery stops sticking, because there is
     no second column for it to stick beside, and the buy bar takes over
     keeping the add control in reach. */
  .pdp { grid-template-columns: minmax(0, 1fr); row-gap: var(--s-md); }
  .pdp .crumbs { margin-bottom: calc(var(--s-md) * -0.5); }
  .gallery { position: static; grid-template-columns: minmax(0, 1fr); }
  .gallery__stage { grid-column: 1; aspect-ratio: 4 / 5; max-height: none; }
  /* Tracks may shrink below 4.5rem: the Porto Stripe has five views, and
     five fixed 72px thumbs overran a 358px phone column by 40px. */
  .gallery__thumbs {
    grid-column: 1;
    grid-row: 2;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 4.5rem);
    justify-content: start;
  }

  .buybar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-buybar);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-sm);
    padding: 0.7rem var(--pad) calc(0.7rem + env(safe-area-inset-bottom));
    background: rgb(245 240 232 / 0.95);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border-top: 1px solid var(--line);
    box-shadow: 0 -12px 30px -22px rgb(60 44 28 / 0.55);
    transform: translate3d(0, 110%, 0);
    transition: transform 0.45s var(--ease);
    will-change: transform;
  }
  .buybar.is-shown { transform: translate3d(0, 0, 0); }

  /* Room for the bar at the very end, so it never sits over the footer's
     last line when the visitor has scrolled all the way down. */
  body[data-page="product"] { padding-bottom: calc(4.75rem + env(safe-area-inset-bottom)); }
  .buybar__name {
    font-size: var(--t--2);
    letter-spacing: var(--track-mid);
    text-transform: uppercase;
  }
  .buybar__price { font-size: var(--t--1); color: var(--ink-2); }
  .buybar__go { min-height: 3rem; padding-inline: 1.6rem; }

  .foot__top { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .foot__brand { grid-column: 1 / -1; }
}

@media (max-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-lg);
    padding-top: var(--s-md);
  }
  .hero__media { padding: 0 0 12% 11%; }

  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-md) var(--s-sm); }
  .promise__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-md) var(--s-sm); }

  .atelier__panel { grid-template-columns: minmax(0, 1fr); gap: var(--s-lg); }

  .foot__join { grid-template-columns: minmax(0, 1fr); }
  .join { justify-self: stretch; max-width: none; }
}

@media (max-width: 767.98px) {
  :root { --nav-h: 6.25rem; }

  .notice { grid-template-columns: 2.75rem minmax(0, 1fr) 2.75rem; min-height: 2.75rem; }
  .notice__arrow { height: 2.75rem; }
  .notice { letter-spacing: 0.16em; }

  .nav__bar { min-height: 3.5rem; gap: 0.25rem; }
  .brand__word { font-size: 1.55rem; }
  .brand__mark { width: 1.1rem; height: 1.1rem; }

  /* Labels leave the screen but not the accessibility tree: the button's
     name is still "Bag, 2 items", not just "2 items". */
  .iconbtn__label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .iconbtn { padding-inline: 0.55rem; }
  .badge { inset-inline-start: 1.4rem; }

  .cats__link { letter-spacing: 0.18em; }
  .cats__list { gap: 1.1rem; }

  .hero__facts { gap: var(--s-md); }
  .tag { inset-inline-end: 0.75rem; bottom: 0.75rem; padding-inline-start: 0.9rem; }
  /* Too narrow for words on the inset; the tag stays the link's name. */
  .tag--small {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .card { gap: 0.7rem; }
  .card__name { font-size: var(--t--2); }
  .card__price { font-size: var(--t--1); }
  .card__colour { font-size: var(--t--2); gap: 0.5rem; }
  .card__colour .swatch { width: 0.8rem; height: 0.8rem; }
  .heart { top: 0.15rem; inset-inline-end: 0.15rem; }

  .film__run { height: 220vh; }

  .look__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2xs); }
  .look__item--lead { grid-row: auto; }
  .look__item--lead img { aspect-ratio: 4 / 5; }
  .look__item figcaption { inset-inline-start: 0.5rem; bottom: 0.5rem; padding: 0.3rem 0.6rem; font-size: 0.625rem; }

  .spec__row, .facts__row { grid-template-columns: 6.5rem minmax(0, 1fr); }

  .cart { width: 100vw; }
  .line__qty button { width: 44px; height: 44px; }
  .line__kill,
  .line__view { display: inline-flex; align-items: center; min-height: 44px; }

  .foot__top { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-md); }
  .foot__col ul { gap: 0; }
  .foot__col a { display: inline-flex; align-items: center; min-height: 44px; min-width: 44px; }
  .foot__fine { flex-direction: column; align-items: flex-start; }
  .pay__mark { display: inline-flex; align-items: center; min-height: 44px; }
  .foot__cookies { min-height: 44px; }

  .crumbs a,
  .crumbs [aria-current] { display: inline-flex; align-items: center; min-height: 44px; }
  .crumbs a { min-width: 44px; }

  .consent__inner { flex-direction: column; align-items: stretch; }
  .consent__actions { width: 100%; }
  .consent__btn { flex: 1; min-width: 0; }
}

@media (max-width: 560px) {
  .promise__list { grid-template-columns: minmax(0, 1fr); gap: var(--s-sm); }
  .promise__item strong { letter-spacing: 0.1em; }
}

@media (max-width: 420px) {
  .hero__facts { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-xs); }
  .hero__facts dt { letter-spacing: 0.08em; }
  .picker__row { gap: 0.4rem; }
}


/* =====================================================================
   27  Reduced motion, print, forced colours

   Reduced motion is structural, not "shorter durations": anything that
   animates in is shown outright, every loop is stopped at its start
   frame, and the film becomes a single still with no scrub.
   ===================================================================== */

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

  .hero__eyebrow,
  .hero__lede,
  .hero__actions,
  .hero__facts,
  .hero__media,
  .hero__title .mask > span { animation: none !important; opacity: 1; transform: none; }

  .js [data-reveal] { opacity: 1; transform: none; }

  .stock__dot::after,
  .picker.is-shaking .picker__row,
  .acquire.is-denied,
  .size.is-selected,
  .line,
  .iconbtn.is-pulsing,
  .iconbtn.is-pulsing .badge,
  .heart.is-popping .heart__icon { animation: none !important; }
  .line { opacity: 1; transform: none; }
  .picker__error { opacity: 1; transform: none; }

  /* The tick must still READ as drawn, just not draw. */
  .acquire.is-added .acquire__check path { animation: none !important; stroke-dashoffset: 0; }

  /* The film: one still frame, no pinned scrub. */
  .film__run { height: auto; }
  .film__pin { position: relative; height: 72svh; }
  .film__cue,
  .film__meter,
  .film__hint { display: none; }
}

@media print {
  .notice, .nav, .drop, .veil, .cart, .film, .buybar, .consent, .quick, .heart { display: none !important; }
  body { background: #fff; color: #000; }
  .pdp { grid-template-columns: minmax(0, 1fr); }
  .foot__word { display: none; }
}

@media (forced-colors: active) {
  .badge, .cart__n { border: 1px solid CanvasText; }
  .size, .btn, .iconbtn, .heart, .quick__size, .join__row { border: 1px solid CanvasText; }
  .cats__link.is-current { text-decoration: underline; }
  .card__img--alt, .foot__word { display: none; }
  .quick { opacity: 1; transform: none; }
}
