/* =========================================================================
   FOZMU — house stylesheet
   Direction: the couture tech pack. Gallery white, flat garment drawings,
   woven care labels, bottle green used exactly three times.
   ========================================================================= */

:root {
  --paper: #ffffff;
  --bone: #efede6;
  --bone-deep: #e3e0d6;
  --ink: #0c0d0c;
  --smoke: #6d6c64;
  --bottle: #0e4a2e;
  --bottle-deep: #08321f;

  --display: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --body: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  /* Montserrat Light for prose, Medium for headings, both tracked open. */
  --track-body: 0.02em;
  --track-display: 0.08em;

  /* The wordmark's sweep: ink to silver on paper, paper to silver on ink. */
  --wm-a: var(--ink);
  --wm-b: #9a9c98;
  --mono: "Spline Sans Mono", ui-monospace, "SFMono-Regular", monospace;

  --gutter: clamp(1.25rem, 4vw, 4.5rem);
  --measure: 34ch;
  --bar: 62px;

  --ease: cubic-bezier(0.16, 0.84, 0.32, 1);
  --slow: 900ms;
}

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

html { -webkit-text-size-adjust: 100%; }
@media (min-width: 861px) and (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.0625rem);
  font-weight: 300;
  letter-spacing: var(--track-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

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

/* ---------- type roles ---------------------------------------------------- */

.display {
  font-family: var(--display);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: var(--track-display);
  line-height: 0.96;
  margin: 0;
}

.eyebrow,
.mono {
  font-family: var(--mono);
  font-weight: 400;
  font-size: 0.6875rem;
  letter-spacing: 0.19em;
  text-transform: uppercase;
}

.eyebrow { color: var(--smoke); display: block; }

.lede {
  font-size: clamp(1.05rem, 0.98rem + 0.45vw, 1.375rem);
  line-height: 1.45;
  max-width: var(--measure);
  font-weight: 300;
}

/* ---------- the care label: the house signature --------------------------- */

.label {
  --label-bg: var(--bone);
  position: relative;
  display: inline-block;
  padding: 0.9rem 1.2rem 0.85rem;
  background: var(--label-bg);
  font-family: var(--mono);
  font-size: 0.625rem;
  line-height: 1.8;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink);
}
/* stitched edge — two rows of thread, not a border */
.label::before,
.label::after {
  content: "";
  position: absolute;
  left: 0.4rem;
  right: 0.4rem;
  height: 1px;
  background: repeating-linear-gradient(
    to right, var(--smoke) 0 4px, transparent 4px 8px
  );
  opacity: 0.6;
}
.label::before { top: 0.35rem; }
.label::after { bottom: 0.35rem; }

.label dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 0 1.2rem; }
.label dt { color: var(--smoke); }
.label dd { margin: 0; }

/* ---------- shell --------------------------------------------------------- */

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--paper); padding: 0.75rem 1rem;
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.15em;
}
.skip:focus { left: 0; }

.masthead {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  height: var(--bar);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 var(--gutter);
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: blur(14px);
  transition: box-shadow 400ms var(--ease), background 400ms var(--ease);
}
.masthead[data-scrolled="true"] {
  /* Fully opaque once scrolled: translucency over a pinned product image reads
     as a smear rather than as frosted glass. */
  background: var(--paper);
  box-shadow: 0 1px 0 var(--bone-deep);
}

.masthead nav { display: flex; gap: 1.75rem; }
.masthead .utilities { display: flex; gap: 1.5rem; justify-content: flex-end; }

.masthead a {
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  padding-block: 0.4rem;
  position: relative;
}
.masthead a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0.1rem;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 400ms var(--ease);
}
.masthead a:hover::after,
.masthead a[aria-current="page"]::after { transform: scaleX(1); }

/* The wordmark: the F drawn as the mark, the rest of the name set beside it
   in Montserrat, with a light sweeping through the letters left to right. */
.wordmark {
  display: inline-flex; align-items: center; gap: 0.3em;
  font-family: var(--display);
  font-size: 1rem;
  white-space: nowrap;
  line-height: 1;
}
.wordmark .mark { height: 1.2em; width: auto; flex: none; display: block; margin-top: -0.06em; }
.wordmark__text {
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--wm-a);
  background: linear-gradient(100deg,
    var(--wm-a) 0%, var(--wm-a) 30%, var(--wm-b) 50%, var(--wm-a) 70%, var(--wm-a) 100%);
  background-size: 260% 100%;
  background-position: 120% 0;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: wordmark-sweep 7s var(--ease) infinite;
}
.wordmark__line { font-weight: 300; }
@keyframes wordmark-sweep {
  0%, 55% { background-position: 120% 0; }
  100% { background-position: -20% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .wordmark__text { animation: none; background-position: 50% 0; }
}
.masthead .wordmark {
  font-family: var(--display); font-size: 1rem; letter-spacing: 0;
  text-transform: none; padding-block: 0;
}
.masthead .wordmark::after { display: none; }

.cart-count { font-variant-numeric: tabular-nums; }

main { padding-top: var(--bar); }

@media (max-width: 760px) {
  .masthead { padding-inline: 1rem; }
  .masthead nav { gap: 0.85rem; }
  .masthead .utilities { gap: 0.85rem; }
  .masthead a { font-size: 0.5625rem; letter-spacing: 0.12em; }
  .wordmark { font-size: 0.75rem; }
  .wordmark__text { letter-spacing: 0.26em; }
}
@media (max-width: 620px) {
  /* Keep the mark centred and give it room: the rest of the nav lives in the footer. */
  .masthead .utilities a[href="/care/"],
  .masthead nav a[href="/collection-01/"],
  .masthead nav a[href="/house/"] { display: none; }
  /* The mark and the name alone; "Garments" comes back with the room for it. */
  .masthead .wordmark__line, .menu .wordmark__line { display: none; }
}

/* ---------- hero: the tech pack sheet ------------------------------------- */

.techpack {
  position: relative;
  min-height: calc(100svh - var(--bar));
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  align-items: center;
  gap: var(--gutter);
  padding: clamp(2rem, 5vw, 4rem) var(--gutter) clamp(2.5rem, 6vw, 5rem);
}

.techpack__copy { max-width: 46ch; }
.techpack .display { font-size: clamp(2.35rem, 6.1vw, 5.25rem); }
.techpack .display em {
  font-style: normal;
  font-weight: 300;
  letter-spacing: 0.14em;
  display: block;
}

.techpack__lede { margin: 1.75rem 0 2.25rem; }

.techpack__sheet { position: relative; align-self: stretch; display: grid; place-items: center; }
.techpack__sheet::before {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(var(--bone-deep) 1px, transparent 1px) 0 0 / 100% 3.5rem,
    linear-gradient(90deg, var(--bone-deep) 1px, transparent 1px) 0 0 / 3.5rem 100%;
  opacity: 0.5;
  -webkit-mask-image: radial-gradient(ellipse 78% 70% at 50% 50%, #000 35%, transparent 78%);
  mask-image: radial-gradient(ellipse 78% 70% at 50% 50%, #000 35%, transparent 78%);
}
.techpack__sheet svg { position: relative; width: min(92%, 28rem); height: auto; }

/* The photographed piece, sat on the sheet where the drawing used to be. A
   hairline keeps a white-ground photograph from dissolving into the paper. */
.techpack__shot {
  position: relative;
  display: block;
  width: min(92%, 30rem);
  border: 1px solid var(--bone-deep);
  background: var(--paper);
}
.techpack__shot img { width: 100%; height: auto; }

/* The hero's one moment: the piece is uncovered top to bottom, then the
   annotations land on it — the same beat the drawing used to keep. */
.techpack__shot { animation: unveil 1100ms var(--ease) both; }
@keyframes unveil {
  from { clip-path: inset(0 0 100% 0); opacity: 0; }
  to { clip-path: inset(0 0 0 0); opacity: 1; }
}

/* annotation callouts, positioned against the drawing */
.annotation {
  position: absolute;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--smoke);
  white-space: nowrap;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--bone-deep);
}
.annotation b { color: var(--ink); font-weight: 400; }

/* Over a photograph the callouts become pinned labels: paper behind them, a
   hairline round them. A line of mono type laid straight over a model is not
   readable, and the tech pack is the point — so the annotation keeps its job
   and gains a ticket to sit on. */
.techpack__sheet--shot .annotation {
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  padding: 0.4rem 0.65rem;
  max-width: 15rem;
  white-space: normal;
}
.techpack__sheet--shot .annotation--a { top: 8%; left: 0; }
.techpack__sheet--shot .annotation--b { top: 46%; right: 0; }
.techpack__sheet--shot .annotation--c { bottom: 10%; left: 0; }
.annotation--a { top: 15%; left: 0; }
.annotation--b { top: 54%; right: 0; text-align: right; }
.annotation--c { bottom: 19%; left: 0; }

@media (max-width: 900px) {
  .techpack { grid-template-columns: 1fr; align-content: center; }
  .techpack__sheet { order: -1; min-height: 20rem; }
  .annotation--a { top: 2%; }
  .annotation--c { bottom: 2%; }
}
@media (max-width: 560px) {
  .annotation { display: none; }
}

/* ---------- sections ------------------------------------------------------ */

.section { padding: clamp(3rem, 10vw, 9rem) var(--gutter); }
.section--bone { background: var(--bone); }
.section--bottle { background: var(--bottle); color: var(--paper); }
.section--bottle .eyebrow,
.section--bottle .mono { color: color-mix(in srgb, var(--paper) 62%, transparent); }
.section--bottle .btn { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.section--bottle .btn:hover { background: transparent; color: var(--paper); }

.section__head {
  display: flex; flex-wrap: wrap; gap: 1rem 2rem;
  align-items: baseline; justify-content: space-between;
  margin-bottom: clamp(2rem, 5vw, 4rem);
}
.section__head h2 { font-size: clamp(1.75rem, 4vw, 3.25rem); }

/* the green band: one statement, set large, nothing else */
.statement {
  font-family: var(--display);
  font-weight: 300;
  text-transform: none;
  font-size: clamp(1.6rem, 4.4vw, 3.75rem);
  line-height: 1.12;
  letter-spacing: 0.03em;
  max-width: 22ch;
  margin: 1.5rem 0 0;
}

.band {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(2rem, 6vw, 6rem);
  align-items: end;
}
@media (max-width: 860px) { .band { grid-template-columns: 1fr; } }

/* ---------- product grid -------------------------------------------------- */

.rail {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 24rem), 1fr));
  gap: clamp(1.75rem, 4vw, 3.5rem) clamp(1.5rem, 3vw, 3rem);
}
.rail--tight {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
}

