/* ═══════════════════════════════════════════════════════════════════
   WATCH MUSEUM & ACCESSORIES — Dhaka
   Ground = blued steel. Paper = opaline dial. Accent = aged lume.
   Gold is reserved for the mark, never for UI.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --ink:      #0F1317;
  --ink-2:    #161C22;
  --dial:     #E6E4DC;
  --dial-2:   #DCD9CF;

  --steel:    #8A9198;
  --steel-d:  #5C646C;
  --gold:     #B08D46;

  --lume:      #9FD9BE;
  --lume-deep: #1E5C46;

  /* per-band, flipped by .band--dark / .band--light */
  --bg:   var(--ink);
  --fg:   var(--dial);
  --fg-2: var(--steel);
  --line: rgba(230,228,220,.14);
  --acc:  var(--lume);

  --sans:  'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* The reference wordmark is Söhne Breit Extrafett (Klim, commercial).
     Archivo at wdth 125 / wght 900 is the closest free equivalent.
     To use licensed Söhne, @font-face it and change this one line. */
  --font-wordmark: 'Archivo', system-ui, sans-serif;
  --serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --mono:  'Chivo Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  --gutter: clamp(1.25rem, 5vw, 4.5rem);
  --vspace: clamp(4.5rem, 11vw, 10rem);
  --max: 1560px;
  --r-img: clamp(10px, 1vw, 16px);

  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-o: cubic-bezier(.16,1,.3,1);
}

/* ── reset ──────────────────────────────────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
html.has-smooth{ scroll-behavior:auto; }   /* JS eases it instead */
body{
  margin:0;
  background:var(--ink);
  color:var(--dial);
  font-family:var(--sans);
  font-size:clamp(.9375rem, .35vw + .84rem, 1.0625rem);
  line-height:1.62;
  font-variation-settings:'wdth' 100,'wght' 400;
  -webkit-font-smoothing:antialiased;
  /* clip, not hidden: `overflow-x:hidden` turns body into a scroll
     container and breaks the sticky hero. */
  overflow-x:clip;
}
h1,h2,h3,h4,p,dl,dd,figure,figcaption,ol,ul{ margin:0; }
ol,ul{ padding:0; list-style:none; }
img,svg{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
hr{ border:0; }

.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.skip{
  position:fixed; top:.5rem; left:.5rem; z-index:999;
  transform:translateY(-200%);
  background:var(--lume); color:#08201A;
  padding:.7rem 1.1rem; border-radius:2px;
  font-family:var(--mono); font-size:.75rem; letter-spacing:.08em; text-transform:uppercase;
}
.skip:focus{ transform:none; }
:focus-visible{ outline:2px solid var(--acc); outline-offset:3px; border-radius:2px; }

.grain{
  position:fixed; inset:0; z-index:900; pointer-events:none; opacity:.055;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── bands ──────────────────────────────────────────────────────── */
.band{ position:relative; background:var(--bg); color:var(--fg); }
.band--dark{
  --bg:var(--ink); --fg:var(--dial); --fg-2:var(--steel);
  --line:rgba(230,228,220,.14); --acc:var(--lume);
}
.band--light{
  --bg:var(--dial); --fg:var(--ink); --fg-2:var(--steel-d);
  --line:rgba(15,19,23,.15); --acc:var(--lume-deep);
}
.sec{ padding-block:var(--vspace); }
.wrap{ width:100%; max-width:var(--max); margin-inline:auto; padding-inline:var(--gutter); }

/* ── type primitives ────────────────────────────────────────────── */
.eyebrow{
  display:flex; align-items:center; gap:.7em;
  font-family:var(--mono); font-size:.6875rem; font-weight:400;
  letter-spacing:.2em; text-transform:uppercase; color:var(--fg-2);
  margin-bottom:1.4rem;
}
.eyebrow b{ color:var(--acc); font-weight:500; letter-spacing:.14em; }
.eyebrow b::after{
  content:''; display:inline-block; width:1.6rem; height:1px;
  background:currentColor; vertical-align:middle; margin-left:.7em; opacity:.5;
}
.h-serif{
  font-family:var(--serif);
  font-size:clamp(2.15rem, 6.1vw, 4.9rem);
  font-variation-settings:'opsz' 60,'wght' 350;
  line-height:1.02; letter-spacing:-.017em; text-wrap:balance;
}
.lede{ max-width:46ch; color:var(--fg-2); }
.rule{ width:3.5rem; height:1px; background:var(--acc); margin:1.9rem 0; opacity:.85; }
.sec__note{ margin-top:1.15rem; max-width:44ch; color:var(--fg-2); font-size:.9375rem; }
.sec__head{ position:relative; margin-bottom:clamp(2.75rem,6vw,5rem); }

/* ═══ Header ═══════════════════════════════════════════════════════ */
.hdr{
  position:fixed; inset:0 0 auto; z-index:400;
  background:rgba(230,228,220,0);
  border-bottom:1px solid transparent;
  transition:background .5s var(--ease), border-color .5s var(--ease);
}
.hdr__in{
  max-width:var(--max); margin-inline:auto;
  padding:.85rem var(--gutter);
  display:flex; align-items:center; gap:clamp(1.5rem,3.5vw,3rem);
}
.hdr.is-stuck{
  background:rgba(15,19,23,.9);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-bottom-color:rgba(230,228,220,.12);
}
.logo{ display:flex; align-items:center; gap:.6rem; margin-right:auto; }
/* The house mark: the real logo, cropped into a disc. The artwork is wider
   than it is tall, so it is fitted rather than filled — filling the circle
   would shear the diamonds' left and right points off. The file is drawn in
   ink, so the disc runs ink-on-cream and inverts to cream-on-ink once the
   header is over a dark band, which keeps the badge visible either way. */
.logo__mark{
  width:38px; height:38px; flex:none; border-radius:50%;
  display:grid; place-items:center; overflow:hidden;
  background:var(--ink); transition:background .4s var(--ease);
}
.logo__mark img{
  display:block; width:84%; height:auto;
  filter:invert(1); transition:filter .4s var(--ease);
}
.logo__type{
  font-size:.9375rem; font-variation-settings:'wdth' 92,'wght' 620;
  letter-spacing:.02em; color:var(--ink); white-space:nowrap;
  transition:color .4s var(--ease);
}
.logo__dot{ color:var(--gold); }

/* ── the categories menu ────────────────────────────────────────
   Phone only. A desktop has the full filter ring on the shop page and
   a header with room to spare; a phone had no route to the fifteen
   categories except going to the shop and swiping through them. */
.burger{
  display:none; width:44px; height:44px; flex:none;
  place-items:center; margin-left:-.55rem;
  color:var(--ink); transition:color .4s var(--ease);
}
.burger > span{ display:block; width:19px; }
.burger i{
  display:block; height:1.5px; background:currentColor; border-radius:2px;
  transition:transform .35s var(--ease), opacity .25s var(--ease);
}
.burger i + i{ margin-top:4.5px; }
.hdr.on-night-l .burger,
.hdr.is-stuck .burger{ color:var(--dial); }
html.menu-open .burger i:nth-child(1){ transform:translateY(6px) rotate(45deg); }
html.menu-open .burger i:nth-child(2){ opacity:0; }
html.menu-open .burger i:nth-child(3){ transform:translateY(-6px) rotate(-45deg); }

.menu__scrim{
  position:fixed; inset:0; z-index:500; background:rgba(8,10,12,.6);
  touch-action:none;                 /* or the page scrolls behind the drawer */
  opacity:0; transition:opacity .4s var(--ease);
  backdrop-filter:blur(2px); -webkit-backdrop-filter:blur(2px);
}
.menu__scrim.is-on{ opacity:1; }
.menu{
  position:fixed; z-index:501; inset:0 auto 0 0;
  width:min(86vw, 360px);
  display:flex; flex-direction:column;
  background:var(--ink-2); color:var(--dial);
  border-right:1px solid rgba(230,228,220,.12);
  transform:translateX(-101%);
  transition:transform .42s var(--ease-o);
  overscroll-behavior:contain;
}
.menu.is-on{ transform:none; }
.menu__head{
  display:flex; align-items:center; gap:1rem; flex:none;
  padding:1.05rem 1.2rem; border-bottom:1px solid rgba(230,228,220,.12);
}
.menu__t{
  flex:1; font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel);
}
.menu__x{ width:40px; height:40px; margin-right:-.5rem; font-size:1.5rem; line-height:1; color:var(--dial); }
.menu__body{ flex:1; overflow-y:auto; -webkit-overflow-scrolling:touch; padding:.4rem 0; }

.mgrp{ border-bottom:1px solid rgba(230,228,220,.08); }
.mgrp__b{
  display:flex; align-items:center; width:100%;
  padding:1rem 1.2rem; text-align:left;
  font-family:var(--serif); font-size:1.2rem;
  font-variation-settings:'opsz' 28,'wght' 340; color:var(--dial);
}
.mgrp__b i{
  margin-left:auto; width:8px; height:8px; flex:none;
  border-right:1.5px solid var(--steel); border-bottom:1.5px solid var(--steel);
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform .3s var(--ease);
}
.mgrp__b[aria-expanded="true"] i{ transform:rotate(-135deg) translate(-2px,-2px); }
.mgrp__l{ padding:0 0 .6rem; }
.mgrp__l[hidden]{ display:none; }
.mgrp__l a{
  display:block; padding:.6rem 1.2rem .6rem 1.7rem;
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.13em; text-transform:uppercase; color:#AEB6BC;
}
.mgrp__l a:active{ color:var(--acc); }

.menu__foot{
  flex:none; padding:1.1rem 1.2rem calc(1.1rem + env(safe-area-inset-bottom,0px));
  border-top:1px solid rgba(230,228,220,.12);
  display:flex; flex-direction:column; gap:.8rem;
}
.menu__all{
  display:inline-flex; align-items:center; gap:.6rem;
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--acc);
}
.menu__tel{ font-family:var(--serif); font-size:1.15rem; color:var(--dial); }

