/* ==========================================================================
   BON JEU — product pages
   Editorial rather than commerce-template: image led, typographic authority,
   no rounded boxes, no gradients, no card grid (BRAND-BRIEF.md §37).
   Runs dark-on-cream, the inverse of the hero.

   Spatial thesis: the whole buying decision — garment, name, price, colourway,
   size, action — sits in the first viewport. Everything below it is editorial
   and is found by scrolling. So the gallery is capped to the viewport rather
   than driven by the image's own 4:5 ratio, and the info column is tuned for a
   short, deliberate stack rather than an evenly spaced one.
   ========================================================================== */

:root {
  --ink: var(--navy);
  /* 0.72 clears 4.5:1 on cream; 0.62 measured 3.92 and failed the small
     labels that use it. */
  --ink-soft: rgba(17, 46, 103, 0.72);
  --ink-mute: rgba(17, 46, 103, 0.55);
  --rule: rgba(17, 46, 103, 0.14);
  --page: var(--cream);
  --gutter: clamp(20px, 4vw, 60px);
  --stack: clamp(56px, 8vw, 128px);
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

html { background: var(--page); }

body {
  color: var(--ink);
  background: var(--page);
  font-size: 16px;
  line-height: 1.5;
}

:focus-visible { outline: 1.5px solid var(--ink); outline-offset: 3px; }

.wrap { max-width: 1520px; margin: 0 auto; padding: 0 var(--gutter); }

/* The one recurring small-caps voice. Used beside headings and as metadata —
   never stacked above a heading as a kicker. */
.label {
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------------- nav */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 40px;
  padding: 16px var(--gutter);
  background: var(--page);
  font-size: 11px;
  font-weight: 400;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.nav__home {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  line-height: 0.84;
  letter-spacing: 0;
}

.nav__links { display: flex; gap: 30px; margin-left: auto; }

.lang {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  margin-left: 28px;
  font-size: 11px;
  letter-spacing: 0.16em;
}
.lang span { color: var(--ink-mute); }
.lang button { color: var(--ink-mute); transition: color 200ms var(--ease); }
.lang button:hover { color: var(--ink); }
.lang button[aria-current='true'] { color: var(--ink); }
.nav a { transition: opacity 180ms var(--ease); }
.nav a:hover { opacity: 0.5; }

/* Bilingual pairs. The French sits beneath its English in italic — §11's
   "small poetic detail" — quiet enough to read as a caption rather than as
   duplicate copy. */
.alt {
  display: block;
  margin-top: 3px;
  font-style: italic;
  font-size: 0.86em;
  text-transform: none;
  letter-spacing: 0.03em;
  color: var(--ink-mute);
}

/* Inline contexts keep the pair on one line. */
.crumb .alt, .size .alt { display: none; }

/* ------------------------------------------------------------- breadcrumb */

.crumb {
  padding: 14px 0 0;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.crumb a:hover { color: var(--ink); }

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

.product {
  display: grid;
  grid-template-columns: minmax(0, 1.18fr) minmax(0, 1fr);
  gap: clamp(30px, 4.5vw, 78px);
  padding: 18px 0 var(--stack);
  align-items: start;
}

/* Gallery ---------------------------------------------------------------- */
/* Height comes from the viewport, not the image's ratio — that is what keeps
   the action above the fold. `contain` because the garment must never crop. */

/* Optical centring. A garment placed at the frame's geometric middle reads as
   having slipped downward — the eye puts the visual centre above the
   mathematical one. Padding the foot of the frame hangs the garment slightly
   high, which is how flats are conventionally shot. Percentage padding would
   resolve against width, so the drop is taken from the frame's own height. */
.gallery__main {
  --frame-h: min(66vh, 660px);
  --optical-drop: 0.025;
  height: var(--frame-h);
  padding-bottom: calc(var(--frame-h) * var(--optical-drop));
  /* Matches the studio ground of that product's photographs. Pure white left a
     visible tonal edge where the image ended and the card carried on. */
  background: var(--plate-bg, #fbfaf8);
  display: grid;
  place-items: center;
  overflow: hidden;
}

.gallery__main img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* The page's one authored motion moment: garments dissolve into each other
     rather than cutting. */
  transition: opacity 420ms var(--ease);
}
.gallery__main[data-swapping='true'] img { opacity: 0; }

.gallery__strip {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  max-width: 392px;
  margin-top: 8px;
}

.gallery__thumb {
  background: var(--plate-bg, #fbfaf8);
  aspect-ratio: 4 / 5;
  padding: 0 0 5%;
  overflow: hidden;
  opacity: 0.55;
  transition: opacity 220ms var(--ease);
}
.gallery__thumb img { width: 100%; height: 100%; object-fit: contain; }
.gallery__thumb:hover { opacity: 0.85; }
.gallery__thumb[aria-current='true'] { opacity: 1; }

/* Info column ------------------------------------------------------------ */

.info { position: sticky; top: 88px; }

/* The name leads. A lighter weight and narrowed width axis read as couture
   rather than as a product-listing headline. */
.info__name {
  font-size: clamp(32px, 4.1vw, 58px);
  font-weight: 500;
  line-height: 0.98;
  letter-spacing: -0.018em;
  text-transform: uppercase;
}

/* Price and colourway share a line: two facts, one row, less vertical stack. */
.info__meta {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--rule);
}

.info__price { font-size: 16px; letter-spacing: 0.08em; }

.info__colour {
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.info__copy {
  margin-top: 20px;
  max-width: 48ch;
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--ink-soft);
}

/* Colourway -------------------------------------------------------------- */

.swatches { display: flex; gap: 12px; margin-top: 24px; }

.swatch {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--rule);
  transition: box-shadow 200ms var(--ease);
}
.swatch:hover { box-shadow: 0 1px 5px rgba(17, 46, 103, 0.18); }
.swatch[aria-current='true'] {
  box-shadow: 0 0 0 1px var(--page), 0 0 0 2px var(--ink);
}

/* Sizes ------------------------------------------------------------------ */
/* A tracked row of type with a rule under the chosen one. Boxes read as a
   checkout widget; this reads as a label sewn into a garment — and costs about
   a third of the height. */

.sizes { margin-top: 26px; }

.sizes__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.sizes__guide {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 2px;
}
.sizes__guide:hover { color: var(--ink); border-bottom-color: var(--ink); }

.sizes__row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin-top: 10px;
}

.size {
  /* Padding keeps the touch target near 34px while the mark itself stays
     small. */
  padding: 10px 3px;
  min-width: 26px;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border-bottom: 1px solid transparent;
  transition: color 180ms var(--ease), border-color 180ms var(--ease);
}
.size:hover { color: var(--ink); }
.size[aria-pressed='true'] { color: var(--ink); border-bottom-color: var(--ink); }
.size[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
  text-decoration: line-through;
}
.size[disabled]:hover { color: var(--ink-mute); }

.add {
  width: 100%;
  margin-top: 22px;
  padding: 15px 0;
  background: var(--ink);
  color: var(--cream);
  font-size: 11px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  transition: background 200ms var(--ease);
}
.add:hover { background: #0a1c40; }
.add[data-state='added'] { background: var(--kelly); }

.add__note {
  margin-top: 10px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  min-height: 1em;
}

/* Spec list -------------------------------------------------------------- */

.spec { margin-top: 26px; border-top: 1px solid var(--rule); }

.spec__item { border-bottom: 1px solid var(--rule); }

.spec__q {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  padding: 14px 26px 14px 0;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-align: left;
  list-style: none;
  cursor: pointer;
}
.spec__q::-webkit-details-marker { display: none; }

/* Drawn from two hairlines rather than a "+" character — a typed glyph is not
   an icon, and its weight never matches the rules around it. */
.spec__q::before,
.spec__q::after {
  content: '';
  position: absolute;
  right: 2px;
  top: 50%;
  margin-top: -0.5px;
  width: 11px;
  height: 1px;
  background: var(--ink);
  transition: transform 260ms var(--ease);
}
.spec__q::after { transform: rotate(90deg); }
.spec__item[open] .spec__q::after { transform: rotate(0deg); }

.spec__a {
  padding: 0 0 18px;
  font-size: 13.5px;
  line-height: 1.62;
  color: var(--ink-soft);
}
.spec__a li { margin-left: 16px; padding-left: 4px; }
.spec__a li + li { margin-top: 3px; }

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

.editorial { margin-bottom: var(--stack); }

.editorial img {
  width: 100%;
  aspect-ratio: 21 / 9;
  object-fit: cover;
}

.editorial figcaption {
  margin-top: 12px;
  padding: 0 var(--gutter);
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

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

.section { margin-bottom: var(--stack); }

/* More space above a heading than below it. */
.section__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 26px;
}

.section__title {
  font-size: clamp(15px, 1.6vw, 20px);
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Materials -------------------------------------------------------------- */

.materials {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(10px, 1.3vw, 18px);
}

.material img { width: 100%; aspect-ratio: 1; object-fit: cover; }

.material p {
  margin-top: 10px;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.55;
}

/* Family strip ----------------------------------------------------------- */

.family {
  display: grid;
  justify-content: start;
  grid-auto-flow: column;
  /* Bounded, so a strip holding one item does not stretch it across the whole
     page. Eight items overflow and scroll, which is intended. */
  grid-auto-columns: clamp(180px, 20vw, 268px);
  gap: clamp(10px, 1.3vw, 18px);
  overflow-x: auto;
  padding-bottom: 8px;
  scroll-snap-type: x mandatory;
}

.family__item { scroll-snap-align: start; }

.family__item img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
  background: var(--white);
  transition: opacity 240ms var(--ease);
}
.family__item:hover img { opacity: 0.8; }

.family__name {
  margin-top: 10px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.family__colour {
  margin-top: 2px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.family__item[data-current='true'] .family__name::after {
  content: ' — this piece';
  color: var(--ink-mute);
}

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

.foot {
  padding: clamp(36px, 5vw, 64px) var(--gutter);
  border-top: 1px solid var(--rule);
}

.foot__line {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 32px;
  align-items: baseline;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.foot__mark {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 14px;
  line-height: 0.84;
  letter-spacing: 0;
  color: var(--ink);
}

/* ------------------------------------------------------------------ mobile */

@media (max-width: 940px) {
  .product { grid-template-columns: 1fr; }
  .info { position: static; }
  .gallery__main { height: min(58vh, 520px); }
  .materials { grid-template-columns: repeat(3, 1fr); }
  .nav { gap: 18px; font-size: 11px; }
  .nav__links { gap: 20px; }
  .editorial img { aspect-ratio: 3 / 2; }
}

@media (max-width: 560px) {
  .nav__links a[data-optional] { display: none; }
  .size { padding: 12px 4px; }
  .sizes__row { gap: 4px 20px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}