.card { display: block; position: relative; }

.plate {
  position: relative;
  background: var(--bone);
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  overflow: hidden;
  transition: background 600ms var(--ease);
}
.section--bone .plate { background: var(--paper); }
.plate svg { width: 80%; height: auto; transition: transform 900ms var(--ease); }
.plate img { width: 100%; height: 100%; object-fit: contain; transition: transform 900ms var(--ease); }

.card:hover .plate { background: var(--bone-deep); }
.section--bone .card:hover .plate { background: var(--bone); }
.card:hover .plate svg,
.card:hover .plate img { transform: scale(1.035); }

.plate__index {
  position: absolute; top: 0.9rem; left: 1rem;
  font-family: var(--mono); font-size: 0.625rem;
  letter-spacing: 0.18em; color: var(--smoke);
  font-variant-numeric: tabular-nums;
}
.plate__sizes {
  position: absolute; inset: auto 0 0 0;
  display: flex; gap: 0.9rem; justify-content: center;
  padding: 0.9rem;
  font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.16em;
  color: var(--smoke);
  opacity: 0; transform: translateY(0.4rem);
  transition: opacity 400ms var(--ease), transform 400ms var(--ease);
}
.card:hover .plate__sizes,
.card:focus-within .plate__sizes { opacity: 1; transform: none; }

.card__line {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; margin-top: 1.1rem;
}
@media (max-width: 560px) {
  .card__line { flex-direction: column; gap: 0.3rem; }
}
.card__name { font-size: 1.0625rem; font-weight: 400; letter-spacing: -0.005em; }
.card__price { font-family: var(--mono); font-size: 0.8125rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---------- promotional pricing ------------------------------------------- */

/* The regular price, struck. Kept quiet — the price that is charged is the one
   that should read first. */
.price-was {
  color: var(--smoke);
  text-decoration-thickness: 1px;
  text-underline-offset: 0;
  margin-right: 0.5ch;
  font-variant-numeric: tabular-nums;
}

.price-flag {
  color: var(--bottle);
  margin-top: 0.5rem;
}

.cart-total--saving { margin: -0.75rem 0 1.5rem; color: var(--bottle); }
.card__meta { margin-top: 0.25rem; color: var(--smoke); font-size: 0.8125rem; }

/* ---------- product page -------------------------------------------------- */

.product {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  padding: clamp(2rem, 5vw, 4.5rem) var(--gutter) clamp(4rem, 8vw, 7rem);
  align-items: start;
}
@media (max-width: 860px) {
  /* Block layout, not grid: a sticky grid item can only travel inside its own
     row, which on one column is no travel at all. As a block it sticks for the
     whole article, so the garment stays on screen while you pick colour and size. */
  .product { display: block; padding-top: 1rem; }
  .product .eyebrow { margin-top: 0; }

  /* Not pinned. A picture that follows you down the page reads as broken, so
     the image scrolls away like everything else — it is simply small enough
     that the colour and size controls sit next to it on the first screen. */
  .product__media { margin-bottom: 1.25rem; }
  .product__plate {
    max-width: none;
    aspect-ratio: auto;
    /* Fixed units, never vh: mobile browsers resize the viewport as the URL bar
       hides and shows, and the page jitters as the block is recalculated. */
    height: 13rem;
  }
  .thumbs { max-width: none; margin-top: 0.4rem; }
  .thumbs .thumb { width: 2.75rem; }
}
@media (max-width: 560px) {
  .sizes { gap: 0.4rem; }
  .size, .swatch { padding-inline: 0.75rem; }
  .colophon__grid { gap: 2rem; }
}

.product__media { position: sticky; top: calc(var(--bar) + 1.5rem); }
.product__plate {
  background: var(--bone);
  aspect-ratio: 4 / 5;
  max-width: 30rem;
  display: grid; place-items: center;
  overflow: hidden;
}
.product__plate svg { width: 74%; height: auto; }
.product__plate img { width: 100%; height: 100%; object-fit: contain; }

/* extra angles, when a colourway has more than one mockup */
.thumbs {
  display: flex; gap: 0.5rem; margin-top: 0.5rem;
  max-width: 30rem; padding: 0; list-style: none;
  overflow-x: auto; scrollbar-width: thin;
}
.thumb { flex: 0 0 auto; }
.thumb {
  width: 4.5rem; aspect-ratio: 4 / 5;
  padding: 0; border: 1px solid transparent; background: var(--bone);
  cursor: pointer; overflow: hidden;
  transition: border-color 300ms var(--ease);
}
.thumb img { width: 100%; height: 100%; object-fit: contain; }
.thumb[aria-pressed="true"] { border-color: var(--ink); }
.thumb:hover { border-color: var(--smoke); }

.product__title {
  font-size: clamp(1.55rem, 4.5vw, 3.25rem);
  margin-bottom: 0.85rem;
  hyphens: manual;
  overflow-wrap: break-word;
}
.product__price { font-family: var(--mono); font-size: 1rem; letter-spacing: 0.06em; }

.sizes { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0 1.5rem; padding: 0; list-style: none; }
.size {
  font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.12em;
  padding: 0.65rem 1rem;
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  color: var(--ink);
  cursor: pointer;
  transition: background 300ms var(--ease), border-color 300ms var(--ease), color 300ms var(--ease);
}
.size:hover { border-color: var(--smoke); }
.size[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

/* colour picker — the swatch carries the colour, the label names it */
.swatch-row { gap: 0.5rem; }
.swatch {
  display: inline-flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.9rem 0.5rem 0.55rem;
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  color: var(--ink);
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.12em; text-transform: uppercase;
  cursor: pointer;
  transition: border-color 300ms var(--ease);
}
.swatch i {
  width: 1.1rem; height: 1.1rem; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(12, 13, 12, 0.18);
}
.swatch:hover { border-color: var(--smoke); }
.swatch[aria-pressed="true"] { border-color: var(--ink); }

/* the swatch strip on a product card */
.swatches { display: inline-flex; gap: 0.25rem; vertical-align: -0.1em; margin-right: 0.4rem; }
.swatches i {
  width: 0.6rem; height: 0.6rem; border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(12, 13, 12, 0.18);
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.75rem;
  width: 100%;
  padding: 1.15rem 1.5rem;
  background: var(--ink); color: var(--paper);
  border: 1px solid var(--ink);
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.22em; text-transform: uppercase;
  cursor: pointer;
  transition: background 400ms var(--ease), color 400ms var(--ease), border-color 400ms var(--ease);
}
.btn:hover { background: var(--bottle); border-color: var(--bottle); }
.btn:disabled { background: var(--bone-deep); border-color: var(--bone-deep); color: var(--smoke); cursor: not-allowed; }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); width: auto; }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }

.spec { margin: 2.5rem 0 0; }
.spec dl { display: grid; grid-template-columns: 8.5rem 1fr; gap: 0.9rem 1.5rem; margin: 0; }
.spec dt {
  font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--smoke); padding-top: 0.2rem;
}
.spec dd { margin: 0; }
@media (max-width: 480px) { .spec dl { grid-template-columns: 1fr; gap: 0.2rem 0; } .spec dd { margin-bottom: 0.9rem; } }

/* ---------- cart ---------------------------------------------------------- */

.cart-line {
  display: grid;
  grid-template-columns: 5.5rem 1fr auto auto;
  gap: 1.25rem; align-items: center;
  padding: 1.5rem 0;
  border-bottom: 1px solid var(--bone-deep);
}
.cart-line .plate { aspect-ratio: 1; }
.cart-line .plate svg, .cart-line .plate img { width: 78%; }
.cart-line__remove { font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--smoke); background: none; border: 0; cursor: pointer; }
.cart-line__remove:hover { color: var(--ink); }
.qty { display: flex; align-items: center; gap: 0.75rem; font-family: var(--mono); font-size: 0.8125rem; }
.qty button {
  width: 1.9rem; height: 1.9rem; border: 1px solid var(--bone-deep);
  background: transparent; color: var(--ink); cursor: pointer; font-family: var(--mono); line-height: 1;
}
.qty button:hover { border-color: var(--ink); }
.cart-total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin: 2rem 0 1.5rem; font-family: var(--mono); font-size: 0.875rem; letter-spacing: 0.08em;
}
.cart-empty { padding: 4rem 0; color: var(--smoke); }
.cart-note { color: var(--smoke); font-size: 0.8125rem; margin-top: 1rem; }

/* ---------- the eco mark -------------------------------------------------- */

/* A drawn leaf in bottle green, set like a utility label. Green appears here
   because the mark means something — it is the one place on a card that is not
   ink on paper. */
.eco {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: var(--bottle);
  vertical-align: baseline;
}

.eco__leaf {
  width: 1.05em;
  height: 1.05em;
  flex: none;
  /* Sits on the text baseline rather than riding above it. */
  transform: translateY(0.1em);
}

.eco__word {
  font-size: 0.625rem;
  letter-spacing: 0.19em;
}
.eco__word:empty { display: none; }

/* On a product page the mark is its own line under the piece number. */
.product__head .eco { margin-top: 0.85rem; }

/* On imagery the leaf stands alone, in the corner opposite the piece number.
   No plate, no circle — the same hairline drawing the garment is shown in. */
.eco--badge {
  position: absolute;
  top: 0.75rem;
  right: 0.9rem;
  z-index: 1;
}
.eco--badge .eco__leaf {
  width: 1.35rem;
  height: 1.35rem;
  transform: none;
}

/* The gallery gets its own frame so the badge sits on the picture, not at the
   far edge of the column — the media column itself stays sticky. */
.product__frame { position: relative; max-width: 30rem; }
@media (max-width: 860px) { .product__frame { max-width: none; } }

/* ---------- thank you ----------------------------------------------------- */

.thanks__title { font-size: clamp(3rem, 11vw, 8rem); }

.thanks__ref {
  margin: 1.5rem 0 0;
  color: var(--smoke);
  font-size: 0.6875rem;
  letter-spacing: 0.19em;
  text-transform: uppercase;
}

.thanks__aside { max-width: 46ch; margin-top: 2.5rem; }

/* The four steps, read left to right like a route sheet. */
.steps {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 clamp(1rem, 3vw, 2.5rem);
  margin: clamp(3rem, 8vw, 5.5rem) 0 0;
  padding: 0;
  list-style: none;
}
.step {
  border-top: 1px solid var(--bone-deep);
  padding: 1rem 0 1.75rem;
  /* One orchestrated moment: the steps land in order, then nothing else moves. */
  opacity: 0;
  animation: land 700ms var(--ease) forwards;
}
.step:nth-child(1) { animation-delay: 120ms; }
.step:nth-child(2) { animation-delay: 260ms; }
.step:nth-child(3) { animation-delay: 400ms; }
.step:nth-child(4) { animation-delay: 540ms; }

.step__no { display: block; color: var(--smoke); }
.step__name {
  font-family: var(--display);
  font-weight: 500;
  text-transform: uppercase;
  font-size: 1.0625rem;
  letter-spacing: var(--track-display);
  margin: 0.6rem 0 0.5rem;
}
.step__note { margin: 0; color: var(--smoke); font-size: 0.8125rem; max-width: 28ch; }

/* Green marks the steps an order has been through; the square marks the one it
   is on. On the thank-you page that is always the first, and only the first. */
.step--done { border-top-color: var(--bottle); }
.step--done .step__no { color: var(--bottle); }
.step--now .step__no::after {
  content: "";
  display: inline-block;
  width: 0.4rem; height: 0.4rem;
  margin-left: 0.6rem;
  background: var(--bottle);
  vertical-align: 0.05rem;
}

/* The same strip inside a tracked order: tighter, and no reveal — it is read
   as an answer to a question, not as an arrival. */