/* ── the same menu, desktop shape ───────────────────────────────
   Not a drawer: a panel that drops from under the header with all four
   groups side by side. A phone hides thirteen of the fifteen because it
   has no room; a desktop does, so hiding them would only be a step to
   click through. Sits BELOW the header in z-order, so the trigger that
   opened it is still there to close it. */
.hdr__cats{
  display:none; align-items:center; height:44px;
  font-family:var(--mono); font-size:.75rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink);
  position:relative; transition:color .4s var(--ease);
}
.hdr__cats::after{
  content:''; position:absolute; left:0; right:0; bottom:12px; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .45s var(--ease-o);
}
.hdr__cats:hover::after,
.hdr__cats[aria-expanded="true"]::after{ transform:scaleX(1); }
.hdr.on-night-r .hdr__cats,
.hdr.is-stuck .hdr__cats{ color:var(--dial); }

@media (min-width:860px){
  .hdr__cats{ display:inline-flex; }
  .menu{
    inset:0 0 auto 0; width:auto; z-index:390;
    border-right:0; border-bottom:1px solid rgba(230,228,220,.12);
    transform:translateY(-101%);
    box-shadow:0 30px 60px -40px rgba(0,0,0,.7);
  }
  .menu__scrim{ z-index:389; }
  .menu__head{ display:none; }
  .menu__body{
    display:grid; grid-template-columns:repeat(4,1fr);
    gap:clamp(1.5rem,3vw,3.5rem);
    width:100%; max-width:var(--max); margin-inline:auto;
    /* clears the fixed header the panel slides out from behind */
    padding:calc(4.6rem + 1.6rem) var(--gutter) 1.4rem;
    overflow:visible;
  }
  .mgrp{ border-bottom:0; }
  .mgrp__b{
    padding:0 0 .9rem; cursor:default; font-size:1.4rem;
    border-bottom:1px solid rgba(230,228,220,.12); margin-bottom:.7rem;
  }
  .mgrp__b i{ display:none; }
  .mgrp__l{ padding:0; }
  .mgrp__l a{ padding:.42rem 0; }
  .mgrp__l a:hover{ color:var(--acc); }
  .menu__foot{
    flex-direction:row; align-items:center; justify-content:space-between;
    width:100%; max-width:var(--max); margin-inline:auto;
    padding:1rem var(--gutter) 1.5rem;
  }
}

@media (max-width:859px){
  .burger{ display:grid; }
  .hdr__in{ gap:.65rem; }
  /* the wordmark gives way to the menu; the mark alone still says whose site this is */
  .logo__type{ display:none; }
}

/* Shop and the bag live in their own group so the header's wide gap
   sits between the logo and the pair, not between the pair. Both are
   the same fixed height so the label and the icon share a centre line. */
.hdr__end{ display:flex; align-items:center; gap:1.1rem; }

.hdr__shop{
  display:inline-flex; align-items:center; gap:.5rem; height:44px;
  font-family:var(--mono); font-size:.75rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink);
  position:relative;
  transition:color .4s var(--ease);
}
.hdr__shop span{ display:inline-block; transition:transform .4s var(--ease-o); }
.hdr__shop:hover span{ transform:translateX(4px); }
.hdr__shop::after{
  content:''; position:absolute; left:0; right:0; bottom:12px; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform .45s var(--ease-o);
}
.hdr__shop:hover::after{ transform:scaleX(1); }

.hdr__cart{
  position:relative; width:44px; height:44px; flex:none;
  display:grid; place-items:center; margin-right:-.6rem;
  color:var(--ink); transition:color .4s var(--ease);
}
.hdr__cart svg{
  width:20px; height:20px; fill:none; stroke:currentColor;
  stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
}
/* the count only exists once something is in the bag */
.hdr__count{
  position:absolute; top:6px; right:5px;
  min-width:15px; height:15px; padding:0 3px;
  border-radius:999px; background:var(--acc); color:var(--ink);
  font-family:var(--mono); font-size:.5rem; line-height:15px;
  text-align:center; opacity:0; transform:scale(.6);
  transition:opacity .3s var(--ease), transform .3s var(--ease-o);
}
.hdr__count:not([data-count="0"]){ opacity:1; transform:none; }
.hdr__count::after{ content:attr(data-count); }

/* The header is transparent for the whole hero stage. Each side turns
   its ink over at the moment the window reaches it — so the logo can be
   on cream while the nav is already over the negative. Once the stage is
   behind us the bar takes its own background and both sides go light. */
.hdr.on-night-l .logo__type,
.hdr.is-stuck .logo__type{ color:var(--dial); }

/* the badge turns over with the type it sits beside */
.hdr.on-night-l .logo__mark,
.hdr.is-stuck .logo__mark{ background:var(--dial); }
.hdr.on-night-l .logo__mark img,
.hdr.is-stuck .logo__mark img{ filter:invert(0); }

.hdr.on-night-r .hdr__shop,
.hdr.on-night-r .hdr__cart,
.hdr.is-stuck .hdr__shop,
.hdr.is-stuck .hdr__cart{ color:var(--dial); }

/* The categories panel slides out from behind the header, so the header
   is suddenly sitting on a dark ground whatever the page beneath it was
   doing. Over the cream hero it is still inked for a light background —
   which on the open panel means an invisible logo and invisible links.
   Same flip the dark bands get. MUST stay below the rules above: these
   are the same specificity, so it is source order that decides. */
html.menu-open .logo__type,
html.menu-open .hdr__shop,
html.menu-open .hdr__cart,
html.menu-open .hdr__cats,
html.menu-open .burger{ color:var(--dial); }
html.menu-open .logo__mark{ background:var(--dial); }
html.menu-open .logo__mark img{ filter:invert(0); }
/* and the bar itself, so the header reads as part of the panel */
html.menu-open .hdr{
  background:rgba(22,28,34,.92);
  backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px);
  border-bottom-color:rgba(230,228,220,.12);
}

/* ═══ The turn ═════════════════════════════════════════════════════
   The stage is two screens tall and the pin holds for the first one,
   so the handover finishes exactly as the pin releases — no dead
   scroll either side. Inside the window the negative hero resolves
   into the opening of the next page while the wordmark pans out. */
/* one screen for the turn, then ~0.85 of a screen per topic. The phone
   block cuts this to a single screen, because there the topics move out
   to a rail of their own. */
.stage{ position:relative; height:440svh; }
.pin{ position:sticky; top:0; height:100svh; overflow:hidden; }

.pane{
  position:absolute; inset:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  padding:6.5rem var(--gutter) 5.5rem;
}
.pane--night{
  background:#080A0C;
  clip-path:circle(var(--win-r, 0px) at var(--win-x, 50%) var(--win-y, 50%));
}
.pane--night .hero__dot{ color:var(--lume); }

/* Both wordmarks carry the same transform, so the letters read as one
   object whichever side of the window edge you catch them on. The mask
   needs vertical padding because line-height .8 lets the caps overflow
   their own box — without it the glyphs would clip at rest. */
.wordmask{ overflow:hidden; padding-block:.26em; margin-block:-.26em; }
/* BOTH wordmarks carry the identical transform. They are one object
   seen through a window — if only the inner copy moves, the circle
   shows letters at a different height and reads as a glitch. Both wipe
   together on scroll, and the circle closes in just behind them. */
.hero__word{
  transform:translateY(var(--word-y,0%));
  will-change:transform;
}
/* stacked lockup, both lines the same size at their natural tracking */
.wm-a,.wm-b{ display:block; }

/* the topics, stacked and cross-wiped inside the window */
.turn{ position:absolute; inset:0; }
.topic{
  position:absolute; inset:0;
  display:flex; align-items:center;
  padding:6.5rem 0 5.5rem;
  opacity:0; pointer-events:none;
  will-change:opacity;
}
.topic .formula{ width:100%; }
.pane--night .hero__meta{ opacity:var(--word-o,1); }
.pane .scroller{ opacity:var(--word-o,1); }

/* ═══ The rooms, on a rail — PHONE ONLY ════════════════════════════
   The four topics used to be stacked inside the window and cross-faded
   by vertical scroll, which cost three-and-a-bit screens of scrolling
   to see them all. They are four panels side by side now: the section
   is ONE screen you can scroll straight past, and the rest of it is
   reached sideways. Nobody is made to travel through the whole set to
   get to what is below it. */
.turnstage{ position:relative; height:100svh; background:#080A0C; }
.turnstage__pin{ position:relative; height:100svh; overflow:hidden; }
/* two layers so a palette change can cross-fade between rooms */
.turnstage__glow{
  position:absolute; inset:0; z-index:0;
  opacity:0; transition:opacity .9s var(--ease);
}
.turnstage .turn{ z-index:1; }

.turn--rail{
  display:flex; overflow-x:auto; overflow-y:hidden;
  scroll-snap-type:x mandatory; overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch; scrollbar-width:none;
}
.turn--rail::-webkit-scrollbar{ display:none; }
/* undo the absolute stacking these had while they were cross-faded */
.turn--rail .topic{
  position:relative; inset:auto;
  flex:0 0 100%; scroll-snap-align:start; scroll-snap-stop:always;
  opacity:1; pointer-events:auto; will-change:auto;
  padding:6.5rem 0 8.5rem;
}

/* The lines still wipe in — but off the panel becoming current, not off
   a scroll position. Cheaper too: a class change instead of a transform
   written to every line on every frame. */
.turn--rail .wipe > *{
  transform:translateY(115%);
  transition:transform .75s var(--ease-o);
}
.turn--rail .wipe > .rule{ transform:scaleX(0); }
.turn--rail .topic.is-live .wipe > *{ transform:none; }
.turn--rail .topic.is-live .wipe > .rule{ transform:scaleX(1); }
.turn--rail .topic .wipe:nth-child(1) > *{ transition-delay:.02s; }
.turn--rail .topic .wipe:nth-child(2) > *{ transition-delay:.07s; }
.turn--rail .topic .wipe:nth-child(3) > *{ transition-delay:.12s; }
.turn--rail .topic .wipe:nth-child(4) > *{ transition-delay:.17s; }
.turn--rail .topic .wipe:nth-child(5) > *{ transition-delay:.22s; }

/* ── where you are, and how to move ─────────────────────────────── */
.rail__nav{
  position:absolute; z-index:3; left:0; right:0; bottom:clamp(1.5rem,4vh,2.75rem);
  display:flex; align-items:center; justify-content:center; gap:1rem;
  padding-inline:var(--gutter); pointer-events:none;
}
.rail__nav > *{ pointer-events:auto; }
.rail__arrow{
  width:44px; height:44px; flex:none; border-radius:50%;
  border:1px solid rgba(230,228,220,.24); color:var(--dial);
  display:grid; place-items:center; font-size:1rem;
  transition:border-color .3s var(--ease), background .3s var(--ease);
}
.rail__arrow:hover{ border-color:var(--dial); background:rgba(230,228,220,.08); }
.rail__dots{ display:flex; align-items:center; gap:.35rem; }
.rail__dot{
  display:flex; align-items:center; gap:.5rem;
  padding:.5rem .55rem; color:rgba(230,228,220,.5);
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.16em; text-transform:uppercase;
  transition:color .35s var(--ease);
}
.rail__dot i{
  display:block; width:6px; height:6px; border-radius:50%; flex:none;
  background:currentColor; opacity:.55;
  transition:opacity .35s var(--ease), transform .35s var(--ease);
}
.rail__dot.is-on{ color:var(--dial); }
.rail__dot.is-on i{ opacity:1; transform:scale(1.45); background:var(--acc); }
/* the labels are a desktop luxury; on a phone the dots carry it alone */
@media (max-width:859px){
  .rail__dot span{ display:none; }
  .rail__dot{ padding:.55rem .3rem; }
  .rail__arrow{ display:none; }
}

.rail__hint{
  position:absolute; z-index:3; left:0; right:0; bottom:clamp(4.6rem,10vh,6.2rem);
  text-align:center; pointer-events:none;
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.2em; text-transform:uppercase;
  color:rgba(230,228,220,.34);
  transition:opacity .45s var(--ease);
}
.rail__hint.is-out{ opacity:0; }
.rail__hint i{
  font-style:normal; display:inline-block;
  animation:swipe-nudge 1.9s var(--ease) infinite;
}
.rail__hint.is-out i{ animation:none; }

/* Lands the "Scroll" cue at the END of the pin, which is where the
   rooms now begin — 100svh used to be that point, but the stage is
   no longer a fixed number of screens tall. */
/* ── pushing to the shop ────────────────────────────────────────
   The hero used to say "Scroll" and nothing else — the one screen
   everyone sees had no way to buy anything from it. */
.hero__acts{
  position:absolute; left:0; right:0; bottom:clamp(1.6rem,4.5vh,3rem);
  display:flex; flex-direction:column; align-items:center; gap:1rem;
  opacity:var(--word-o,1);
}
.hero__cta{
  display:inline-flex; align-items:center; gap:.6rem;
  padding:.85rem 1.7rem; border-radius:999px;
  background:var(--fg); color:var(--bg);
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.16em; text-transform:uppercase;
  transition:transform .4s var(--ease-o), box-shadow .4s var(--ease);
}
.hero__cta span{ transition:transform .4s var(--ease-o); }
.hero__cta:hover{ transform:translateY(-2px); box-shadow:0 10px 30px -12px rgba(0,0,0,.5); }
.hero__cta:hover span{ transform:translateX(4px); }
/* .scroller pins itself to the bottom of the pane; in here it has to
   flow under the button instead of on top of it */
.hero__acts .scroller{
  position:static; transform:none; left:auto; bottom:auto;
}

/* one per room, so the piece just described is one tap away */
.btn--room{ margin-top:1.6rem; }
.rooms__note{ max-width:52ch; margin-bottom:clamp(2rem,5vw,3rem); }
.btn--inline{ margin-left:.6rem; vertical-align:baseline; }
.cta__shop{ margin-top:1.6rem; }

@media (max-width:859px){
  /* the hero is one screen on a phone and the wordmark needs the room */
  .hero__acts{ gap:.7rem; bottom:1.4rem; }
  .hero__cta{ padding:.75rem 1.4rem; font-size:.625rem; }
  .btn--inline{ display:inline-flex; margin:.8rem 0 0; }
}

.anchor{ position:absolute; top:100svh; left:0; width:1px; height:1px; }

/* section I, composed: copy left, the piece lit on its own on the right */
.formula{ display:grid; gap:clamp(1.75rem,5vw,4.5rem); align-items:center; }
.formula .h-serif{ max-width:16ch; }

/* the wipe masks own the spacing, so the lines inside can travel freely */
.wipe{ overflow:hidden; padding-block:.18em; margin-block:-.18em; }
.wipe > *{ will-change:transform; }
.formula__copy > .wipe:nth-child(1){ margin-bottom:1.15rem; }
.formula__copy > .wipe:nth-child(2){ margin-bottom:1.5rem; }
.formula__copy > .wipe:nth-child(3){ margin-bottom:1.5rem; }
.formula__copy > .wipe:nth-child(4){ margin-bottom:1.9rem; }
.formula__copy .eyebrow{ margin-bottom:0; }
.formula__copy .rule{ display:block; transform-origin:left center; }
.formula__copy .figs{ margin-top:0; }

.figs{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:.4rem .55rem;
  margin-top:2rem;
}
.figs b{
  font-family:var(--serif); font-size:1.5rem; font-weight:400;
  font-variation-settings:'opsz' 32,'wght' 420;
  font-feature-settings:'tnum'; line-height:1; color:var(--fg);
}
.figs span{
  font-family:var(--mono); font-size:.6875rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--fg-2);
}
.figs i{ font-style:normal; color:var(--fg-2); opacity:.5; padding-inline:.5rem; }

.tags{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:.35rem .5rem;
  margin-top:0;
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.14em; text-transform:uppercase;
}
.tags span{ color:var(--acc); }
.tags i{ font-style:normal; color:var(--fg-2); opacity:.45; }

/* one hard light source, the way a piece is lit in a case.
   Sized from height so a wide column can't push it past the pin. */
/* A block box with width:auto ignores aspect-ratio and simply fills its
   column — which letterboxed the 3:4 photograph into a thin band. As a
   FLEX item the auto main size is derived from the ratio instead. */
.formula__slot{ display:flex; align-items:center; justify-content:center; }
.formula__slot .slot{
  height:min(64svh, 520px); width:auto; flex:0 0 auto;
}

/* the cooling drift inside the window */
/* WebGL mesh gradient; the CSS drift below is the fallback */
.hero__gl{
  position:absolute; inset:0; z-index:-1;
  width:100%; height:100%; display:block;
}
.pane--night.has-gl .hero__drift{ display:none; }

.hero__drift{
  position:absolute; inset:-30%; z-index:-1;
  background:
    radial-gradient(40% 44% at 22% 28%, rgba(40,118,90,.95) 0%, transparent 64%),
    radial-gradient(38% 42% at 78% 22%, rgba(34,80,120,.9) 0%, transparent 62%),
    radial-gradient(46% 48% at 64% 82%, rgba(122,92,42,.6) 0%, transparent 66%),
    radial-gradient(52% 52% at 28% 80%, rgba(22,56,74,.85) 0%, transparent 68%);
  filter:blur(14px);
  animation:drift 26s var(--ease) infinite alternate;
}
@keyframes drift{
  0%  { transform:translate3d(-4%,-3%,0) scale(1.02) rotate(0deg); }
  50% { transform:translate3d(3%,2%,0)   scale(1.14) rotate(5deg); }
  100%{ transform:translate3d(-2%,4%,0)  scale(1.08) rotate(-4deg); }
}


.hero__word{
  font-family:var(--font-wordmark);
  /* two stacked lines now, so it takes a smaller step than one word did */
  font-size:clamp(2.35rem, 13.2vw, 15.5rem);
  font-weight:900;                       /* h1 and div must match exactly */
  font-variation-settings:'wdth' 125,'wght' 900;
  letter-spacing:-.038em; line-height:.8;
  text-transform:uppercase; white-space:nowrap;
  color:var(--fg);                       /* ink on the day pane, cream on the night */
}
.hero__dot{ color:var(--lume-deep); }