.steps--track {
  margin-top: 2rem;
  gap: 0 clamp(0.75rem, 2vw, 1.75rem);
}
.steps--track .step { animation: none; opacity: 1; padding-bottom: 1.25rem; }
@media (max-width: 780px) { .steps--track { margin-top: 1.5rem; } }
.steps--track .step__name { font-size: 1rem; }
.steps--track .step__note { font-size: 0.75rem; }

/* On a phone the four steps become a rail: the number, a line down the side,
   and the words beside it. Stacked as four full-width blocks they were most of
   a screen each, and an order with two of them was a scroll. */
@media (max-width: 780px) {
  .steps { display: block; }

  .step {
    position: relative;
    display: grid;
    grid-template-columns: 1.75rem 1fr;
    align-items: start;
    column-gap: 0.75rem;
    border-top: 0;
    padding: 0 0 1.35rem;
  }

  /* The line joins one step to the next, and stops at the last. */
  .step::before {
    content: "";
    position: absolute;
    left: 0.4rem;
    top: 1.1rem;
    bottom: 0;
    width: 1px;
    background: var(--bone-deep);
  }
  .step:last-child::before { display: none; }
  .step--done::before { background: var(--bottle); }

  .step__no {
    grid-column: 1;
    grid-row: 1 / span 2;
    position: relative;
    z-index: 1;
    padding-top: 0.15rem;
    background: var(--paper);
  }
  .step__no::after { margin-left: 0.25rem; }

  .step__name { grid-column: 2; margin: 0; font-size: 0.9375rem; }
  .step__note { grid-column: 2; margin-top: 0.2rem; max-width: none; }
}

.receipt {
  background: var(--bone);
  padding: clamp(1.5rem, 4vw, 2.5rem);
  margin-top: clamp(2rem, 5vw, 3.5rem);
  max-width: 44rem;
}

.receipt__lines { list-style: none; margin: 1.25rem 0 0; padding: 0; }
.receipt__line {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1.5rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--bone-deep);
}
.receipt__meta { display: block; color: var(--smoke); font-size: 0.8125rem; margin-top: 0.15rem; }
.receipt__amount { font-size: 0.8125rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.receipt__totals {
  display: grid; grid-template-columns: 1fr auto; gap: 0.6rem 1.5rem;
  margin: 1.25rem 0 0;
  font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase;
}
.receipt__totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.receipt__totals .is-total { color: var(--ink); padding-top: 0.6rem; border-top: 1px solid var(--bone-deep); }
.receipt__totals dt { color: var(--smoke); }
.receipt__totals dt.is-total { color: var(--ink); }

@media (max-width: 620px) {
  /* Quantity and remove share one row under the piece, rather than stacking
     into two — a bag of three lines was most of a screen of nothing. */
  .cart-line {
    grid-template-columns: 4.5rem 1fr;
    row-gap: 0.6rem;
    column-gap: 1rem;
    padding: 1.1rem 0;
  }
  /* Piece and picture on the first row, the controls together on the second. */
  .cart-line .plate { grid-column: 1; grid-row: 1; }
  .cart-line > div:not(.plate):not(.qty) { grid-column: 2; grid-row: 1; }
  .cart-line .qty { grid-column: 2; grid-row: 2; justify-self: start; }
  .cart-line__remove {
    grid-column: 2;
    grid-row: 2;
    justify-self: end;
    align-self: center;
    /* A finger, not a mouse: the word is small but the target is not. */
    padding: 0.75rem 0 0.75rem 1rem;
  }

  /* Thumbs, not cursors. */
  .qty { gap: 0.35rem; }
  .qty button { width: 2.75rem; height: 2.75rem; font-size: 1rem; }
  .qty span { min-width: 2rem; text-align: center; }

  /* The way out of the bag stays within reach the whole way down it, the same
     way the buy button does on a product. Sticky was not enough: it only pins
     while the summary itself is on screen, which is after all the scrolling. */
  [data-bag-summary] { padding-bottom: 5rem; }
  [data-checkout] {
    position: fixed;
    left: var(--gutter);
    right: var(--gutter);
    bottom: 0.9rem;
    width: auto;
    max-width: none;
    z-index: 20;
    box-shadow: 0 0.75rem 1.75rem color-mix(in srgb, var(--ink) 22%, transparent);
  }
}

/* ---------- tracking ------------------------------------------------------ */

.track-form { max-width: 26rem; }
.field {
  width: 100%;
  margin-top: 0.6rem;
  padding: 0.95rem 1rem;
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
}
.field:focus-visible { outline: 2px solid var(--bottle); outline-offset: 2px; }

.track-order {
  border-top: 1px solid var(--bone-deep);
  padding: 1.75rem 0;
  max-width: 34rem;
}
.track-order__state {
  font-family: var(--display); font-weight: 500;
  text-transform: uppercase; letter-spacing: var(--track-display);
  font-size: clamp(1.25rem, 2.6vw, 1.75rem);
  margin: 0.4rem 0 0.5rem;
}
.track-order__items { margin: 0.9rem 0 0; padding: 0; list-style: none; color: var(--smoke); font-size: 0.9375rem; }
.track-order__ship {
  display: inline-flex; align-items: center; gap: 0.6rem;
  margin-top: 1rem; padding-bottom: 0.3rem;
  border-bottom: 1px solid var(--ink);
  font-family: var(--mono); font-size: 0.6875rem; letter-spacing: 0.16em; text-transform: uppercase;
}
.track-none { color: var(--smoke); max-width: 34rem; margin-top: 2rem; }

/* ---------- size table ----------------------------------------------------- */

.size-table { overflow-x: auto; max-width: 100%; margin: 1.25rem 0 0; }
.size-table table {
  width: 100%; border-collapse: collapse;
  font-family: var(--mono); font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}
.size-table th, .size-table td {
  padding: 0.6rem 0.75rem;
  text-align: right;
  border-bottom: 1px solid var(--bone-deep);
  white-space: nowrap;
}
.size-table thead th {
  font-weight: 400; color: var(--smoke);
  font-size: 0.625rem; letter-spacing: 0.14em; text-transform: uppercase;
}
.size-table th[scope="row"] {
  text-align: left; font-weight: 400;
  color: var(--smoke); font-size: 0.625rem;
  letter-spacing: 0.12em; text-transform: uppercase;
}
.size-table tbody tr:last-child th,
.size-table tbody tr:last-child td { border-bottom: 0; }

.size-help { margin: -0.5rem 0 1.5rem; }
.size-help summary {
  font-family: var(--mono); font-size: 0.625rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--smoke); cursor: pointer; padding: 0.4rem 0;
}
.size-help summary:hover { color: var(--ink); }
.size-help[open] summary { color: var(--ink); }

/* ---------- editorial prose ----------------------------------------------- */

.prose { max-width: 62ch; }
.prose h2 {
  font-family: var(--display); font-weight: 500;
  text-transform: uppercase; font-size: 1rem; letter-spacing: var(--track-display);
  margin: 3rem 0 0.9rem;
}
.prose h2:first-child { margin-top: 0; }
.prose p { margin: 0 0 1.1rem; }
.prose ul { margin: 0 0 1.1rem; padding-left: 1.1rem; }
.prose li { margin-bottom: 0.4rem; }
.prose a { border-bottom: 1px solid var(--bone-deep); }
.prose a:hover { border-color: var(--ink); }

.two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); gap: clamp(2rem, 5vw, 4.5rem); }

/* ---------- footer -------------------------------------------------------- */

.colophon {
  background: var(--ink); color: var(--bone);
  padding: clamp(3rem, 7vw, 6rem) var(--gutter) 2rem;
  overflow: hidden;
}
.colophon a:hover { color: var(--paper); }
.colophon__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 2.5rem; margin-bottom: clamp(2.5rem, 6vw, 4rem);
}
.colophon h3 { font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--smoke); font-weight: 400; margin: 0 0 1rem; }
.colophon ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.55rem; font-size: 0.9375rem; }
.colophon__mark {
  /* Same wordmark, set large on ink: the sweep runs paper to silver here. */
  --wm-a: var(--paper); --wm-b: #b9bbb6;
  font-size: clamp(1.25rem, 5.6vw, 5rem);
  margin: 0; user-select: none;
}
.colophon__mark .wordmark__text { letter-spacing: 0.3em; }
.colophon__fine {
  display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; justify-content: space-between;
  margin-top: 1.5rem; color: var(--smoke);
}

/* ---------- motion -------------------------------------------------------- */

/* Only hide for reveal when scripting is on — no-JS readers get the content. */
.js .reveal { opacity: 0; transform: translateY(1.25rem); }
.js .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
}

/* hero draw-on: the flat sketches itself, then the annotations land */
.draw [data-draw] {
  stroke-dasharray: 2400;
  stroke-dashoffset: 2400;
  animation: draw 2000ms var(--ease) forwards;
}
@keyframes draw { to { stroke-dashoffset: 0; } }

.techpack .annotation { opacity: 0; animation: land 700ms var(--ease) forwards; }
.annotation--a { animation-delay: 1150ms; }
.annotation--b { animation-delay: 1350ms; }
.annotation--c { animation-delay: 1550ms; }
@keyframes land { from { opacity: 0; transform: translateY(0.5rem); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 1ms !important; animation-delay: 0ms !important; transition-duration: 1ms !important; }
  .js .reveal { opacity: 1; transform: none; }
  .draw [data-draw] { stroke-dashoffset: 0; }
}

/* =========================================================================
   Phone-first product experience
   Full-bleed imagery, one shot per screen, a short page that folds open,
   and buying always within reach. Desktop keeps the two-column layout.
   ========================================================================= */

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

/* ---------- menu ---------------------------------------------------------- */

.menu-button {
  display: none;
  align-items: center; justify-content: flex-start;
  width: 2.5rem; height: 2.5rem; margin-left: -0.6rem;
  padding: 0; border: 0; background: none; color: var(--ink); cursor: pointer;
}
.menu-button__bars { display: block; width: 1.15rem; }
.menu-button__bars i {
  display: block; height: 1px; background: currentColor;
}
.menu-button__bars i + i { margin-top: 5px; }
.menu-button__close {
  position: relative; display: block; width: 1.1rem; height: 1.1rem;
}
.menu-button__close::before,
.menu-button__close::after {
  content: ""; position: absolute; top: 50%; left: 0;
  width: 100%; height: 1px; background: currentColor;
}
.menu-button__close::before { transform: rotate(45deg); }
.menu-button__close::after { transform: rotate(-45deg); }

.menu {
  position: fixed; inset: 0; z-index: 80;
  background: var(--paper);
  display: flex; flex-direction: column;
  padding: 0 var(--gutter) 2rem;
  overflow-y: auto;
}
.menu[hidden] { display: none; }
.menu__head {
  display: flex; align-items: center; gap: 1rem;
  height: var(--bar); margin-bottom: 2rem;
}
.menu__nav { display: grid; gap: 0.15rem; }
.menu__nav a {
  font-family: var(--display); font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.06em;
  font-size: clamp(1.25rem, 5.6vw, 2rem); line-height: 1.2;
  padding: 0.35rem 0;
}
.menu__foot {
  margin-top: auto; padding-top: 3rem;
  display: grid; gap: 0.75rem; color: var(--smoke);
}

/* ---------- gallery ------------------------------------------------------- */

.gallery {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  background: var(--bone);
  aspect-ratio: 4 / 5;
  max-width: 30rem;
}
.gallery::-webkit-scrollbar { display: none; }
.gallery__slide {
  flex: 0 0 100%;
  scroll-snap-align: center;
  display: grid; place-items: center;
}
.gallery__slide img { width: 100%; height: 100%; object-fit: contain; }
.gallery__slide svg { width: 74%; height: auto; }

.gallery__count {
  margin: 0.6rem 0 0;
  color: var(--smoke);
  font-variant-numeric: tabular-nums;
}

/* ---------- folded detail ------------------------------------------------- */

.folds { margin-top: 2.5rem; border-top: 1px solid var(--bone-deep); }
.fold { border-bottom: 1px solid var(--bone-deep); }
.fold summary {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem 0; cursor: pointer; list-style: none;
  font-family: var(--mono); font-size: 0.6875rem;
  letter-spacing: 0.16em; text-transform: uppercase;
}
.fold summary::-webkit-details-marker { display: none; }
.fold summary::after {
  content: "+"; font-family: var(--mono); font-size: 0.9rem; color: var(--smoke);
}
.fold[open] summary::after { content: "–"; }
.fold__body { padding-bottom: 1.5rem; }
.fold__body p { margin: 0 0 0.9rem; }
.fold__body a { border-bottom: 1px solid var(--bone-deep); }

.spec-list { display: grid; grid-template-columns: 7rem 1fr; gap: 0.7rem 1.25rem; margin: 0; }
.spec-list dt {
  font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--smoke); padding-top: 0.15rem;
}
.spec-list dd { margin: 0; }

.plain-list { margin: 0; padding-left: 1.05rem; }
.plain-list li { margin-bottom: 0.35rem; }

/* ---------- the buy bar --------------------------------------------------- */