.hero__meta{
  position:absolute; bottom:calc(1.5rem + env(safe-area-inset-bottom,0px));
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.14em; text-transform:uppercase; line-height:1.85;
  color:var(--fg-2);
}
.hero__meta--l{ left:var(--gutter); }
.hero__meta--r{ right:var(--gutter); text-align:right; }

.scroller{
  position:absolute; left:50%; transform:translateX(-50%);
  bottom:calc(1.5rem + env(safe-area-inset-bottom,0px));
  display:flex; flex-direction:column; align-items:center; gap:.65rem;
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.32em; text-transform:uppercase; color:var(--fg-2);
}
.scroller__tube{ width:18px; height:29px; border:1px solid var(--line); border-radius:10px; position:relative; }
.scroller__tube i{
  position:absolute; left:50%; top:6px; width:3px; height:3px;
  border-radius:50%; background:var(--acc); margin-left:-1.5px;
  animation:tube 2.1s var(--ease) infinite;
}
@keyframes tube{
  0%{ transform:translateY(0); opacity:0; }
  25%{ opacity:1; }
  75%{ transform:translateY(13px); opacity:1; }
  100%{ transform:translateY(13px); opacity:0; }
}

/* the black room slides up over the pinned hero */

/* ═══ Pointer ══════════════════════════════════════════════════════
   The window edge is the cursor; all that is left is a dot for aiming.
   `difference` makes it genuinely adaptive — it inverts whatever is
   actually behind it, so it works over the cream hero, the black rooms,
   a photograph and the shader alike. A class-based light/dark swap only
   knew about band colours and went invisible on the shop page. */
.cur__dot{
  position:fixed; left:0; top:0; z-index:950;
  width:9px; height:9px; margin:-4.5px 0 0 -4.5px;
  border-radius:50%;
  background:#fff;
  mix-blend-mode:difference;
  pointer-events:none; opacity:0;
  will-change:transform;
}
.cur__dot.is-live{ opacity:1; transition:opacity .5s var(--ease); }
.cur__dot.is-over{ transform-origin:50% 50%; }

@media (hover:hover) and (pointer:fine){
  html.has-cur, html.has-cur *{ cursor:none; }
}
@media (hover:none),(prefers-reduced-motion:reduce){
  .cur,.cur__dot{ display:none; }
}

/* ═══ Photo slots ══════════════════════════════════════════════════
   A lit case showing its accession number until a photograph is added:
   drop an <img class="slot__img"> inside the slot. */
.slot{
  position:relative; aspect-ratio:4/3;
  display:grid; place-items:center; overflow:hidden;
  border-radius:var(--r-img);
  background:
    radial-gradient(ellipse 74% 58% at 50% 34%, rgba(127,127,127,.09), transparent 72%),
    linear-gradient(180deg, transparent 62%, rgba(127,127,127,.07) 100%);
}
.slot--tall{ aspect-ratio:4/5; }

.slot--lit{
  aspect-ratio:3/4;
  background:
    radial-gradient(closest-side circle at 50% 45%,
      rgba(228,234,238,.20) 0%,
      rgba(228,234,238,.07) 44%,
      rgba(228,234,238,.02) 66%,
      transparent 78%);
}
.slot--lit .slot__no{ opacity:.16; }
.slot::before{                       /* plinth edge */
  content:''; position:absolute; left:14%; right:14%; bottom:20%;
  height:1px; background:var(--line);
}
.slot--lit::before{                    /* the glow is the plinth here */
  left:26%; right:26%; bottom:12%;
  background:radial-gradient(ellipse at center, rgba(0,0,0,.55), transparent 72%);
  height:14px; filter:blur(8px);
}
/* The photograph is a real <img>, not a background fed through a custom
   property — it loads properly, carries alt text, and there is no
   var() indirection to go wrong. */
.slot__img{
  position:absolute; inset:0; z-index:2;
  width:100%; height:100%;
  object-fit:cover; object-position:center;
  border-radius:inherit;
  transition:transform .9s var(--ease-o);
}

/* A hairline instead of the old radial vignette: once the frame has a
   rounded edge it reads as a deliberate plate, and a soft fade just
   made the corner look like a mistake. */
.slot--lit{ box-shadow:0 0 0 1px rgba(230,228,220,.09), 0 30px 60px -20px rgba(0,0,0,.7); }
.slot__no{
  position:relative;
  font-family:var(--serif); font-size:clamp(3.5rem,7vw,5.5rem);
  font-variation-settings:'opsz' 72,'wght' 300;
  font-feature-settings:'tnum'; line-height:1;
  color:var(--fg); opacity:.12; transform:translateY(-6%);
  transition:opacity .6s var(--ease), color .6s var(--ease);
}
.slot__cap{
  margin-top:.9rem;
  font-family:var(--mono); font-size:.625rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--fg-2);
}

/* ═══ I — The house lives inside the turn, above ═══════════════════ */
.btn{
  display:inline-flex; align-items:center; gap:.75rem;
  min-height:48px; padding:.8rem 1.6rem;
  border:1px solid var(--acc); color:var(--acc); border-radius:2px;
  font-family:var(--mono); font-size:.75rem;
  letter-spacing:.13em; text-transform:uppercase;
  transition:background .35s var(--ease), color .35s var(--ease);
}
.btn::after{ content:'→'; transition:transform .4s var(--ease-o); }
.btn:hover{ background:var(--acc); color:var(--bg); }
.btn:hover::after{ transform:translateX(4px); }

/* ═══ V — Featured ═════════════════════════════════════════════════ */
.feats{
  display:grid; gap:1rem;
  max-width:1120px; margin-inline:auto;   /* smaller than the full measure */
}
/* `display:flex` on the class outranks the UA's `[hidden]{display:none}`,
   so a filtered-out card stayed in the grid — invisible but still
   holding its cell, which is what pushed everything down. */
.feat[hidden]{ display:none; }
.feat{
  position:relative; isolation:isolate; overflow:hidden;
  display:flex; flex-direction:column;
  border:1px solid var(--line); border-radius:var(--r-img);
  padding:clamp(.8rem,1.4vw,1.05rem);
}
/* everything the reader needs sits above both gradient layers */
.feat > *{ position:relative; z-index:1; }

/* Each card gets its own set. Saturated but LIGHT-keyed, so the card
   stays pale and the ink keeps its contrast — a dark vibrant wash would
   look great and be unreadable. */
/* Keyed to the kind of product, so a card's colour means something and
   survives filtering — position-based cycling shifted every time the
   grid changed. */
.feat{ --g1:#2FA37B; --g2:#1FB6A6; --g3:#2E7FA8; --g4:#7FE3C0; }
.feat[data-cat="Timepieces"]{ --g1:#1E4E74; --g2:#2E7FA8; --g3:#4CB5D1; --g4:#9BD9E0; }
.feat[data-cat="Leather"]   { --g1:#8A4E1E; --g2:#C97B2E; --g3:#E0A93B; --g4:#EBC77A; }
.feat[data-cat="Evening"]   { --g1:#8E1F3E; --g2:#C0395F; --g3:#E0596F; --g4:#E8A9B8; }
.feat[data-cat="Footwear"]  { --g1:#4C3F84; --g2:#6D5BA8; --g3:#9A5FA8; --g4:#B49BE0; }

/* Colour wash + film grain, drifting together, BEHIND the content.
   Paused until hover so three cards are not animating off screen. */
.feat::after{
  content:''; position:absolute; inset:-25%; z-index:0;
  pointer-events:none; opacity:0;
  background-image:
    radial-gradient(38% 42% at 20% 24%, var(--g1), transparent 62%),
    radial-gradient(36% 40% at 80% 18%, var(--g2), transparent 60%),
    radial-gradient(44% 48% at 72% 82%, var(--g3), transparent 64%),
    radial-gradient(46% 50% at 26% 78%, var(--g4), transparent 66%);
  background-size:auto, auto, auto, auto;
  filter:blur(30px) saturate(1.15);
  transition:opacity .55s var(--ease);
  animation:cardDrift 13s ease-in-out infinite alternate;
  animation-play-state:paused;
}
.feat:hover::after{ opacity:.5; animation-play-state:running; }
/* The grain sits on its own STILL layer. On the drifting layer it
   inherited the transform and crawled; it should be a fixed texture the
   colour moves underneath. */
.feat__grain{
  position:absolute; inset:0; z-index:1; pointer-events:none;
  border-radius:inherit;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.45' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:220px 220px;
  mix-blend-mode:overlay;
  opacity:0; transition:opacity .55s var(--ease);
}
.feat:hover .feat__grain{ opacity:.34; }

@keyframes cardDrift{
  0%  { transform:translate3d(-5%,-4%,0) scale(1.04) rotate(0deg); }
  100%{ transform:translate3d(5%,4%,0)  scale(1.16) rotate(7deg); }
}

/* The wash lifts the background, which eats into the contrast of the
   muted copy — so it darkens to compensate rather than staying put. */
.feat__sub,.feat__desc,.feat__fine,.feat__alt{ transition:color .5s var(--ease); }
.feat:hover .feat__sub,
.feat:hover .feat__desc,
.feat:hover .feat__fine,
.feat:hover .feat__alt{ color:#23292E; }

/* the saturated half of the effect goes on the border, where it can be
   full strength without touching legibility */
.feat::before{
  content:''; position:absolute; inset:0; z-index:0;
  border-radius:inherit; padding:1px; pointer-events:none; opacity:0;
  background:conic-gradient(from 0deg,
    var(--g1), var(--g2), var(--g3), var(--g4), var(--g1));
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
  mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite:exclude;
  transition:opacity .5s var(--ease);
  animation:ringHue 7s linear infinite;
  animation-play-state:paused;
}
.feat:hover::before{ opacity:1; animation-play-state:running; }
@keyframes ringHue{ to{ filter:hue-rotate(360deg); } }

.feat__shot{
  aspect-ratio:1/1; overflow:hidden; border-radius:calc(var(--r-img) - 4px);
  background:var(--ink); margin-bottom:1rem;
}
.feat__shot img{
  width:100%; height:100%; object-fit:cover;
  transform-origin:center;
  transition:transform .9s var(--ease-o);
}
.feat:hover .feat__shot img{ transform:scale(1.28); }
a.feat__shot{ display:block; }

.feat__name{ display:flex; align-items:baseline; gap:.45rem; flex-wrap:wrap; }
.feat__name b{
  font-family:var(--sans); font-size:.8125rem;
  font-variation-settings:'wdth' 108,'wght' 750;
}
.feat__name span{
  font-family:var(--serif); font-size:1.15rem;
  font-variation-settings:'opsz' 26,'wght' 350; line-height:1;
}
.feat__sub{
  font-family:var(--mono); font-size:.5625rem; letter-spacing:.15em;
  text-transform:uppercase; color:var(--fg-2); margin-top:.45rem;
}
.feat__desc{
  color:var(--fg-2); font-size:.8125rem; line-height:1.55; margin-top:.7rem;
}

.feat__opts{ display:flex; flex-wrap:wrap; gap:.4rem; margin-top:.95rem; }
.pill{
  min-height:32px; padding:.3rem .8rem;
  border:1px solid var(--line); border-radius:999px;
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--fg-2);
  transition:border-color .3s var(--ease), color .3s var(--ease),
             background .3s var(--ease);
}
.pill:hover{ border-color:var(--fg); color:var(--fg); }
.pill.is-on{ background:var(--fg); border-color:var(--fg); color:var(--bg); }

.feat__price{ margin-top:1rem; }
.feat__price b{
  font-family:var(--serif); font-size:1.25rem; font-weight:400;
  font-variation-settings:'opsz' 28,'wght' 400;
  font-feature-settings:'tnum';
}
.feat__price i{
  font-style:normal; font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.14em; color:var(--fg-2); margin-left:.4rem;
}
.feat__fine{
  font-family:var(--serif); font-style:italic; font-size:.78125rem;
  color:var(--fg-2); margin-top:.2rem;
}

.feat__cta{
  display:block; text-align:center; margin-top:auto;
  padding:.8rem 1rem; border-radius:2px;
  background:var(--fg); color:var(--bg);
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.16em; text-transform:uppercase;
  transition:opacity .3s var(--ease);
}
.feat__cta{ margin-top:1.1rem; }
.feat__cta:hover{ opacity:.85; }
.feat__alt{
  align-self:center; margin-top:.65rem; padding:.35rem 0;
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--fg-2);
  transition:color .3s var(--ease);
}
.feat__alt:hover{ color:var(--acc); }
.feat__alt span{ display:inline-block; transition:transform .4s var(--ease-o); }
.feat__alt:hover span{ transform:translateX(3px); }

@media (hover:none){
  .feat::before,.feat::after{ display:none; }
}

/* ═══ IV — Rooftops ════════════════════════════════════════════════ */
.rooms{ border-top:1px solid var(--line); }
.room{
  position:relative;
  display:grid; grid-template-columns:auto 1fr; gap:.35rem 1.5rem;
  padding:clamp(1.5rem,4vw,2.4rem) 0;
  border-bottom:1px solid var(--line);
}
.room::before{
  content:''; position:absolute; left:calc(var(--gutter) * -1); right:calc(var(--gutter) * -1);
  top:0; bottom:0; z-index:0;
  background:linear-gradient(90deg, rgba(30,92,70,.07), transparent 62%);
  opacity:0; transition:opacity .55s var(--ease);
}
.room:hover::before{ opacity:1; }
.room > *{ position:relative; z-index:1; }
.room__n{
  grid-row:1 / span 3;
  font-family:var(--mono); font-size:.75rem; letter-spacing:.1em;
  color:var(--acc); padding-top:.55rem;
}
.room__t{
  font-family:var(--serif); font-size:clamp(1.85rem,6.5vw,3.1rem);
  font-variation-settings:'opsz' 44,'wght' 330;
  line-height:1.02; letter-spacing:-.02em;
}
.room__d{ color:var(--fg-2); max-width:40ch; font-size:.9375rem; }
.room__a{
  justify-self:start; margin-top:.5rem;
  font-family:var(--mono); font-size:.6875rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--acc);
  padding:.45rem 0; border-bottom:1px solid currentColor;
}

.marq{
  margin-top:clamp(3.5rem,8vw,6rem);
  border-block:1px solid var(--line);
  padding-block:clamp(1.25rem,3vw,2rem);
  overflow:hidden;
}
.marq__row{ display:flex; width:max-content; animation:slide 42s linear infinite; }
.marq__row--ghost{ animation-duration:56s; animation-direction:reverse; margin-top:.35rem; opacity:.22; }
.marq__set{
  display:flex; align-items:center; gap:1.5rem; padding-right:1.5rem;
  font-family:var(--serif); font-size:clamp(1.9rem,6vw,3.4rem);
  font-variation-settings:'opsz' 48,'wght' 300;
  white-space:nowrap;
}
.marq__set i{ font-style:normal; color:var(--gold); }
@keyframes slide{ to{ transform:translateX(-50%); } }

/* ═══ V — The counter ══════════════════════════════════════════════ */
.svcs{ display:grid; gap:1px; background:var(--line); border-block:1px solid var(--line); }
.svc{ background:var(--bg); padding:clamp(1.5rem,4vw,2.25rem); }
.svc h3{
  font-family:var(--sans); font-size:1rem;
  font-variation-settings:'wdth' 96,'wght' 600;
  margin-bottom:.55rem;
}
.svc p{ color:var(--fg-2); font-size:.9375rem; max-width:34ch; }

.cta{
  margin-top:clamp(3.5rem,8vw,6rem); text-align:center;
  padding:clamp(2.5rem,7vw,4.5rem) var(--gutter);
  border:1px solid var(--line); border-radius:3px;
}
.cta__k{
  font-family:var(--mono); font-size:.6875rem; letter-spacing:.2em;
  text-transform:uppercase; color:var(--fg-2);
}
.cta__num{
  display:inline-block; margin:1rem 0 .9rem;
  font-family:var(--serif);
  font-size:clamp(2.35rem,9.5vw,5rem);
  font-variation-settings:'opsz' 72,'wght' 330;
  letter-spacing:-.02em; line-height:1; font-feature-settings:'tnum';
  background-image:linear-gradient(currentColor,currentColor);
  background-size:0% 1px; background-repeat:no-repeat; background-position:0 100%;
  transition:background-size .6s var(--ease-o);
}
.cta__num:hover{ background-size:100% 1px; }
.cta__s{ color:var(--fg-2); font-size:.875rem; max-width:34ch; margin-inline:auto; }

/* ═══ Footer ═══════════════════════════════════════════════════════ */
.foot{ padding-top:clamp(3.5rem,8vw,6rem); }
.foot__in{ display:grid; gap:2.75rem; padding-bottom:clamp(2.5rem,6vw,4.5rem); }
/* The footer is the one place with room for the real artwork — big enough
   that the "Watch Museum" set inside the diamonds actually reads. The file
   is drawn in ink for the light pages, so invert it against the dark foot. */
.logo__img--lg{
  display:block; width:auto; height:clamp(86px, 13vw, 118px);
  margin-bottom:1.25rem; filter:invert(1);
}
.foot__tag{
  font-family:var(--serif); font-size:1.35rem;
  font-variation-settings:'opsz' 30,'wght' 330; line-height:1.28;
}
.foot__est{
  font-family:var(--mono); font-size:.625rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--steel); margin-top:.9rem;
}
.foot__col h4{
  font-family:var(--mono); font-size:.625rem; font-weight:400;
  letter-spacing:.2em; text-transform:uppercase; color:var(--steel);
  margin-bottom:1.1rem;
}
.foot__col li{ padding:.3rem 0; color:rgba(230,228,220,.82); font-size:.9375rem; }
.foot__col a{ transition:color .3s var(--ease); }
.foot__col a:hover{ color:var(--lume); }
.foot__num{
  display:block; font-family:var(--serif); font-size:1.9rem;
  font-variation-settings:'opsz' 36,'wght' 340;
  font-feature-settings:'tnum'; letter-spacing:-.01em;
  color:var(--lume); margin-bottom:.9rem;
}
.foot__fb{
  display:inline-block; font-family:var(--mono); font-size:.75rem;
  letter-spacing:.1em; text-transform:uppercase;
  border-bottom:1px solid rgba(230,228,220,.25); padding-bottom:.3rem;
  transition:border-color .3s var(--ease), color .3s var(--ease);
}
.foot__fb:hover{ color:var(--lume); border-color:var(--lume); }
.foot__hrs{ margin-top:1.1rem; color:var(--steel); font-size:.8125rem; }

.foot__base{
  display:flex; flex-wrap:wrap; gap:.75rem 2rem; align-items:center;
  padding-block:1.5rem calc(1.5rem + env(safe-area-inset-bottom,0px));
  border-top:1px solid rgba(230,228,220,.12);
  font-family:var(--mono); font-size:.625rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--steel);
}
.foot__live{ font-feature-settings:'tnum'; }
#footClock{ color:var(--lume); margin-left:.5em; }
.foot__top{ margin-left:auto; transition:color .3s var(--ease); }
.foot__top:hover{ color:var(--lume); }

/* ═══ Reveal ═══════════════════════════════════════════════════════ */
.reveal{
  opacity:0; transform:translateY(22px);
  transition:opacity .95s var(--ease-o), transform .95s var(--ease-o);
}
.reveal.is-in{ opacity:1; transform:none; }
.feats .reveal:nth-child(2),.svcs .reveal:nth-child(2),.rooms .reveal:nth-child(2){ transition-delay:.07s; }
.feats .reveal:nth-child(3),.svcs .reveal:nth-child(3),.rooms .reveal:nth-child(3){ transition-delay:.14s; }
.feats .reveal:nth-child(4),.svcs .reveal:nth-child(4),.rooms .reveal:nth-child(4){ transition-delay:.21s; }

/* ═══════════════════════════════════════════════════════════════════
   Breakpoints
   ═══════════════════════════════════════════════════════════════════ */
@media (min-width:560px){
  .svcs{ grid-template-columns:1fr 1fr; }
  .feats{ grid-template-columns:1fr 1fr; }
  .room{ grid-template-columns:auto 1fr auto; align-items:center; }
  .room__n{ grid-row:1 / span 2; padding-top:0; }
  .room__a{ grid-row:1 / span 2; grid-column:3; justify-self:end; margin:0; }
}

@media (min-width:860px){
  .hdr__in{ padding-block:1.1rem; }

  .formula{ grid-template-columns:1.05fr 1fr; }

  .sec__head{ display:grid; grid-template-columns:1fr auto; align-items:end; }
  .sec__head .eyebrow,
  .sec__head .h-serif,
  .sec__head .sec__note{ grid-column:1; }


  .cases{ grid-template-columns:repeat(4,1fr); }
  .svcs{ grid-template-columns:repeat(4,1fr); }
  .feats{ grid-template-columns:repeat(3,1fr); gap:1.25rem; }

  .foot__in{ grid-template-columns:1.6fr 1fr 1fr 1.4fr; gap:3rem; }
}

@media (max-width:859px){
  /* The piece belongs in the turn on a phone too — it just goes above
     the copy and takes a third of the screen, and the pane gives back
     some padding so the whole thing still lands in one view. */
  /* The window does not open on a phone. The hero is one screen you
     scroll off, so the stage holds exactly one screen and the pin has
     nothing left to pin — it stays positioned only so the two panes
     still lay themselves out against it. `dvh` rather than `svh`: the
     pane must reach the bottom whether or not the browser bar is
     showing, and the stage no longer drives a scroll length that would
     shift as the bar comes and goes. */
  .stage{ height:100dvh; background:var(--dial); }
  .pin{ position:relative; height:100dvh; }

  .turnstage__pin{ height:100dvh; }
  .anchor{ top:100%; }

  /* A fixed, full-viewport overlay forces the whole page into one
     composited layer that repaints as the clip-path animates beneath
     it. On a phone that is a real cost for a texture nobody can see at
     that size. */
  .grain{ display:none; }

  /* promote the clipped pane so its repaints stay on the GPU */
  .pane--night{ will-change:clip-path; }
  .pane{ padding:4.75rem var(--gutter) 3.5rem; }

  .formula{ grid-template-columns:1fr; gap:1rem; }
  .formula__slot{ display:flex; order:-1; }
  .formula__slot .slot{ height:min(27svh, 230px); }
  /* .turn is inset:0 of the pane's PADDING box, so it is already inset
     once — a second padding here was stacking on top of it and pushing
     the headline out through the top of the pin. */
  .topic{ padding:4.5rem 0 7rem; }

  .turn .h-serif{ font-size:clamp(1.65rem,6.6vw,2.2rem); }
  .turn .lede{ font-size:.875rem; line-height:1.5; }
  .formula__copy > .wipe:nth-child(1){ margin-bottom:.8rem; }
  .formula__copy > .wipe:nth-child(2){ margin-bottom:1rem; }
  .formula__copy > .wipe:nth-child(3){ margin-bottom:1rem; }
  .formula__copy > .wipe:nth-child(4){ margin-bottom:1.15rem; }
}

@media (hover:none){
  .case:hover .slot__no{ opacity:.12; color:var(--fg); }
  .case:hover .slot__img{ transform:none; }
  .room:hover::before{ opacity:0; }
  .btn:hover{ background:none; color:var(--acc); }

  /* touch targets: nothing smaller than 44px */
  .room__a{ padding:.85rem 0; }
  .foot__col li{ padding:.5rem 0; }
  .foot__fb{ padding:.7rem 0; }
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
  }
  .reveal{ opacity:1; transform:none; }
  /* no pin, no turn: the hero is one screen and the next page follows */
  .stage{ height:100svh; }
  .pin{ position:static; }
  .pane--night{ display:none; }
  .hero__word{ transform:none; opacity:1; }
}