.buybar {
  position: fixed; inset: auto 0 0 0; z-index: 60;
  display: none;
  align-items: center; gap: 1rem;
  padding: 0.75rem var(--gutter);
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0px));
  background: var(--paper);
  box-shadow: 0 -1px 0 var(--bone-deep);
}
.buybar[hidden] { display: none; }
.buybar__what { min-width: 0; flex: 1; }
.buybar__name {
  display: block; font-size: 0.9375rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.buybar__meta { display: block; color: var(--smoke); font-size: 0.625rem; letter-spacing: 0.12em; }
.buybar .btn { width: auto; padding: 0.9rem 1.4rem; }

/* ---------- phone --------------------------------------------------------- */

@media (max-width: 860px) {
  .masthead { grid-template-columns: 1fr auto 1fr; }
  .masthead .masthead__nav { display: none; }
  .menu-button { display: inline-flex; }
  .utilities__care { display: none; }

  .product { display: block; padding: 0 var(--gutter) 5rem; }

  /* Imagery runs to the edges of the screen; nothing sits in a frame. It also
     scrolls away normally — the desktop rule pins it, which on a phone reads as
     the picture chasing you down the page. */
  .product__media {
    position: static;
    margin: 0 calc(var(--gutter) * -1) 1.5rem;
  }
  .gallery {
    max-width: none;
    aspect-ratio: 1 / 1;
  }
  .gallery__count { text-align: center; margin-top: 0.75rem; }
  .thumbs { display: none; }

  /* Name, price and choices centred, the way a garment page reads. */
  .product__head { text-align: center; }
  .product__title { font-size: clamp(1.35rem, 6vw, 2rem); letter-spacing: 0.01em; }
  .product__price { font-size: 0.9375rem; }
  .product .eyebrow { text-align: center; }
  .product .lede { margin-inline: auto; text-align: center; font-size: 1rem; }

  .sizes, .swatch-row { justify-content: center; }
  .size { min-width: 3.25rem; text-align: center; }

  .buybar { display: flex; }
}

@media (max-width: 560px) {
  .menu__nav a { font-size: 1.75rem; }
  .spec-list { grid-template-columns: 1fr; gap: 0.15rem 0; }
  .spec-list dd { margin-bottom: 0.85rem; }
}

/* ---------- also add ------------------------------------------------------- */

.also { margin: 2rem 0 2.5rem; }
.also__list {
  display: flex; flex-wrap: wrap; gap: 0.6rem;
  margin: 0.75rem 0 0; padding: 0; list-style: none;
}
.also__item {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0.9rem 0.5rem 0.5rem;
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  color: var(--ink);
  cursor: pointer; text-align: left;
  transition: border-color 300ms var(--ease);
}
.also__item:hover { border-color: var(--ink); }
.also__plate {
  width: 2.75rem; height: 2.75rem; flex: 0 0 auto;
  background: var(--bone);
  display: grid; place-items: center; overflow: hidden;
}
.also__plate img { width: 100%; height: 100%; object-fit: contain; }
.also__plate svg { width: 80%; height: auto; }
.also__what { display: grid; gap: 0.1rem; min-width: 0; }
.also__name {
  font-size: 0.875rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 11rem;
}
.also__price { font-size: 0.6875rem; color: var(--smoke); letter-spacing: 0.08em; }
.also__plus { font-family: var(--mono); color: var(--smoke); font-size: 1rem; line-height: 1; }
.also__item:hover .also__plus { color: var(--ink); }

/* =========================================================================
   The front page: a catalog
   Object one, measured by the wheel; the room, walked sideways; one label at
   thread scale; the house label as the close. The scroll engine
   (scrollcraft.css/.js) drives the acts; everything it drives reads --sc-p.
   ========================================================================= */

/* The engine's tokens, in the house's colours. scrollcraft.css loads before
   this sheet, so these win, and so does every house rule that says the same
   thing twice. */
:root {
  --sc-canvas: #ffffff;
  --sc-surface: #efede6;
  --sc-ink: #0c0d0c;
  --sc-ink-soft: #6d6c64;
  --sc-accent: #0e4a2e;
  --sc-accent-ink: #ffffff;
  --sc-font-display: var(--display);
  --sc-font-text: var(--body);
  --sc-font-mono: var(--mono);
  --sc-gutter: var(--gutter);
}
/* Drift interpolates --sc-canvas on the root; the ground has to read it. */
body.is-front { background: var(--sc-canvas, var(--paper)); }
/* The stages are a full screen each and pad for the masthead themselves. */
.is-front main { padding-top: 0; }
.is-front :focus-visible { border-radius: 0; }
/* The engine's sheet smooths scrolling everywhere; the house only does so on a
   desktop, where the wheel is coarse. A thumb needs none. */
@media (max-width: 860px) { html { scroll-behavior: auto; } }

/* No scripting, no engine: nothing is held back for a reveal that will never
   fire, and the drawings stand complete. */
html:not(.js) [data-sc-in],
html:not(.js) [data-sc-stagger] > * { opacity: 1; transform: none; }
html:not(.js) .one,
html:not(.js) .room { --sc-p: 1; }

/* ---------- the object index ---------------------------------------------- */

.index {
  position: fixed; left: clamp(0.9rem, 1.6vw, 1.75rem); top: 50%;
  z-index: 40;
  display: grid; gap: 1.1rem;
  transform: translateY(-50%);
  color: var(--smoke);
}
.index[hidden] { display: none; }
/* Past the room there is nothing left to index. */
.index { transition: opacity 320ms var(--ease); }
.index.is-off { opacity: 0; pointer-events: none; }
.index a {
  display: flex; align-items: baseline; gap: 0.7rem;
  color: inherit;
  font-size: 0.625rem; letter-spacing: 0.18em;
  transition: color 240ms var(--ease);
}
.index a::before {
  content: ""; align-self: center;
  width: 2.25rem; height: 1px; background: currentColor;
  transform-origin: 0 50%; transform: scaleX(0.55);
  transition: transform 320ms var(--ease);
}
.index__no { font-variant-numeric: tabular-nums; }
.index__name {
  opacity: 0; transform: translateX(-0.35rem);
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
  white-space: nowrap;
}
.index a:hover, .index a:focus-visible, .index a[aria-current="true"] { color: var(--ink); }
.index a[aria-current="true"]::before { transform: scaleX(1); }
.index a:hover .index__name, .index a:focus-visible .index__name { opacity: 1; transform: none; }
@media (max-width: 1100px) { .index { display: none !important; } }

/* ---------- 1 · object one, in depth, measured ----------------------------- */

.one__stage {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: center;
  gap: var(--gutter);
  padding: calc(var(--bar) + 1rem) var(--gutter) 1.5rem;
}
@media (min-width: 1101px) { .one__stage { padding-left: calc(var(--gutter) + 3rem); } }
/* The spotlight attribute is here for the pointer it publishes, not its light. */
.one [data-sc-spotlight]::after { display: none; }

/* Every plane leans with the pointer by its depth: far planes drift against
   it, near ones with it, the way a room does when you move your head. The
   engine's parallax writes `transform`; the lean rides on `translate`, which
   composes with it rather than fighting over the same property. */
.one__plane {
  --lean-x: calc((var(--sc-mx, 0.5) - 0.5) * var(--depth, 0));
  --lean-y: calc((var(--sc-my, 0.5) - 0.5) * var(--depth, 0));
  translate: calc(var(--lean-x) * 18px) calc(var(--lean-y) * 12px);
  transition: translate 700ms var(--ease);
}

/* Far plane: the pattern sheet. */
.one__sheet {
  position: absolute; inset: -12% 0;
  pointer-events: none;
  background:
    linear-gradient(var(--bone-deep) 1px, transparent 1px) 0 0 / 100% 3.5rem,
    linear-gradient(90deg, var(--bone-deep) 1px, transparent 1px) 0 0 / 3.5rem 100%;
  opacity: 0.55;
  -webkit-mask-image: radial-gradient(ellipse 30% 46% at 70% 52%, #000 25%, transparent 80%);
  mask-image: radial-gradient(ellipse 30% 46% at 70% 52%, #000 25%, transparent 80%);
}

.one__figure {
  position: relative; grid-column: 2; grid-row: 1;
  height: min(78svh, 100%);
  display: grid; place-items: center;
  perspective: 1400px;
}

/* Mid plane: the technical flat, drawn by the wheel, behind the piece. */
.one__flat { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.one__flat svg { width: min(146%, 40rem); max-width: none; height: auto; stroke: var(--ink); opacity: 0.3; }
.one__flat [data-draw] {
  stroke-dasharray: 2400;
  stroke-dashoffset: calc(2400 * (1 - min(1, var(--sc-p, 0) * 2.4)));
}

/* A soft paper shadow, so the garment stands off the sheet. */
.one__shadow {
  position: absolute; width: 62%; aspect-ratio: 758 / 1000;
  background: radial-gradient(ellipse 50% 46% at 50% 56%, rgba(12, 13, 12, 0.22), transparent 72%);
  filter: blur(18px);
  pointer-events: none;
}

/* The object, turning a few degrees toward the pointer, with the tape on it. */
.one__garment {
  position: relative; width: min(100%, 29rem); color: var(--ink);
  rotate: y calc((var(--sc-mx, 0.5) - 0.5) * -8deg);
  transition: rotate 700ms var(--ease), translate 700ms var(--ease);
  transform-style: preserve-3d;
}
.one__garment img { width: 100%; height: auto; }
.one__garment svg:not(.one__tape) { width: 100%; height: auto; }

.one__tape { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.one__halo { stroke: var(--paper); stroke-width: 4; }
.one__dim--w .one__line, .one__dim--w .one__halo {
  stroke-dasharray: 457;
  stroke-dashoffset: calc(457 * (1 - clamp(0, (var(--sc-p, 0) - 0.34) / 0.26, 1)));
}
.one__dim--w .one__tick { opacity: clamp(0, (var(--sc-p, 0) - 0.34) / 0.05, 1); }
.one__dim--l .one__line, .one__dim--l .one__halo {
  stroke-dasharray: 946;
  stroke-dashoffset: calc(946 * (1 - clamp(0, (var(--sc-p, 0) - 0.58) / 0.28, 1)));
}
.one__dim--l .one__tick, .one__dim--l .one__lead { opacity: clamp(0, (var(--sc-p, 0) - 0.58) / 0.05, 1); }

.one__readout, .one__ticket {
  position: absolute; margin: 0;
  font-size: 0.6875rem; letter-spacing: 0.14em;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--bone-deep);
  padding: 0.3rem 0.55rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  box-shadow: 0 6px 18px -10px rgba(12, 13, 12, 0.28);
}
.one__readout::before { content: attr(data-readout) " "; color: var(--smoke); }
.one__readout--w { left: 50%; top: 49%; transform: translate(-50%, calc(-100% - 0.9rem)); opacity: clamp(0, (var(--sc-p, 0) - 0.36) / 0.05, 1); }
.one__readout--l { left: calc(660 / 758 * 100% + 1.1rem); top: 50%; transform: translateY(-50%); opacity: clamp(0, (var(--sc-p, 0) - 0.6) / 0.05, 1); }

/* Near planes: the spec as tickets around the piece. They are read on the
   label; here they are placed, so the reader can tell the piece has depth. */
.one__ticket { z-index: 2; max-width: 16rem; white-space: normal; line-height: 1.5; }
.one__ticket b { font-weight: 400; color: var(--smoke); margin-right: 0.35rem; }
.one__ticket--a { left: 0; top: 12%; }
.one__ticket--b { right: -2%; top: 36%; }
.one__ticket--c { left: 4%; bottom: 10%; }

/* The label. Same schema as every object in the room. */
.one__label { grid-column: 1; grid-row: 1; position: relative; z-index: 2; max-width: 40rem; }
.one__index { color: var(--smoke); display: flex; align-items: center; gap: 0.75rem; margin: 0; }
.one__index .eco__word { font-size: inherit; letter-spacing: inherit; }
.one__name { font-size: clamp(1.75rem, 3vw, 2.75rem); margin: 0.9rem 0 1.5rem; }

.spec-line { margin: 0; display: grid; gap: 0.45rem 0; }
.spec-line > div { display: grid; grid-template-columns: 5.5rem minmax(0, 1fr); gap: 0 1rem; align-items: baseline; }
.spec-line dt {
  font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--smoke);
}
.spec-line dd { margin: 0; font-size: 0.9375rem; text-wrap: pretty; }
.spec-line dd .price-was { margin-right: 0.35rem; }
.spec-line--tight { gap: 0.3rem 0; }
.spec-line--tight > div { grid-template-columns: 4.25rem minmax(0, 1fr); }
.spec-line--tight dd { font-size: 0.8125rem; }
.spec-line .swatches { margin-right: 0.5rem; }

.one__sizes { margin: 1.5rem 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem 0.9rem; }
.one__sizes-label { color: var(--smoke); }
.sizes--tape { margin: 0; gap: 0.4rem; }
.sizes--tape .size { padding: 0.5rem 0.75rem; font-size: 0.6875rem; }
.one__open { margin-top: 1.6rem; }

@media (max-width: 860px) {
  .one__stage {
    --figure-h: clamp(11rem, 40svh, 24rem);
    grid-template-columns: 1fr;
    grid-template-rows: minmax(0, 1fr) auto;
    align-content: stretch;
    gap: 0.5rem;
    padding: calc(var(--bar) + 0.5rem) var(--gutter) 1rem;
  }
  .one__figure { grid-column: 1; grid-row: 1; height: var(--figure-h); min-height: 0; }
  .one__garment { width: auto; height: var(--figure-h); }
  .one__garment img { height: var(--figure-h); width: auto; max-width: none; }
  .one__flat svg { width: auto; height: calc(var(--figure-h) * 1.16); }
  .one__shadow { width: auto; height: var(--figure-h); }
  .one__ticket { display: none; }
  .one__sheet { -webkit-mask-image: radial-gradient(ellipse 80% 55% at 50% 32%, #000 30%, transparent 78%); mask-image: radial-gradient(ellipse 80% 55% at 50% 32%, #000 30%, transparent 78%); }
  .one__label { grid-column: 1; grid-row: 2; max-width: none; }
  .one__name { font-size: clamp(1.35rem, 6vw, 1.9rem); margin: 0.5rem 0 0.8rem; }
  .spec-line { gap: 0.25rem 0; }
  .spec-line dd { font-size: 0.875rem; }
  .one__label .spec-line > div:nth-of-type(3) { display: none; } /* the mark: read it on the piece */
  .one__sizes { margin-top: 0.9rem; gap: 0.4rem 0.6rem; }
  .sizes--tape { gap: 0.25rem; }
  .sizes--tape .size { padding: 0.45rem 0.42rem; font-size: 0.5625rem; letter-spacing: 0.04em; min-width: 2.5rem; }
  .one__open { margin-top: 0.9rem; padding: 0.9rem 1.25rem; }
  .one__readout { font-size: 0.5625rem; padding: 0.2rem 0.4rem; }
  .one__readout--l { left: auto; right: 0; top: 50%; transform: translate(0, -50%); }
}
@media (max-width: 860px) and (max-height: 700px) {
  .one__stage { --figure-h: 32svh; }
  .one__name { font-size: 1.2rem; margin: 0.35rem 0 0.5rem; }
  .spec-line dd { font-size: 0.8125rem; }
  .one__label .spec-line > div:nth-of-type(4) { display: none; } /* colours: on the piece */
  .one__sizes { margin-top: 0.6rem; }
  .one__open { margin-top: 0.6rem; padding: 0.7rem 1rem; }
}

/* ---------- 2 · the room: the pieces turn as they pass --------------------- */

.room__stage { display: flex; align-items: center; }
.room__rail {
  display: flex; align-items: stretch;
  gap: clamp(1.5rem, 3vw, 3rem);
  padding: calc(var(--bar) + 1rem) var(--gutter) 2rem;
}
@media (min-width: 1101px) { .room__rail { padding-left: calc(var(--gutter) + 3rem); } }
.room__lead { flex: 0 0 auto; width: clamp(16rem, 26vw, 24rem); align-self: center; }
.room__title { font-size: clamp(2rem, 4.5vw, 4rem); }
.room__lead .lede { margin: 1.5rem 0 0; }

.object { flex: 0 0 auto; width: clamp(15rem, 22vw, 20rem); align-self: center; }
.object__link { display: block; }

/* Each plate turns toward the centre of the screen as the rail travels, and
   once it has turned far enough the front gives way to the side view. Both
   values are written by the page from where the plate actually is. */
.object__turn {
  transform: perspective(1200px) rotateY(var(--turn, 0deg));
  transform-style: preserve-3d;
  will-change: transform;
}
.object__plate {
  position: relative;
  background: var(--paper);
  aspect-ratio: 1;
  overflow: hidden;
  box-shadow: 0 22px 44px -26px rgba(12, 13, 12, 0.38), 0 2px 6px -3px rgba(12, 13, 12, 0.18);
  transition: background 500ms var(--ease);
}
/* Pictures at their own proportions: the mockups are square, so is the plate. */
.object__plate img { width: 100%; height: auto; display: block; }
.object__side { position: absolute; inset: 0; opacity: var(--side, 0); }
.object__plate svg { width: 76%; height: auto; margin: 12% auto; }
.object__link:hover .object__plate { background: var(--bone-deep); }
.object__index { margin: 1.1rem 0 0.35rem; color: var(--smoke); }
.object__name { font-size: 1.0625rem; font-weight: 400; letter-spacing: -0.005em; margin: 0 0 0.7rem; }

.room__note { flex: 0 0 auto; width: clamp(14rem, 20vw, 18rem); align-self: center; }
.room__note .mono { color: var(--smoke); margin: 0 0 0.9rem; }
.room__note p { margin: 0; }
.room__all { display: inline-block; margin-top: 1.25rem; color: var(--smoke); border-bottom: 1px solid var(--bone-deep); }
.room__all:hover { color: var(--ink); border-color: var(--ink); }

/* Without motion, or without scripting, the room is not pulled. It is a grid
   that wraps, or a strip that scrolls, so every object stays gettable. */
.room--still { background: var(--bone); }
.room--still .room__stage { display: block; }
.room--still .room__rail { flex-wrap: wrap; align-items: start; padding-block: clamp(2rem, 5vw, 4rem) clamp(3rem, 8vw, 6rem); transform: none !important; }
.room--still .room__lead, .room--still .room__note { width: 100%; }
.room--still .object__turn { transform: none; }
html:not(.js) .room__stage { overflow-x: auto; }

/* Objects settle in as the rail is pulled: the first is already there, the
   rest arrive in order. Floored so an unsettled object reads as arriving, not
   as failing to load. */
@media (min-width: 861px) and (prefers-reduced-motion: no-preference) {
  .object {
    --settle: clamp(0, calc(var(--sc-p, 0) * 9 - (var(--i) - 1) * 1.1 + 1), 1);
    opacity: calc(0.55 + 0.45 * var(--settle));
    transform: translateY(calc((1 - var(--settle)) * 1.5rem));
  }
}
@media (max-width: 860px) {
  .room__rail { padding-top: calc(var(--bar) + 1.5rem); gap: 1.25rem; }
  .room__lead { width: 78vw; }
  .room__title { font-size: clamp(1.9rem, 9vw, 2.6rem); }
  .object { width: 74vw; }
  .room__note { width: 78vw; }
}

/* ---------- 3 · the shoot: a dolly through every photograph ---------------- */

.shoot__stage {
  perspective: 1100px;
  perspective-origin: 50% 50%;
  overflow: clip;
}
.shoot__head {
  position: absolute; z-index: 3;
  top: calc(var(--bar) + 1.25rem); left: var(--gutter); right: var(--gutter);
  display: flex; justify-content: space-between;
  color: var(--smoke);
}
.shoot__head p { margin: 0; }
.shoot__count { font-variant-numeric: tabular-nums; }
@media (min-width: 1101px) { .shoot__head { left: calc(var(--gutter) + 3rem); } }

.shoot__space { position: absolute; inset: 0; transform-style: preserve-3d; }

/* One photograph per card, at its own proportions. The camera is the act's
   progress: it travels one card-depth per (cards - 1) of it, so card 0 stands
   at the camera plane on the first screen and the last card on the last.
   A card fades in from far away and out again the moment it passes. */
.shot {
  --zc: calc(var(--sc-p, 0) * (var(--cards, 1) - 1) - var(--depth, 0));
  position: absolute; left: 50%; top: 50%;
  width: min(34vw, 30rem);
  margin: 0;
  transform: translate3d(calc(-50% + var(--x, 0) * 38vw), calc(-50% + var(--y, 0) * 30vh), calc(var(--zc) * 640px));
  opacity: min(clamp(0, calc(1.1 + var(--zc) * 0.22), 1), clamp(0, calc(1 - var(--zc) * 2.6), 1));
  will-change: transform, opacity;
  background: var(--paper);
  box-shadow: 0 30px 60px -36px rgba(12, 13, 12, 0.45), 0 2px 8px -4px rgba(12, 13, 12, 0.2);
}
.shot img { width: 100%; height: auto; display: block; }
.shot figcaption {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: 0.7rem 0.8rem;
  font-size: 0.625rem; letter-spacing: 0.14em;
  color: var(--smoke);
}
.shot figcaption span:first-child { color: var(--ink); }
.shot--last { width: min(44vw, 38rem); }

/* The label the camera stops on. */
.shoot__label {
  position: absolute; z-index: 3;
  right: var(--gutter); bottom: clamp(2rem, 8vh, 5rem);
  opacity: clamp(0, (var(--sc-p, 0) - 0.9) / 0.07, 1);
  transform: translateY(calc((1 - clamp(0, (var(--sc-p, 0) - 0.9) / 0.07, 1)) * 0.75rem));
  font-size: 0.625rem;
}

/* Without motion the shoot is a contact sheet; every photograph is on the page. */
.shoot--still { padding: clamp(3rem, 8vw, 6rem) var(--gutter); }
.shoot--still .shoot__stage { perspective: none; overflow: visible; height: auto; position: static; }
.shoot--still .shoot__head { position: static; margin-bottom: 1.5rem; }
.shoot--still .shoot__space { position: static; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr)); gap: 1.5rem; transform: none; }
.shoot--still .shot { position: static; width: auto; transform: none; opacity: 1; }
.shoot--still .shoot__label { position: static; opacity: 1; transform: none; margin-top: 2rem; }
html:not(.js) .shoot { --sc-p: 1; }

@media (max-width: 860px) {
  .shot { width: min(70vw, 22rem); transform: translate3d(calc(-50% + var(--x, 0) * 22vw), calc(-50% + var(--y, 0) * 24vh), calc(var(--zc) * 520px)); }
  .shot--last { width: min(84vw, 26rem); --y: -0.32; }
  .shot figcaption { flex-direction: column; gap: 0.15rem; padding: 0.55rem 0.65rem; }
  .shoot__label { left: var(--gutter); right: var(--gutter); bottom: 1.25rem; }
  .shoot__label dl { grid-template-columns: auto 1fr; }
}

/* ---------- 4 · the house label: the close ------------------------------- */

.house { padding: clamp(3rem, 9vw, 8rem) var(--gutter) clamp(4rem, 12vw, 10rem); }
.house__inner { max-width: 80rem; margin: 0 auto; display: flex; justify-content: flex-end; }
.label--house { font-size: 0.6875rem; letter-spacing: 0.14em; line-height: 1.9; padding: 1.1rem 1.4rem 1rem; }
.label--house dl { gap: 0 1.6rem; }
.label--house dd a { border-bottom: 1px solid var(--bone-deep); transition: border-color 240ms var(--ease); }
.label--house dd a:hover { border-color: var(--bottle); }
@media (max-width: 860px) {
  .house__inner { justify-content: flex-start; }
  .label--house { font-size: 0.625rem; }
}