/* ═══ Bag ══════════════════════════════════════════════════════════ */
/* Still catches the click that closes the bag, but does not dim the
   page behind it. */
.bag__scrim{
  position:fixed; inset:0; z-index:490;
  background:transparent;
}
.bag__scrim.is-on{ opacity:1; }

.bag{
  position:fixed; top:0; right:0; bottom:0; z-index:500;
  width:min(430px, 100%);
  overflow:hidden; isolation:isolate;
  background:var(--dial); color:var(--ink);
  /* muted copy is darkened from --steel-d: the colour wash lifts the
     ground enough that the usual value drops under 3.5:1 */
  --fg:var(--ink); --fg-2:#333B42; --acc:var(--lume-deep);
  --line:rgba(15,19,23,.16);
  transform:translateX(100%);
  transition:transform .72s var(--ease-o);
}
.bag.is-on{ transform:none; }

/* rainbow, dark-keyed so cream text still reads, drifting and
   hue-cycling, with the same coarse grain overlaid */
.bag__bg{
  position:absolute; inset:-45%; z-index:0; pointer-events:none;
  opacity:.55;
  background-image:
    radial-gradient(38% 32% at 18% 12%, #FF6B8A, transparent 62%),
    radial-gradient(36% 30% at 82% 20%, #FFB24F, transparent 60%),
    radial-gradient(40% 34% at 72% 48%, #4FD1A5, transparent 62%),
    radial-gradient(38% 32% at 22% 60%, #5AA9F0, transparent 62%),
    radial-gradient(42% 36% at 58% 88%, #B98BF0, transparent 64%);
  background-size:auto, auto, auto, auto, auto;
  filter:blur(60px) saturate(1.2);
  animation:bagDrift 19s ease-in-out infinite alternate,
            bagHue 26s linear infinite;
}
.bag::after{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.65' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:180px 180px;
  mix-blend-mode:overlay; opacity:.17;
}
@keyframes bagDrift{
  0%  { transform:translate3d(-4%,-3%,0) scale(1.05) rotate(0deg); }
  100%{ transform:translate3d(4%,4%,0)  scale(1.18) rotate(8deg); }
}
@keyframes bagHue{
  from{ filter:blur(60px) saturate(1.2) hue-rotate(0deg); }
  to  { filter:blur(60px) saturate(1.2) hue-rotate(360deg); }
}

.bag__in{
  position:relative; z-index:1;
  height:100%; display:flex; flex-direction:column;
  padding:1.5rem var(--gutter) calc(1.5rem + env(safe-area-inset-bottom,0px));
  padding-inline:clamp(1.25rem,4vw,2rem);
}
.bag__top{ display:flex; align-items:center; justify-content:space-between; }
.bag__title{
  font-family:var(--serif); font-size:1.75rem;
  font-variation-settings:'opsz' 34,'wght' 340;
}
.bag__x{
  width:44px; height:44px; margin-right:-.6rem;
  display:grid; place-items:center; color:var(--ink);
  transition:color .3s var(--ease);
}
.bag__x svg{ width:18px; fill:none; stroke:currentColor; stroke-width:1.5; stroke-linecap:round; }
.bag__x:hover{ color:var(--lume-deep); }

.bag__empty{
  margin-top:2rem; color:var(--fg-2); font-size:.9375rem; max-width:30ch;
}
.bag__list{ margin-top:1.75rem; overflow-y:auto; flex:1; }
.bag__row{
  display:grid; grid-template-columns:56px 1fr auto; gap:.9rem;
  align-items:center; padding:.9rem 0;
  border-bottom:1px solid var(--line);
}
.bag__row img{
  width:56px; height:56px; object-fit:cover;
  border-radius:6px; background:var(--ink);
}
.bag__nm{ font-family:var(--serif); font-size:1.0625rem; line-height:1.2; }
.bag__op{
  font-family:var(--mono); font-size:.5625rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--fg-2); margin-top:.3rem;
}
.bag__rm{
  width:34px; height:34px; display:grid; place-items:center;
  color:var(--fg-2); font-family:var(--mono); font-size:.875rem;
  border:1px solid var(--line); border-radius:50%;
  transition:color .3s var(--ease), border-color .3s var(--ease);
}
.bag__rm:hover{ color:var(--lume-deep); border-color:var(--lume-deep); }

.bag__foot{
  margin-top:auto; padding-top:1.5rem;
  /* the panel clips; without a scroller of its own the form below the
     fold could not be reached at all */
  flex:0 1 auto; min-height:0;
  overflow-y:auto; overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
/* While the order form is open the form is the task, so the item list
   gives up its share of the panel instead of pushing the form out. */
.bag.is-checkout .bag__list{ flex:0 1 auto; max-height:24vh; }
.bag.is-checkout .bag__foot{ flex:1 1 auto; }
.bag__sum{
  display:flex; justify-content:space-between; align-items:baseline;
  padding-bottom:1rem; border-bottom:1px solid var(--line);
}
.bag__sum span{
  font-family:var(--mono); font-size:.625rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--fg-2);
}
.bag__sum b{
  font-family:var(--serif); font-size:1.5rem; font-weight:400;
  font-feature-settings:'tnum';
}
.bag__fine{
  font-family:var(--serif); font-style:italic; font-size:.875rem;
  color:var(--fg-2); margin:1rem 0 1.1rem;
}
.bag__cta{
  display:block; text-align:center; padding:1.05rem 1rem; border-radius:2px;
  background:var(--ink); color:var(--dial);
  font-family:var(--mono); font-size:.75rem;
  letter-spacing:.16em; text-transform:uppercase;
  transition:opacity .3s var(--ease);
}
.bag__cta:hover{ opacity:.86; }
.bag__alt{
  display:block; text-align:center; margin-top:.9rem; padding:.5rem 0;
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--fg-2);
  transition:color .3s var(--ease);
}
.bag__alt:hover{ color:var(--lume-deep); }

@media (prefers-reduced-motion:reduce){
  .bag__bg{ animation:none; }
}


/* ═══ Shop page ════════════════════════════════════════════════════ */
.shop{ background:var(--ink); }
.shopbg{
  position:fixed; inset:0; z-index:0;
  width:100%; height:100%; display:block;
  pointer-events:none;
}
/* if WebGL is missing the page still needs a ground, not a black void */
.no-shader .shopbg{
  background:
    radial-gradient(60% 50% at 20% 15%, #123329, transparent 65%),
    radial-gradient(55% 45% at 80% 30%, #15364B, transparent 62%),
    radial-gradient(65% 55% at 55% 90%, #1E5C46, transparent 66%),
    var(--ink);
}
.shop main{ position:relative; z-index:1; }

/* Centred and compact, so the grid starts near the top of the page. */
.shop__head{
  padding:calc(5rem + 1.5vw) 0 clamp(1.5rem,3vw,2.25rem);
  text-align:center; color:var(--dial);
  --fg:var(--dial); --fg-2:#B9C0C6; --acc:var(--lume);
  --line:rgba(230,228,220,.2);
}
.shop__head .eyebrow{ justify-content:center; margin-bottom:.7rem; }
.shop__head .h-serif{
  font-size:clamp(1.85rem, 3.6vw, 3.1rem);
  max-width:20ch; margin-inline:auto;
}
.shop__head .sec__note{
  color:var(--fg-2); font-size:.875rem;
  max-width:46ch; margin:.75rem auto 0;
}

/* the filters keep their size — they are the control, not the caption */
/* ── who you are shopping for ───────────────────────────────────
   A ring of three: the one before, the one you are in, the one after.
   It wraps, so the last group sits to the left of the first and there
   is no end to walk into. Move it by tapping either faint side, by
   swiping anywhere on the page, or with the arrow keys. */
.tops{
  display:flex; align-items:baseline; justify-content:center;
  gap:clamp(1rem,5vw,3rem); margin-top:2rem;
  overflow:hidden;
}
.top{
  font-family:var(--serif); line-height:1.1; white-space:nowrap;
  transition:color .4s var(--ease);
}
.top--now{
  flex:0 0 auto;
  font-size:clamp(1.75rem, 6vw, 2.6rem);
  font-variation-settings:'opsz' 40,'wght' 340;
  color:var(--dial);
}
.top--side{
  flex:1 1 0; min-width:0; overflow:hidden;
  font-size:clamp(1rem, 3.4vw, 1.5rem);
  font-variation-settings:'opsz' 30,'wght' 300;
  color:rgba(230,228,220,.3);
}
.top--side:first-child{ text-align:right; }
.top--side:last-child{ text-align:left; }
.top--side:hover{ color:rgba(230,228,220,.62); }
.shop--light .top--now{ color:var(--ink); }
.shop--light .top--side{ color:rgba(15,19,23,.3); }
.shop--light .top--side:hover{ color:rgba(15,19,23,.6); }

/* the labels slide the way the ring turned, so the movement reads as a
   direction rather than a swap */
.tops span{ display:inline-block; }
.tops.slide-l span{ animation:ring-l .42s var(--ease-o) both; }
.tops.slide-r span{ animation:ring-r .42s var(--ease-o) both; }
@keyframes ring-l{ from{ transform:translateX(28%); opacity:0 } to{ transform:none; opacity:1 } }
@keyframes ring-r{ from{ transform:translateX(-28%); opacity:0 } to{ transform:none; opacity:1 } }

.filts{
  display:flex; flex-wrap:wrap; gap:.5rem;
  justify-content:center; margin-top:1.1rem;
}
.filt{
  min-height:38px; padding:.45rem 1.1rem;
  border:1px solid rgba(230,228,220,.28); border-radius:999px;
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.13em; text-transform:uppercase; color:#D6DBDF;
  transition:background .3s var(--ease), color .3s var(--ease),
             border-color .3s var(--ease);
}
.filt:hover{ border-color:var(--dial); color:var(--dial); }
.filt.is-on{ background:var(--dial); border-color:var(--dial); color:var(--ink); }

/* A nudge that the row keeps going — there is no scrollbar to say so.
   shop.js drives it live: shown while the strip sits at its start and
   genuinely overflows, gone once it is swiped, back again on return to
   the beginning. Only the opacity moves, so the element holds its space
   and the grid below never jumps. Phone only: on a desktop the chips
   simply wrap and there is nothing to swipe.

   This base rule MUST stay above the phone media query below. Both are
   a single class, so specificity ties and source order decides — with
   it underneath, display:none won at every width and the hint never
   appeared at all. */
.filts__hint{
  display:none; margin-top:.6rem; text-align:center;
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.2em; text-transform:uppercase;
  color:rgba(230,228,220,.32);
  transition:opacity .45s var(--ease), transform .45s var(--ease);
}
.filts__hint.is-out{ opacity:0; transform:translateY(-4px); pointer-events:none; }
/* nothing to see, so stop the arrow rather than animate it invisibly */
.filts__hint.is-out i{ animation:none; }
.filts__hint i{
  font-style:normal; display:inline-block;
  animation:swipe-nudge 1.9s var(--ease) infinite;
}
@keyframes swipe-nudge{
  0%,100%{ transform:translateX(0); opacity:.55; }
  50%    { transform:translateX(5px); opacity:1; }
}

/* Sixteen chips wrap to four or five rows on a phone, which pushes the
   grid off the screen entirely. There they become one strip you swipe
   instead — the selected chip is scrolled back into the middle by
   shop.js so the row never loses its place. */
@media (max-width:859px){
  .filts{
    flex-wrap:nowrap; justify-content:flex-start;
    overflow-x:auto; overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    scroll-snap-type:x proximity;
    /* bleed to the screen edges so the strip reads as scrollable */
    margin-inline:calc(var(--gutter) * -1);
    padding-inline:var(--gutter); padding-bottom:.35rem;
    scrollbar-width:none;
  }
  .filts::-webkit-scrollbar{ display:none; }
  .filt{ flex:none; scroll-snap-align:center; }
  .filts__hint{ display:block; }
}

/* beats the phone rule's display:block once the hint has been dismissed */
.filts__hint[hidden]{ display:none; }

/* ── the request form in the bag ────────────────────────────────── */
.bag__form{ margin-top:1rem; }
.bag__form label:not(.pick){
  display:block; margin-bottom:.7rem;
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.16em; text-transform:uppercase; color:var(--fg-2);
}
.bag__form .opt{ text-transform:none; letter-spacing:0; opacity:.7; }
.bag__form input,.bag__form textarea{
  display:block; width:100%; margin-top:.35rem; padding:.7rem .8rem;
  border:1px solid var(--line); border-radius:9px;
  background:rgba(0,0,0,.25); color:var(--fg);
  font:inherit; font-size:.9375rem; letter-spacing:normal; text-transform:none;
}
.bag__form input:focus,.bag__form textarea:focus{
  outline:2px solid var(--acc); outline-offset:1px;
}
.bag__form .bag__cta{ margin-top:.4rem; }
.bag__pick{ border:0; padding:0; margin:0 0 1.1rem; }
.bag__pick legend{
  padding:0; margin-bottom:.5rem; display:block;
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.16em; text-transform:uppercase; color:var(--fg-2);
}
.pick{
  display:flex; align-items:center; gap:.65rem;
  padding:.6rem .8rem; margin-bottom:.4rem;
  border:1px solid var(--line); border-radius:9px;
  font-size:.9375rem; cursor:pointer;
  transition:border-color .3s var(--ease), background .3s var(--ease);
}
.pick span{ flex:1; }
.pick b{ font-weight:500; color:var(--fg-2); font-size:.875rem; }
.bag__form .pick input{
  display:inline-block; width:auto; margin:0; flex:none;
  accent-color:var(--acc); min-width:16px;
}
.pick:has(input:checked){ border-color:var(--acc); background:rgba(159,217,190,.07); }
/* what is not built yet must not look like a choice you can make */
.pick.is-soon{ opacity:.42; cursor:not-allowed; }
.pick.is-soon b{
  font-family:var(--mono); font-size:.5625rem;
  letter-spacing:.14em; text-transform:uppercase; color:var(--acc);
}

.bag__tot{ margin:1.1rem 0 .6rem; }
.bag__tot > div{
  display:flex; align-items:baseline; gap:.75rem;
  padding:.3rem 0; font-size:.9375rem;
}
.bag__tot dt{ color:var(--fg-2); }
.bag__tot dd{ margin:0 0 0 auto; font-variant-numeric:tabular-nums; }
.bag__tot .grand{
  margin-top:.35rem; padding-top:.6rem; border-top:1px solid var(--line);
  font-size:1.0625rem;
}
.bag__tot .grand dt{ color:var(--fg); }
.bag__tot .grand dd{ font-weight:600; }
.bag__ask{
  margin:.2rem 0 .8rem; color:var(--fg-2);
  font-size:.8125rem; line-height:1.45;
}

.bag__err{
  margin:.2rem 0 .6rem; color:#8E1F2B; font-size:.85rem;
}
/* These two took the ADMIN's colours, which are built for a dark panel.
   The bag is cream with a pastel wash behind it, so pale mint on pale
   green came out at 1.05:1 — the confirmation was invisible. Dark ink
   on a light tint instead: 6.5:1 or better on every colour the wash
   passes through. */
.bag__done{
  margin-top:1rem; padding:.85rem 1rem; border-radius:9px;
  background:rgba(30,92,70,.12); border:1px solid rgba(30,92,70,.34);
  color:#123D2C; font-size:.9rem;
}

.shop__grid{ padding-bottom:var(--vspace); }
.shop__grid .feats{ max-width:1180px; }
/* The cards sit on the shader, so they carry their own cream ground —
   plain at rest, and only on hover do they pick up the wash, grain and
   ring they have on the main page. */
.shop .feat{
  background:var(--dial); color:var(--ink);
  /* --bg matters as much as --fg here: the solid button and the selected
     pill paint their label with var(--bg), and without it the value fell
     through to :root (ink) — ink text on an ink fill. */
  --bg:var(--dial); --fg:var(--ink); --fg-2:var(--steel-d); --acc:var(--lume-deep);
  --line:rgba(15,19,23,.15);
  border-color:rgba(15,19,23,.12);
  box-shadow:0 20px 50px -24px rgba(0,0,0,.7);
}
/* shown while the catalogue is on its way, then removed */
.shop__load{
  margin-top:3rem; text-align:center; color:#8B959C;
  font-family:var(--serif); font-style:italic; font-size:1.05rem;
}
.shop--light .shop__load{ color:var(--steel-d); }
.shop__none{
  margin-top:3rem; text-align:center; color:#B9C0C6;
  font-family:var(--serif); font-style:italic; font-size:1.05rem;
}
.shop .foot{ position:relative; z-index:1; }


/* ═══ Product page ═════════════════════════════════════════════════ */
.pdp__wrap{ padding-top:calc(6rem + 2vw); padding-bottom:var(--vspace); }
.pdp__back{
  display:inline-block; margin-bottom:2rem; padding:.5rem 0;
  font-family:var(--mono); font-size:.6875rem;
  letter-spacing:.14em; text-transform:uppercase; color:#C3C9CE;
  transition:color .3s var(--ease);
}
.pdp__back:hover{ color:var(--lume); }
.pdp__back span{ display:inline-block; transition:transform .4s var(--ease-o); }
.pdp__back:hover span{ transform:translateX(-4px); }

/* Both columns share the row height — the image is not an aspect box,
   it fills whatever the pair settles on and crops with object-fit. */
.pdp{ display:grid; gap:clamp(1.5rem,4vw,3rem); align-items:stretch; }

.pdp__shot{
  position:relative; overflow:hidden;
  min-height:clamp(380px, 62vh, 660px);
  border-radius:var(--r-img);
  background:var(--ink);
  box-shadow:0 30px 70px -28px rgba(0,0,0,.8);
}
.pdp__shot img{
  width:100%; height:100%; object-fit:cover;
  transform-origin:center;
  transition:transform 1s var(--ease-o);
}
.pdp__shot:hover img{ transform:scale(1.9); }

.pdp__body{
  display:flex; flex-direction:column;
  background:var(--dial); color:var(--ink);
  --bg:var(--dial); --fg:var(--ink); --fg-2:var(--steel-d);
  --acc:var(--lume-deep); --line:rgba(15,19,23,.15);
  border-radius:var(--r-img);
  padding:clamp(1.35rem,3vw,2.25rem);
  box-shadow:0 24px 60px -28px rgba(0,0,0,.7);
}
.pdp__eyebrow{
  display:flex; align-items:center; gap:.7em;
  font-family:var(--mono); font-size:.625rem;
  letter-spacing:.2em; text-transform:uppercase; color:var(--fg-2);
}
.pdp__eyebrow b{ color:var(--acc); font-weight:500; }
.pdp__eyebrow b::after{
  content:''; display:inline-block; width:1.4rem; height:1px;
  background:currentColor; vertical-align:middle; margin-left:.7em; opacity:.5;
}
.pdp__name{
  font-family:var(--serif); font-size:clamp(2.1rem,5vw,3.1rem);
  font-variation-settings:'opsz' 48,'wght' 340;
  line-height:1.02; letter-spacing:-.02em; margin-top:.5rem;
}
.pdp__desc{ color:var(--fg-2); max-width:44ch; }
.pdp__body .feat__cta{ margin-top:1.4rem; }

.pdp__spec{ margin-top:auto; padding-top:1.75rem; border-top:1px solid var(--line); }
.pdp__spec > div{
  display:flex; align-items:baseline; justify-content:space-between; gap:1.5rem;
  padding:.65rem 0; border-bottom:1px solid var(--line);
}
.pdp__spec dt{
  font-family:var(--mono); font-size:.625rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--fg-2);
}
.pdp__spec dd{ font-family:var(--mono); font-size:.75rem; text-align:right; }

@media (min-width:860px){
  .pdp{ grid-template-columns:1.05fr .95fr; }
  .pdp__wrap{ max-width:1180px; }
}


/* ── the product page runs on paper ──────────────────────────────── */
.shop--light{ background:var(--dial); }
.no-shader.shop--light .shopbg,
.shop--light .no-shader .shopbg{ background:var(--dial); }
.shop--light .pdp__back{ color:var(--steel-d); }
.shop--light .pdp__back:hover{ color:var(--lume-deep); }
.shop--light .shop__none{ color:var(--steel-d); }
.shop--light .pdp__body{
  border:1px solid rgba(15,19,23,.12);
  box-shadow:0 24px 60px -30px rgba(0,0,0,.35);
}
.shop--light .pdp__shot{ box-shadow:0 30px 70px -30px rgba(0,0,0,.45); }
.shop--light .foot{ position:relative; z-index:1; }

/* ═══ Page transitions ═════════════════════════════════════════════
   One curtain travelling in one direction: it rises to cover the page
   you are leaving, and keeps rising off the top of the page you arrive
   on. Because both halves move the same way it reads as a single pass
   rather than two effects meeting in the middle.

   The arrival half is a pseudo-element so it is painted from the
   stylesheet — a JS-inserted node would flash the page first. */
html{ background:var(--ink); }

body::after{
  content:''; position:fixed; inset:0; z-index:985;
  background:var(--ink); pointer-events:none;
  animation:wipeIn .8s var(--ease-o) both;
}
@keyframes wipeIn{
  from{ transform:translateY(0); }
  to  { transform:translateY(-101%); }
}

.xfade{
  position:fixed; inset:0; z-index:990; pointer-events:none;
  background:var(--ink);
  transform:translateY(101%);
  transition:transform .62s var(--ease-o);
}
.xfade.is-out{ transform:translateY(0); }

@media (prefers-reduced-motion:reduce){
  body::after{ animation:none; transform:translateY(-101%); }
  .xfade{ display:none; }
}


/* ── the product page is one screen on desktop ───────────────────── */
@media (min-width:860px){
  .shop--pdp{ height:100svh; overflow:hidden; }
  .shop--pdp #main{ height:100svh; display:flex; align-items:center; }
  .shop--pdp .pdp__wrap{
    width:100%; padding-top:4.5rem; padding-bottom:1.5rem;
  }
  .shop--pdp .pdp__back{ margin-bottom:1rem; }
  /* both columns take the same fixed height; the copy scrolls inside
     its own panel rather than the page growing a scrollbar */
  .shop--pdp .pdp__shot{ min-height:0; height:min(66svh, 580px); }
  .shop--pdp .pdp__body{ max-height:min(66svh, 580px); overflow-y:auto; }
}
