/* =====================================================================
   ZAH MARBLE
   Tokens → base → layout → components → responsive
   Palette is quarry-derived: blackened basalt, calacatta white, graphite,
   rosso levanto (accent, used sparingly), warm vein gold.
   ===================================================================== */

/* --- TOKENS ---------------------------------------------------------- */
:root {
  /* Stone */
  --basalt:    #0B0B0C;
  --graphite:  #2A2C2F;
  --graphite-2:#17181B;
  --calacatta: #EDEFEE;
  --rosso:     #8E1B21;
  --gold:      #C9A66B;

  /* Semantic — dark is the default; light theme overrides below. */
  --bg:        var(--basalt);
  --bg-raised: var(--graphite-2);
  --ink:       var(--calacatta);
  --ink-soft:  #9A9B99;
  --ink-faint: #63645F;
  --rule:      rgba(237,239,238,.12);
  --rule-firm: rgba(237,239,238,.24);
  --accent:    #A8262E;
  --glass:     rgba(20,21,23,.62);

  /* Type */
  --display: "Bodoni Moda", "Didot", "Times New Roman", serif;
  --ui:      "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono:    "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

  /* Scale — fluid, clamped so 4K and ultrawide stay composed */
  --t-hero: clamp(2.3rem, 7.4vw, 8rem);
  --t-h2:   clamp(2rem, 4.4vw, 4.25rem);
  --t-h3:   clamp(1.1rem, 1.5vw, 1.4rem);
  --t-body: clamp(1rem, 1.05vw, 1.125rem);
  --t-small:0.8125rem;
  --t-micro:0.6875rem;

  /* Rhythm */
  --gut:  clamp(1.25rem, 4vw, 4rem);
  --pad:  clamp(4.5rem, 11vh, 10rem);
  --max:  1680px;
  --nav-h: 66px;   /* fixed header height; sticky bars offset by this */
  --fab: 50px;     /* floating button diameter — content keeps clear of it */

  /* Motion — one easing curve for the whole site */
  --ease: cubic-bezier(.22, .61, .36, 1);
  --slow: .9s;
  --med:  .45s;
  --fast: .22s;
}

:root[data-theme="light"] {
  --bg:        #F1F2F0;
  --bg-raised: #FFFFFF;
  --ink:       #131416;
  --ink-soft:  #55575A;
  --ink-faint: #8B8D8F;
  --rule:      rgba(19,20,22,.13);
  --rule-firm: rgba(19,20,22,.26);
  --accent:    #8E1B21;
  --glass:     rgba(241,242,240,.72);
}

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

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--ui);
  font-size: var(--t-body);
  font-weight: 300;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  transition: background var(--med) var(--ease), color var(--med) var(--ease);
}

img, picture, svg { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1, h2, h3 { margin: 0; font-weight: 400; }
p { margin: 0; }
dl, dd { margin: 0; }
kbd {
  font-family: var(--mono); font-size: .75em; padding: .1em .4em;
  border: 1px solid var(--rule-firm); border-radius: 3px;
}

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

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink); color: var(--bg); padding: .75rem 1.25rem;
}
.skip:focus { left: 1rem; top: 1rem; }

/* Shared type helpers */
.eyebrow {
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.h2 {
  font-family: var(--display);
  font-size: var(--t-h2);
  font-weight: 400;
  line-height: .98;
  letter-spacing: -.02em;
}

/* --- BUTTONS --------------------------------------------------------- */
.btn {
  --btn-ink: var(--ink);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  padding: .95rem 1.9rem;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--btn-ink);
  border: 1px solid var(--rule-firm);
  background: transparent;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;   /* keeps the ::before wipe behind the label */
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
/* Fill wipes up from the base — no default browser transition anywhere. */
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--ink);
  transform: translate3d(0, 101%, 0);
  transition: transform var(--med) var(--ease);
}
.btn:hover::before, .btn:focus-visible::before { transform: translate3d(0, 0, 0); }
.btn:hover, .btn:focus-visible { color: var(--bg); border-color: var(--ink); }

.btn--solid { background: var(--ink); color: var(--bg); border-color: var(--ink); }
.btn--solid::before { background: var(--accent); }
.btn--solid:hover, .btn--solid:focus-visible { color: #fff; border-color: var(--accent); }
.btn--full { width: 100%; }

/* Label sits above the wipe */
.btn { text-align: center; }

/* --- CURTAIN (page load) --------------------------------------------- */
.curtain {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center;
  background: var(--basalt);
  transition: transform 1s var(--ease);
  will-change: transform;
}
.curtain__mark {
  font-family: var(--display);
  font-size: clamp(2.5rem, 8vw, 6rem);
  color: var(--calacatta);
  letter-spacing: .12em;
  opacity: .9;
}
.curtain.is-lifted { transform: translate3d(0, -101%, 0); }
.curtain.is-gone { display: none; }

/* --- NAV ------------------------------------------------------------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  display: flex; align-items: center; gap: var(--gut);
  padding: 1.15rem var(--gut);
  background: transparent;
  transition: background var(--med) var(--ease),
              backdrop-filter var(--med) var(--ease),
              border-color var(--med) var(--ease),
              padding var(--med) var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  border-bottom-color: var(--rule);
  padding-block: .8rem;
}

.nav__mark { display: flex; align-items: baseline; gap: .5rem; }
.nav__mark-z {
  font-family: var(--display);
  font-size: 1.4rem; letter-spacing: .18em;
}
.nav__mark-sub {
  font-family: var(--mono);
  font-size: var(--t-micro); letter-spacing: .22em;
  text-transform: uppercase; color: var(--ink-faint);
}

.nav__links { display: flex; gap: 2.25rem; margin-inline-start: auto; }
.nav__links a {
  position: relative;
  font-family: var(--mono);
  font-size: var(--t-micro);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  transition: color var(--fast) var(--ease);
}
.nav__links a::after {
  content: ""; position: absolute; left: 0; bottom: -.4rem;
  width: 100%; height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: right;
  transition: transform var(--med) var(--ease);
}
.nav__links a:hover { color: var(--ink); }
.nav__links a:hover::after { transform: scaleX(1); transform-origin: left; }

.nav__actions { display: flex; align-items: center; gap: 1rem; }
.nav__actions .btn { padding: .7rem 1.3rem; }

.theme-toggle {
  width: 40px; height: 22px; padding: 0;
  border: 1px solid var(--rule-firm); border-radius: 22px;
  background: transparent; cursor: pointer;
  display: grid; align-items: center;
}
.theme-toggle__dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--ink); margin-inline-start: 3px;
  transition: transform var(--med) var(--ease), background var(--med) var(--ease);
}
:root[data-theme="light"] .theme-toggle__dot { transform: translateX(17px); }

.nav__burger {
  display: none;
  width: 40px; height: 40px; padding: 0;
  background: none; border: 0; cursor: pointer;
}
.nav__burger span {
  display: block; width: 22px; height: 1px; margin: 6px auto;
  background: var(--ink);
  transition: transform var(--med) var(--ease), opacity var(--fast) var(--ease);
}
.nav__burger[aria-expanded="true"] span:first-child { transform: translateY(3.5px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child  { transform: translateY(-3.5px) rotate(-45deg); }

.drawer {
  position: fixed; inset: 0; z-index: 99;
  display: flex; flex-direction: column; justify-content: center; gap: 1rem;
  padding: var(--gut);
  background: var(--bg);
}
.drawer[hidden] { display: none; }
.drawer a {
  font-family: var(--display);
  font-size: clamp(2rem, 9vw, 3.5rem);
  line-height: 1.15;
  border-bottom: 1px solid var(--rule);
  padding-bottom: .5rem;
}

/* --- HERO ------------------------------------------------------------ */
.hero {
  position: relative;
  min-height: 100svh;
  /* Row 1 takes the slack and bottom-aligns the headline; row 2 is the
     bottom bar. Nothing in the hero is absolutely positioned over anything
     else, so the two bands cannot collide at any viewport size. */
  display: grid;
  grid-template-rows: 1fr auto;
  align-items: end;
  gap: clamp(1.5rem, 4vh, 3rem);
  padding: calc(var(--pad) + 3rem) var(--gut) clamp(1.5rem, 4vh, 3rem);
  overflow: hidden;
  isolation: isolate;
}

.hero__foot {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 1rem 2rem;
  width: 100%;
}

/* Three stone planes at different depths. --mx/--my come from JS pointer
   tracking; they default to 0 so the hero is correct without JavaScript. */
.hero__stone { position: absolute; inset: -6%; z-index: -1; }
.hero__layer {
  position: absolute; inset: 0;
  will-change: transform;
  transform: translate3d(calc(var(--mx, 0) * var(--d)), calc(var(--my, 0) * var(--d)), 0);
  transition: transform 1.2s var(--ease);
}
/* Once there is a real photograph behind it, this layer's job changes from
   being the backdrop to darkening one — an opaque fill would simply hide the
   yard. It is weighted to the left, where the headline sits. */
.hero__layer--far {
  --d: 6px;
  background:
    linear-gradient(100deg, rgba(11,11,12,.92) 0%, rgba(11,11,12,.78) 34%, rgba(11,11,12,.45) 62%, rgba(11,11,12,.62) 100%),
    linear-gradient(180deg, rgba(11,11,12,.55) 0%, transparent 40%, rgba(11,11,12,.75) 100%);
}
.hero__layer--mid {
  --d: 14px;
  background:
    linear-gradient(104deg, transparent 0 38%, rgba(237,239,238,.055) 38% 41%, transparent 41%),
    linear-gradient(104deg, transparent 0 58%, rgba(201,166,107,.10) 58% 59.2%, transparent 59.2%),
    linear-gradient(104deg, transparent 0 74%, rgba(237,239,238,.04) 74% 78%, transparent 78%);
}
.hero__layer--near {
  --d: 26px;
  background: radial-gradient(80% 60% at 22% 78%, rgba(201,166,107,.10), transparent 68%);
}
/* Dust in the light shaft — two slow drifting fields, GPU-composited only. */
.hero__dust {
  position: absolute; inset: 0;
  background:
    radial-gradient(1.5px 1.5px at 18% 32%, rgba(237,239,238,.5), transparent 50%),
    radial-gradient(1px 1px   at 42% 68%, rgba(237,239,238,.4), transparent 50%),
    radial-gradient(1.5px 1.5px at 71% 24%, rgba(201,166,107,.5), transparent 50%),
    radial-gradient(1px 1px   at 86% 58%, rgba(237,239,238,.35), transparent 50%),
    radial-gradient(1px 1px   at 58% 88%, rgba(237,239,238,.3), transparent 50%);
  animation: drift 28s linear infinite;
  will-change: transform, opacity;
}
@keyframes drift {
  0%   { transform: translate3d(0, 0, 0);        opacity: .5; }
  50%  { transform: translate3d(2vw, -3vh, 0);   opacity: .9; }
  100% { transform: translate3d(0, 0, 0);        opacity: .5; }
}
:root[data-theme="light"] .hero__layer--far {
  background:
    linear-gradient(100deg, rgba(241,242,240,.94) 0%, rgba(241,242,240,.82) 36%, rgba(241,242,240,.5) 64%, rgba(241,242,240,.7) 100%),
    linear-gradient(180deg, rgba(241,242,240,.6) 0%, transparent 42%, rgba(241,242,240,.8) 100%);
}
:root[data-theme="light"] .hero__dust { opacity: .35; }

.hero__type { max-width: min(1180px, 94vw); }
.hero__h1 {
  font-family: var(--display);
  font-size: var(--t-hero);
  font-weight: 400;
  line-height: .92;
  letter-spacing: -.035em;
  margin: 1.5rem 0 1.75rem;
}
.hero__line { display: block; overflow: hidden; }
.hero__line--em { font-style: italic; color: var(--ink); padding-left: .06em; }
/* Each line rises from behind its own mask on load. */
.hero__line > * , .hero__line { will-change: transform; }
.js .hero__line { transform: translate3d(0, 105%, 0); }
.js .hero.is-in .hero__line {
  transform: translate3d(0, 0, 0);
  transition: transform 1.1s var(--ease);
}
.js .hero.is-in .hero__line--em { transition-delay: .12s; }

.hero__lede { max-width: 46ch; color: var(--ink-soft); }
.hero__cta { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: 2.25rem; }

.hero__scroll {
  display: flex; align-items: center; gap: .75rem;
  margin-inline-start: auto;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .2em; text-transform: uppercase; color: var(--ink-faint);
}
.hero__scroll span {
  display: block; width: 46px; height: 1px; background: var(--rule-firm);
  position: relative; overflow: hidden;
}
.hero__scroll span::after {
  content: ""; position: absolute; inset: 0; background: var(--gold);
  animation: sweep 2.6s var(--ease) infinite;
}
@keyframes sweep {
  0%   { transform: translate3d(-100%, 0, 0); }
  60%,100% { transform: translate3d(100%, 0, 0); }
}

/* --- SECTION SHELL --------------------------------------------------- */
.statement, .work, .flow, .faq, .visit, .rack {
  padding: var(--pad) var(--gut);
  max-width: var(--max);
  margin-inline: auto;
}
.rack { padding-inline: 0; max-width: none; }

/* Scroll reveal — layered, so children arrive after their section. */
.js .reveal { opacity: 0; transform: translate3d(0, 28px, 0); }
.js .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease);
}

/* --- STATEMENT ------------------------------------------------------- */
/* Centred and monumental, with a lot of air around it — the one treatment
   taken from Rolls-Royce, whose hero sets a short line in wide-tracked caps
   and then leaves it alone. Used once, on the page's central claim. */
.statement {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  gap: clamp(1.75rem, 4vw, 3rem);
  border-top: 1px solid var(--rule);
  padding-block: clamp(6rem, 14vh, 12rem);
}
.statement__label {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .42em;            /* the wide tracking is the whole point */
  text-transform: uppercase; color: var(--gold);
  text-indent: .42em;               /* recentre: tracking adds a trailing gap */
}
.statement__text {
  font-family: var(--display);
  font-size: clamp(1.4rem, 3.1vw, 2.9rem);
  line-height: 1.26;
  letter-spacing: -.015em;
  max-width: 24ch;
  text-wrap: balance;
}
.statement__text em { color: var(--gold); font-style: italic; }

/* --- THE RACK (signature) -------------------------------------------- */
.rack__head {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--gut);
  padding-inline: var(--gut);
  max-width: var(--max); margin: 0 auto 3.5rem;
}
.rack__note {
  font-size: var(--t-small); color: var(--ink-soft); max-width: 40ch;
  margin-inline-start: auto;
}

.rack__frame {
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  perspective: 1600px;
  perspective-origin: 50% 44%;
  padding-block: 2rem 1rem;
  cursor: grab;
}
.rack__frame::-webkit-scrollbar { display: none; }
.rack__frame.is-dragging { cursor: grabbing; scroll-snap-type: none; }

/* The A-frame floor line the slabs stand on. */
.rack__frame::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 6.5rem;
  height: 1px; background: linear-gradient(90deg, transparent, var(--rule-firm) 12%, var(--rule-firm) 88%, transparent);
  pointer-events: none;
}

.rack__rail {
  display: flex;
  align-items: flex-end;
  gap: clamp(1.5rem, 3vw, 3.25rem);
  padding-inline: var(--gut);
  width: max-content;
  transform-style: preserve-3d;
}

/* One slab */
.slab {
  flex: 0 0 auto;
  width: clamp(230px, 24vw, 380px);
  scroll-snap-align: center;
  transform-style: preserve-3d;
}

.slab__body {
  position: relative;
  aspect-ratio: 3 / 4;
  transform-style: preserve-3d;
  /* Leaning on the frame, as slabs actually stand. */
  transform: rotateY(-15deg) rotateX(1.5deg) translate3d(0, 0, 0);
  transition: transform var(--slow) var(--ease), filter var(--slow) var(--ease);
  filter: brightness(.86);
  will-change: transform;
}
.slab:hover .slab__body,
.slab:focus-visible .slab__body,
.slab.is-front .slab__body {
  transform: rotateY(-4deg) rotateX(0deg) translate3d(0, -14px, 90px);
  filter: brightness(1.04);
}

/* Cut edge — its width is the real thickness, scaled. */
.slab__edge {
  position: absolute; top: 0; bottom: 0; left: 0;
  width: calc(var(--mm) * 0.42px);
  transform: rotateY(90deg) translate3d(0, 0, calc(var(--mm) * -0.21px));
  transform-origin: left center;
  background: linear-gradient(180deg, #3A3B3D, #17181A 40%, #26282A);
  box-shadow: inset -1px 0 0 rgba(0,0,0,.6);
}

.slab__face {
  position: absolute; inset: 0;
  background: var(--vein);
  background-size: cover;
  box-shadow:
    0 40px 60px -30px rgba(0,0,0,.85),
    inset 0 0 0 1px rgba(255,255,255,.06);
  overflow: hidden;
}
.slab__photo, .slab__photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Fine fracture veining over the base gradient, so a face without a photograph
   still reads as stone rather than a colour chip. Hidden once a photo loads. */
.slab__face::before {
  content: ""; position: absolute; inset: -20%;
  background:
    repeating-linear-gradient(107deg, transparent 0 22px, rgba(255,255,255,.05) 22px 23px, transparent 23px 61px),
    repeating-linear-gradient(84deg,  transparent 0 47px, rgba(0,0,0,.10)       47px 48px, transparent 48px 96px),
    repeating-linear-gradient(131deg, transparent 0 78px, rgba(255,255,255,.03) 78px 80px, transparent 80px 150px);
  mix-blend-mode: overlay;
  pointer-events: none;
}
.slab__face:has(.slab__photo)::before, .viewer:has(.viewer__photo)::before { content: none; }

/* Raking light passes across the polish on hover. */
.slab__sheen {
  position: absolute; inset: -30%;
  background: linear-gradient(104deg, transparent 42%, rgba(255,255,255,.17) 49%, transparent 56%);
  transform: translate3d(-60%, 0, 0);
  opacity: 0;
  transition: transform 1.1s var(--ease), opacity var(--med) var(--ease);
  pointer-events: none;
}
.slab:hover .slab__sheen,
.slab:focus-visible .slab__sheen,
.slab.is-front .slab__sheen { transform: translate3d(60%, 0, 0); opacity: 1; }

.slab__plate { padding-top: 1.5rem; }
.slab__no {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
}
.slab__name {
  font-family: var(--display); font-size: var(--t-h3);
  margin: .35rem 0 .9rem; letter-spacing: -.01em;
}
.slab__name a { background-image: linear-gradient(var(--gold), var(--gold));
  background-size: 0 1px; background-repeat: no-repeat; background-position: 0 100%;
  transition: background-size var(--med) var(--ease); padding-bottom: 2px; }
.slab__name a:hover { background-size: 100% 1px; }

.slab__specs { display: grid; grid-template-columns: 1fr 1fr; gap: .45rem 1rem; }
.slab__specs div { display: flex; flex-direction: column; }
.slab__specs dt {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
.slab__specs dd { font-size: var(--t-small); color: var(--ink-soft); }

.slab__stock {
  margin-top: .9rem; display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft);
}
.slab__stock::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--ink-faint);
}
.slab__stock[data-state="in-stock"]::before   { background: #6E9B7A; }
.slab__stock[data-state="limited"]::before    { background: var(--gold); }
.slab__stock[data-state="made-to-order"]::before { background: var(--accent); }

/* End card */
.rack__end {
  flex: 0 0 auto; align-self: center;
  display: flex; flex-direction: column; gap: .5rem;
  padding: 2.5rem 3rem; margin-inline-end: var(--gut);
  border: 1px solid var(--rule-firm);
  transition: border-color var(--med) var(--ease), transform var(--med) var(--ease);
}
.rack__end:hover { border-color: var(--gold); transform: translate3d(0, -4px, 0); }
.rack__end-count { font-family: var(--display); font-size: clamp(2.5rem, 4vw, 4rem); line-height: 1; }
.rack__end-label {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft);
}

/* --- WORK ------------------------------------------------------------ */
.work { border-top: 1px solid var(--rule); }
.work__head { margin-bottom: 3rem; }
.work__sub { color: var(--ink-soft); margin-top: .75rem; }
.work__grid {
  display: grid; gap: 1px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  background: var(--rule);
  border: 1px solid var(--rule);
}
.work__card {
  background: var(--bg);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  transition: background var(--med) var(--ease), transform var(--med) var(--ease);
}
.work__card:hover { background: var(--bg-raised); }
.work__title { font-family: var(--display); font-size: var(--t-h3); }
.work__meta {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
  margin: .6rem 0 1rem;
}
.work__copy { font-size: var(--t-small); color: var(--ink-soft); line-height: 1.7; }

/* --- FLOW ------------------------------------------------------------ */
.flow { border-top: 1px solid var(--rule); }
.flow__list {
  list-style: none; margin: 3rem 0 0; padding: 0;
  display: grid; gap: 0;
}
.flow__step {
  display: grid;
  grid-template-columns: 5rem minmax(0, 14ch) minmax(0, 1fr);
  gap: var(--gut);
  align-items: baseline;
  padding: 1.9rem 0;
  border-top: 1px solid var(--rule);
}
.flow__step:last-child { border-bottom: 1px solid var(--rule); }
.flow__num { font-family: var(--mono); font-size: var(--t-micro); color: var(--gold); letter-spacing: .14em; }
.flow__title { font-family: var(--display); font-size: clamp(1.3rem, 2.2vw, 2rem); }
.flow__copy { color: var(--ink-soft); font-size: var(--t-small); line-height: 1.75; max-width: 60ch; }

/* --- FAQ ------------------------------------------------------------- */
.faq { border-top: 1px solid var(--rule); }
.faq__list { margin-top: 2.5rem; border-top: 1px solid var(--rule); }
.faq__item { border-bottom: 1px solid var(--rule); }
.faq__item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 2rem;
  padding: 1.5rem 0; cursor: pointer; list-style: none;
  font-family: var(--display); font-size: clamp(1.1rem, 2vw, 1.6rem);
  transition: color var(--fast) var(--ease);
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary:hover { color: var(--gold); }
.faq__mark { position: relative; flex: 0 0 14px; height: 14px; }
.faq__mark::before, .faq__mark::after {
  content: ""; position: absolute; inset: 50% 0 auto 0; height: 1px; background: currentColor;
}
.faq__mark::after { transform: rotate(90deg); transition: transform var(--med) var(--ease); }
.faq__item[open] .faq__mark::after { transform: rotate(0deg); }
.faq__item p { padding: 0 0 1.75rem; max-width: 68ch; color: var(--ink-soft); font-size: var(--t-small); line-height: 1.8; }

/* --- VISIT + FORM ---------------------------------------------------- */
.visit { border-top: 1px solid var(--rule); }
.visit__grid {
  display: grid; gap: clamp(2.5rem, 6vw, 6rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  align-items: start;
}
.visit__copy { color: var(--ink-soft); max-width: 44ch; margin: 1.5rem 0 2.5rem; }
.visit__facts { display: grid; gap: 1.25rem; margin-bottom: 2.5rem; }
.visit__facts dt {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: .35rem;
}
.visit__facts dd { font-size: var(--t-small); }

.form {
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  padding: clamp(1.75rem, 3.5vw, 3rem);
}
.form__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__title {
  font-family: var(--display); font-size: var(--t-h3); margin-bottom: 2rem;
}
.field { margin-bottom: 1.5rem; }
.field label {
  display: block; margin-bottom: .5rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint);
}
.field__opt { text-transform: none; letter-spacing: .04em; opacity: .7; }
.field input, .field textarea {
  width: 100%; padding: .85rem 0;
  font-family: var(--ui); font-size: var(--t-body); font-weight: 300;
  color: var(--ink); background: transparent;
  border: 0; border-bottom: 1px solid var(--rule-firm);
  border-radius: 0;
  transition: border-color var(--med) var(--ease);
}
.field textarea { resize: vertical; }
.field input:focus, .field textarea:focus { outline: none; border-bottom-color: var(--gold); }
.field.has-error input, .field.has-error textarea { border-bottom-color: var(--accent); }
.field__error { min-height: 0; font-size: var(--t-small); color: var(--accent); margin-top: .4rem; }

.form .btn { margin-top: 1rem; }
.form__status { margin-top: 1rem; font-size: var(--t-small); color: var(--ink-soft); }
.form__status[data-state="ok"] { color: var(--gold); }
.form__status[data-state="error"] { color: var(--accent); }
.form__aside { margin-top: 1.5rem; font-size: var(--t-small); color: var(--ink-faint); }
.form__aside a { color: var(--ink); border-bottom: 1px solid var(--rule-firm); }

/* --- FOOTER ---------------------------------------------------------- */
.foot {
  border-top: 1px solid var(--rule);
  padding: var(--pad) var(--gut) 2rem;
  max-width: var(--max); margin-inline: auto;
}
.foot__grid {
  display: grid; gap: clamp(2rem, 4vw, 4rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.foot__brand { grid-column: span 1; }
.foot__mark { font-family: var(--display); font-size: 2.25rem; letter-spacing: .16em; }
.foot__line { margin-top: 1rem; font-size: var(--t-small); color: var(--ink-soft); line-height: 1.8; }
.foot__h {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .2em; text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: 1.1rem; font-weight: 400;
}
.foot address { font-style: normal; font-size: var(--t-small); color: var(--ink-soft); line-height: 1.9; }
.foot__link {
  display: block; font-size: var(--t-small); color: var(--ink-soft);
  padding: .25rem 0; transition: color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.foot__link:hover { color: var(--ink); transform: translateX(4px); }
.foot__hours { margin-top: .9rem; font-size: var(--t-small); color: var(--ink-faint); }
.foot__base {
  display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
  margin-top: clamp(3rem, 6vw, 5rem); padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}

/* --- FLOATING CONTROLS ----------------------------------------------- */
.wa, .totop {
  position: fixed; right: clamp(1rem, 2.5vw, 2rem); z-index: 90;
  display: grid; place-items: center;
  width: var(--fab); height: var(--fab); border-radius: 50%;
  border: 1px solid var(--rule-firm);
  background: var(--glass);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  color: var(--ink); cursor: pointer;
  transition: transform var(--med) var(--ease), border-color var(--med) var(--ease), opacity var(--med) var(--ease);
}
.wa { bottom: clamp(1rem, 2.5vw, 2rem); }
.wa:hover { transform: scale(1.08); border-color: var(--gold); }
.totop {
  bottom: calc(clamp(1rem, 2.5vw, 2rem) + var(--fab) + 12px);
  opacity: 0; pointer-events: none; font-size: 1.1rem;
}
.totop.is-in { opacity: 1; pointer-events: auto; }

.progress {
  position: fixed; top: 0; left: 0; z-index: 101;
  height: 2px; width: 100%;
  background: var(--gold);
  transform: scaleX(var(--p, 0)); transform-origin: left;
  will-change: transform;
}

/* --- RESPONSIVE ------------------------------------------------------ */
@media (max-width: 900px) {
  :root { --nav-h: 58px; }
  .nav__links, .nav__actions .btn { display: none; }
  .nav__burger { display: block; margin-inline-start: auto; }
  .nav__actions { margin-inline-start: auto; order: 2; }
  .flow__step { grid-template-columns: 3.5rem 1fr; }
  .flow__copy { grid-column: 2; }
  .hero__scroll { display: none; }
  .hero__foot { justify-content: center; }

  /* Stacked, so the note starts at the margin rather than being pushed
     into the corner the floating buttons occupy. */
  .rack__head { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .rack__note { margin-inline-start: 0; max-width: none; padding-inline-end: calc(var(--fab) + 1.5rem); }
}

@media (max-width: 560px) {
  :root { --fab: 46px; }
  .slab { width: 74vw; }
  .slab__specs { grid-template-columns: 1fr; }
  .foot__base { flex-direction: column; }
}

/* Ultrawide: cap the rail so slabs never stretch into a smear. */
@media (min-width: 2200px) {
  :root { --max: 2000px; }
  .rack__rail { padding-inline: calc((100vw - 2000px) / 2 + var(--gut)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js .reveal, .js .hero__line { opacity: 1; transform: none; }
  .curtain { display: none; }
  .slab__body { transform: rotateY(-8deg); filter: none; }
}

@media print {
  .nav, .drawer, .wa, .totop, .progress, .curtain, .hero__stone { display: none !important; }
  body { background: #fff; color: #000; }
}

/* =====================================================================
   INNER PAGES
   ===================================================================== */
.sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.page-head {
  max-width: var(--max); margin-inline: auto;
  padding: calc(var(--pad) + 4rem) var(--gut) clamp(2.5rem, 5vw, 4rem);
}
.page-head--tall { min-height: 70svh; display: flex; flex-direction: column; justify-content: center; }
.page-head .h2 { margin: 1rem 0 1.5rem; }
.page-head__lede { max-width: 52ch; color: var(--ink-soft); }
.page-head__cta { margin-top: 2.5rem; }

/* --- Filters --------------------------------------------------------- */
/* Solid, not glass — and that is a performance decision, not a style one.
   This bar is re-positioned by transform on every scrolled frame, and a
   backdrop-filter that moves has to re-sample what is behind it each time.
   Measured: with the blur on, scrolling this page held ~46fps; without it,
   a steady 60. The header keeps its glass because it never moves, so its
   backdrop is composited once and reused. */
.filters {
  position: sticky; top: var(--nav-h); z-index: 50;
  max-width: var(--max); margin-inline: auto;
  padding: 1.25rem var(--gut);
  background: var(--bg);
  border-block: 1px solid var(--rule);
  box-shadow: 0 18px 30px -24px rgba(0, 0, 0, .8);
}
.filters__bar { display: flex; flex-wrap: wrap; gap: 1.25rem 2rem; align-items: center; }
.filters__row { display: flex; flex-wrap: wrap; gap: 1.25rem 2rem; align-items: center; }
.filters__search input {
  width: min(28ch, 60vw); padding: .6rem 0;
  background: transparent; border: 0; border-bottom: 1px solid var(--rule-firm);
  color: var(--ink); font-family: var(--ui); font-size: var(--t-small); font-weight: 300;
}
.filters__search input:focus { outline: none; border-bottom-color: var(--gold); }
.filters__group { display: flex; flex-wrap: wrap; gap: .5rem; }
.chip {
  padding: .45rem .9rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-soft); background: transparent;
  border: 1px solid var(--rule); border-radius: 999px; cursor: pointer;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.chip:hover { color: var(--ink); border-color: var(--rule-firm); }
.chip.is-on { color: var(--bg); background: var(--ink); border-color: var(--ink); }
.filters__count {
  margin: 0 0 0 auto; padding-left: 1rem; white-space: nowrap;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}

/* --- Grid rack (inventory page) -------------------------------------- */
.grid-rack {
  max-width: var(--max); margin-inline: auto;
  padding: clamp(3rem, 6vw, 5rem) var(--gut) var(--pad);
  display: grid; gap: clamp(2.5rem, 5vw, 4.5rem);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  perspective: 1600px;
}
.grid-rack .slab { width: auto; }
.grid-rack__empty { grid-column: 1 / -1; color: var(--ink-soft); max-width: 46ch; }
.grid-rack__empty a { color: var(--gold); border-bottom: 1px solid currentColor; }
.slab.is-hidden { display: none; }

/* --- Breadcrumb ------------------------------------------------------ */
.crumbs {
  max-width: var(--max); margin-inline: auto;
  padding: calc(var(--pad) + 3rem) var(--gut) 0;
  display: flex; gap: .6rem; flex-wrap: wrap;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}
.crumbs a:hover { color: var(--gold); }

/* --- Slab detail ----------------------------------------------------- */
.detail {
  max-width: var(--max); margin-inline: auto;
  padding: clamp(2rem, 4vw, 3.5rem) var(--gut) var(--pad);
  display: grid; gap: clamp(2.5rem, 5vw, 5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), 1fr));
  align-items: start;
}
.viewer {
  position: relative; aspect-ratio: 4 / 3;
  background: var(--vein); background-size: cover;
  box-shadow: 0 60px 80px -50px rgba(0,0,0,.9), inset 0 0 0 1px rgba(255,255,255,.06);
  overflow: hidden;
}
.viewer__photo, .viewer__photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* --lx follows the pointer, so the highlight rakes across the polish. */
.viewer__sheen {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(38% 60% at var(--lx, 50%) var(--ly, 40%),
    rgba(255,255,255,.22), transparent 70%);
  transition: background .18s linear;
}
.viewer__hint { margin-top: 1rem; font-size: var(--t-small); color: var(--ink-faint); max-width: 44ch; }

.detail__name {
  font-family: var(--display);
  font-size: clamp(2.25rem, 5vw, 4.5rem); line-height: 1; letter-spacing: -.03em;
  margin: 1rem 0 1.5rem;
}
.detail__summary { color: var(--ink-soft); max-width: 46ch; }
.detail__specs {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1.5rem; margin: 2.5rem 0;
  padding-block: 2rem; border-block: 1px solid var(--rule);
}
.detail__specs dt {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint);
  margin-bottom: .4rem;
}
.detail__specs dd { font-size: var(--t-small); }
.detail__actions { display: flex; flex-wrap: wrap; gap: .75rem; }
.detail__form {
  max-width: min(var(--max), 640px); margin-inline: auto;
  padding: 0 var(--gut) var(--pad);
}

/* --- Map ------------------------------------------------------------- */
.map {
  position: relative; aspect-ratio: 16 / 10; margin-bottom: 1.5rem;
  border: 1px solid var(--rule); overflow: hidden;
  filter: grayscale(1) contrast(1.1);
  transition: filter var(--slow) var(--ease);
}
.map:hover { filter: grayscale(0); }
.map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* =====================================================================
   MOTION LAYER
   Paired with public/js/motion.js. Every rule here is inert until that
   file adds its flag class, and all of it collapses under reduced motion.
   ===================================================================== */

/* --- Inertia scroll track --------------------------------------------
   The track is taken out of flow and moved by transform; body height is
   set in JS to match, so the native scrollbar stays honest. ----------- */
/* Body keeps the document's scrollbar — JS sets its height to match the track,
   so the native scroll range stays exactly right. Never set overflow on body
   here: with a fixed height it would turn body into its own scroll container
   and the document would stop scrolling. The track is lifted out of flow and
   moved by transform. */
.has-inertia .track {
  position: fixed; inset: 0 0 auto 0;
  will-change: transform;
  backface-visibility: hidden;
}

/* Neither `sticky` nor `fixed` escapes a transformed ancestor — the track
   becomes their containing block. So the bar stays in normal flow and JS
   gives it exactly the offset the track just took away, which holds it at
   the top of the viewport without any layout jump to compensate for. */
.has-inertia .filters {
  position: relative; z-index: 50;
  will-change: transform;
}

/* --- Camera pan across the rack --------------------------------------
   --pan is the slab's distance from the centre of the screen, written by
   JS each frame: -1 above, 0 centred, +1 below. ---------------------- */
.slab { --pan: 0; }
/* The rail is the one place the pan blur earns its cost. */
.rack__rail .slab__body {
  filter: brightness(calc(.9 - min(var(--pan) * var(--pan), .5) * .3))
          blur(var(--pan-blur, 0px));
}
.slab__body {
  transform:
    perspective(1400px)
    rotateY(calc(-15deg + var(--pan) * 9deg))
    rotateX(calc(var(--pan) * -2.5deg))
    translate3d(calc(var(--pan) * -22px), 0, calc(var(--pan) * var(--pan) * -70px));
  /* Brightness only. A blur pass over every card costs more GPU than the
     smear is worth at grid size; the rail keeps it below, where there are
     few slabs and the movement is fast enough for it to read. */
  filter: brightness(calc(.9 - min(var(--pan) * var(--pan), .5) * .3));
}
/* Hover still wins — the slab comes square-on and stops smearing. */
.slab:hover .slab__body,
.slab:focus-visible .slab__body,
.slab.is-front .slab__body {
  transform: perspective(1400px) rotateY(-3deg) translate3d(0, -16px, 100px);
  filter: brightness(1.06) blur(0);
}

/* Anything with data-depth drifts against the scroll at its own rate. */
[data-depth] {
  transform: translate3d(0, var(--shift, 0px), 0);
  will-change: transform;
}

/* --- Headlines cut letter by letter ---------------------------------- */
/* A word holds its letters together so a heading can never break mid-word;
   the mask clips one letter as it rises. */
.word { display: inline-block; white-space: nowrap; }
.cut  { display: inline-block; overflow: hidden; vertical-align: bottom; padding: 0; }
.cut__in {
  display: inline-block;
  transform: translate3d(0, 105%, 0) rotate(4deg);
  transition: transform 1s var(--ease);
  will-change: transform;
}
.is-cut .cut__in { transform: translate3d(0, 0, 0) rotate(0); }

/* --- Cursor ----------------------------------------------------------- */
.cursor { position: fixed; inset: 0; z-index: 300; pointer-events: none; }
.has-cursor, .has-cursor a, .has-cursor button, .has-cursor summary { cursor: none; }
/* Text entry keeps its real caret — never take that away. */
.has-cursor input, .has-cursor textarea, .has-cursor select { cursor: auto; }

.cursor__dot, .cursor__ring {
  position: absolute; top: 0; left: 0;
  border-radius: 50%;
  margin: -4px 0 0 -4px;
  will-change: transform;
}
.cursor__dot { width: 8px; height: 8px; background: var(--gold); }
.cursor__ring {
  width: 34px; height: 34px; margin: -17px 0 0 -17px;
  border: 1px solid var(--rule-firm);
  transition: width var(--med) var(--ease), height var(--med) var(--ease),
              margin var(--med) var(--ease), border-color var(--med) var(--ease),
              opacity var(--med) var(--ease);
}
.cursor.is-hot .cursor__ring {
  width: 62px; height: 62px; margin: -31px 0 0 -31px;
  border-color: var(--gold);
}
.cursor.is-down .cursor__ring { width: 24px; height: 24px; margin: -12px 0 0 -12px; }

/* --- Magnetic controls ------------------------------------------------ */
.btn, .rack__end, .theme-toggle {
  transition: transform .5s var(--ease), color var(--fast) var(--ease),
              border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.btn:active { transition-duration: .08s; }

/* --- Page transition veil --------------------------------------------- */
.veil {
  position: fixed; inset: 0; z-index: 250;
  background: var(--basalt);
  transform: translate3d(0, 100%, 0);
  pointer-events: none;
}
.veil.is-in {
  transform: translate3d(0, 0, 0);
  transition: transform .48s cubic-bezier(.7, 0, .3, 1);
}

/* --- Hero material switcher (adapted from the segmented control that
       sits over Varmora's hero, but wired to change the actual stone) --- */
.switch {
  display: flex; gap: .25rem; padding: .3rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  z-index: 3;
}
.switch__btn {
  padding: .7rem 1.4rem; border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-soft); cursor: pointer;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; white-space: nowrap;
  transition: color var(--med) var(--ease), background var(--med) var(--ease);
}
.switch__btn:hover { color: var(--ink); }
.switch__btn.is-on { background: var(--ink); color: var(--bg); }

/* Each material relights the hero. The mid layer carries the veining, so
   changing its hue changes what stone the room is cut from. */
.hero[data-material="granite"] .hero__layer--near {
  background: radial-gradient(80% 60% at 22% 78%, rgba(146,160,152,.14), transparent 68%);
}
.hero[data-material="granite"] .hero__layer--mid { filter: hue-rotate(120deg) saturate(.7); }
.hero[data-material="stone"] .hero__layer--near {
  background: radial-gradient(80% 60% at 22% 78%, rgba(224,213,195,.16), transparent 68%);
}
.hero[data-material="stone"] .hero__layer--mid { filter: hue-rotate(-18deg) saturate(1.5) brightness(1.15); }
/* Quartz is a made material — the room reads cooler and more even for it. */
.hero[data-material="quartz"] .hero__layer--near {
  background: radial-gradient(80% 60% at 22% 78%, rgba(214,220,226,.16), transparent 68%);
}
.hero[data-material="quartz"] .hero__layer--mid { filter: hue-rotate(190deg) saturate(.45) brightness(1.1); }

/* The swap itself: light sweeps across the room, once. */
.hero.is-swapping .hero__stone { animation: relight .95s var(--ease); }
@keyframes relight {
  0%   { opacity: 1;   transform: scale(1); }
  35%  { opacity: .35; transform: scale(1.035); }
  100% { opacity: 1;   transform: scale(1); }
}
.hero__layer { transition: filter .8s var(--ease), background .8s var(--ease); }

/* --- Marquee of stone currently on the racks -------------------------- */
.crawl {
  overflow: hidden; padding: 1.4rem 0;
  border-block: 1px solid var(--rule);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.crawl__row { display: flex; width: max-content; animation: crawl 42s linear infinite; }
.crawl:hover .crawl__row { animation-play-state: paused; }
.crawl__item {
  display: flex; align-items: center; gap: 2.5rem; padding-inline: 1.25rem;
  font-family: var(--display); font-size: clamp(1.1rem, 2vw, 1.75rem);
  color: var(--ink-soft); white-space: nowrap;
}
.crawl__item::after { content: "◆"; font-size: .5em; color: var(--gold); }
@keyframes crawl { to { transform: translate3d(-50%, 0, 0); } }

@media (prefers-reduced-motion: reduce) {
  .cut__in { transform: none; }
  .cursor, .veil { display: none; }
  .crawl__row { animation: none; }
  .slab__body { transform: rotateY(-8deg); filter: none; }
  .has-inertia .track { position: static; transform: none; }
}

/* --- Tally (counters) -------------------------------------------------- */
.tally {
  display: grid; gap: clamp(1.5rem, 3vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  padding-block: clamp(2rem, 4vw, 3rem);
  border-block: 1px solid var(--rule);
}
.tally__item { display: flex; flex-direction: column; gap: .6rem; }
.tally__n {
  font-family: var(--display);
  font-size: clamp(2.5rem, 5vw, 4.5rem); line-height: .9;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.tally__n span { font-variant-numeric: tabular-nums; }
.tally__l {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-faint);
  max-width: 22ch; line-height: 1.7;
}

/* The switcher stacks under the headline on narrow screens. */
@media (max-width: 620px) {
  .switch { width: 100%; justify-content: center; flex-wrap: wrap; }
  .switch__btn { padding: .6rem 1rem; flex: 1 1 auto; }
}

/* =====================================================================
   CONTINUOUS 3D
   The yard is never still. These run for as long as the page is open,
   independently of scroll, so the depth reads even when nothing is
   being interacted with. All of it is transform/opacity only, so it
   stays on the compositor and costs no layout.
   ===================================================================== */

/* --- Slabs breathe on the rack ---------------------------------------
   Real slabs leaning on an A-frame settle and shift. Each slab is given
   its own period and phase from --i (its index), so the rack never
   pulses in unison — that is what would read as animation rather than
   as stone. --------------------------------------------------------- */
/* The drift is a small, self-contained motion on its own element. Keeping it
   off .slab__body is what lets the hover pose transition: an animation and a
   transition on the same property cannot coexist — cancelling the animation
   makes the element jump straight to its new value instead of easing to it. */
.slab__drift {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  animation: settle calc(11s + var(--i, 0) * 1.7s) ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -2.3s);
}
@keyframes settle {
  0%, 100% { transform: translate3d(0, 0, 0)    rotateX(0deg); }
  50%      { transform: translate3d(0, -5px, 14px) rotateX(.55deg); }
}
/* Taking a slab stills it — and because the drift is a separate element, the
   pose underneath is free to ease in and out normally. */
.slab:hover .slab__drift,
.slab:focus-visible .slab__drift,
.slab.is-front .slab__drift {
  animation-play-state: paused;
}

/* --- Light crosses the rack ------------------------------------------
   A slow raking highlight, as if the roller shutter were open at one
   end of the shed. Runs continuously, offset per slab. ---------------- */
.slab__face::after {
  content: ""; position: absolute; inset: -40% -60%;
  background: linear-gradient(100deg,
    transparent 40%, rgba(255,255,255,.13) 50%, transparent 60%);
  animation: rake calc(9s + var(--i, 0) * 1.1s) linear infinite;
  animation-delay: calc(var(--i, 0) * -1.9s);
  pointer-events: none;
}
@keyframes rake {
  0%   { transform: translate3d(-55%, 0, 0); }
  100% { transform: translate3d(55%, 0, 0); }
}

/* --- The room itself drifts ------------------------------------------
   Two of the hero's stone planes move on long, mismatched cycles, so the
   depth between them keeps changing. Combined with the pointer parallax
   this reads as a room you are standing in, not a flat backdrop. ------ */
.hero__layer--mid  { animation: driftA 26s ease-in-out infinite; }
.hero__layer--near { animation: driftB 34s ease-in-out infinite; }
@keyframes driftA {
  0%, 100% { transform: translate3d(calc(var(--mx, 0) * var(--d)), calc(var(--my, 0) * var(--d)), 0) scale(1); }
  50%      { transform: translate3d(calc(var(--mx, 0) * var(--d) + 14px), calc(var(--my, 0) * var(--d) - 8px), 0) scale(1.018); }
}
@keyframes driftB {
  0%, 100% { transform: translate3d(calc(var(--mx, 0) * var(--d)), calc(var(--my, 0) * var(--d)), 0) scale(1.02); }
  50%      { transform: translate3d(calc(var(--mx, 0) * var(--d) - 20px), calc(var(--my, 0) * var(--d) + 10px), 0) scale(1); }
}

/* Gentle vertical float, used where an element has clear space around it.
   Deliberately no rotation or Z on anything sitting in a tight grid — that
   is what pushes corners over their neighbours. */
@keyframes float3d {
  0%, 100% { transform: translate3d(0, 0, 0); }
  50%      { transform: translate3d(0, -6px, 0); }
}

/* --- The gold rule under the header breathes -------------------------- */
.nav.is-stuck { border-bottom-color: var(--rule); }
.nav::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 1px;
  width: 100%;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0; transform: scaleX(.3);
  transition: opacity var(--slow) var(--ease);
}
.nav.is-stuck::after { opacity: .5; animation: sweepRule 9s ease-in-out infinite; }
@keyframes sweepRule {
  0%, 100% { transform: scaleX(.25) translateX(-120%); opacity: .15; }
  50%      { transform: scaleX(1)   translateX(0);     opacity: .5; }
}

/* --- The stock figure never settles ----------------------------------- */
.rack__end-count {
  display: inline-block;
  animation: float3d 12s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .slab__drift, .slab__face::after, .hero__layer--mid, .hero__layer--near,
  .nav.is-stuck::after, .rack__end-count { animation: none !important; }
}

/* =====================================================================
   3D STAGES
   Every WebGL scene on the site uses these. A stage stays hidden until a
   context exists (`.has-webgl` is set the moment one is created), so the
   flat markup it replaces is never swapped out for an empty box.
   ===================================================================== */
.stage {
  position: relative;
  margin-inline: auto;
  max-width: var(--max);
  touch-action: pan-y;              /* vertical scroll still belongs to the page */
  display: none;
}
.has-webgl .stage { display: block; }

/* What each stage replaces, once WebGL is confirmed. */
.has-webgl .rack__frame,
.has-webgl .viewer,
.has-webgl .no-webgl { display: none; }
.only-webgl { display: none; }
.has-webgl .only-webgl { display: inline; }

.stage__canvas { display: block; width: 100%; height: 100%; }

.stage--rack     { height: clamp(420px, 68vh, 760px); cursor: grab; }
.stage--wide     { max-width: none; }
.stage--viewer   { height: clamp(380px, 60vh, 640px); cursor: grab; }
.stage--block    { height: clamp(360px, 56vh, 620px); }
.stage--monolith { height: clamp(320px, 46vh, 520px); }
.stage--quiet    { opacity: .55; }
.stage.is-dragging { cursor: grabbing; }

/* The plate reads like the chalk board hung on a real rack. */
.stage__plate {
  position: absolute; left: var(--gut); bottom: var(--gut);
  max-width: min(34ch, calc(100% - var(--gut) * 2));
  padding: 1.25rem 1.5rem;
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid var(--rule);
  animation: plateIn .4s var(--ease);
}
@keyframes plateIn {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: none; }
}
.stage__no {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
}
.stage__name {
  font-family: var(--display); font-size: clamp(1.25rem, 2.2vw, 1.9rem);
  margin: .3rem 0 .5rem;
}
.stage__spec { font-size: var(--t-small); color: var(--ink-soft); }
.stage__link {
  display: inline-block; margin-top: .9rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase;
  border-bottom: 1px solid var(--rule-firm); padding-bottom: 2px;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.stage__link:hover { color: var(--gold); border-color: var(--gold); }

.stage__hint, .stage__caption {
  position: absolute; right: var(--gut); top: var(--gut);
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-faint);
  pointer-events: none;
}
.stage__caption { right: auto; left: var(--gut); bottom: var(--gut); top: auto; max-width: 34ch; }

/* Face / edge switch on the slab viewer. */
.stage__views {
  position: absolute; left: var(--gut); top: var(--gut); z-index: 2;
  display: flex; gap: .25rem; padding: .3rem;
  border: 1px solid var(--rule); border-radius: 999px;
  background: var(--glass);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}
.stage__view {
  padding: .55rem 1.1rem; border: 0; border-radius: 999px;
  background: transparent; color: var(--ink-soft); cursor: pointer;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
  transition: color var(--med) var(--ease), background var(--med) var(--ease);
}
.stage__view:hover { color: var(--ink); }
.stage__view.is-on { background: var(--ink); color: var(--bg); }

/* --- The block section on the About page -----------------------------
   Named `.sawn`, not `.cut`: `.cut` is the per-letter mask used by the
   headline split, and a section's padding landing on every glyph is not a
   mistake worth making twice. ---------------------------------------- */
.sawn {
  max-width: var(--max); margin-inline: auto;
  padding: var(--pad) var(--gut);
  border-top: 1px solid var(--rule);
}
.sawn .h2 { margin-bottom: clamp(2rem, 4vw, 3rem); }
.sawn__note {
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  max-width: 56ch; color: var(--ink-soft); font-size: var(--t-small); line-height: 1.8;
}

@media (max-width: 700px) {
  .stage--rack { height: clamp(360px, 56vh, 520px); }
  .stage__plate { left: var(--gut); right: var(--gut); max-width: none; padding: 1rem 1.1rem; }
  .stage__hint { display: none; }
  .stage__views { left: 50%; transform: translateX(-50%); }
}

/* The way through to the full inventory, shown with either rack. */
.rack__more {
  max-width: var(--max);
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  padding-inline: var(--gut);
  text-align: right;
}
.rack__more a {
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft);
  border-bottom: 1px solid var(--rule-firm); padding-bottom: 3px;
  transition: color var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.rack__more a:hover { color: var(--gold); border-color: var(--gold); }
@media (max-width: 900px) { .rack__more { text-align: left; } }

/* A plain-language clause under the editorial headline. It says what the page
   is for, in the words someone would actually search — visible text doing an
   honest job, not a keyword line hidden from readers. */
.h1__sub {
  display: block;
  margin-top: .9rem;
  max-width: 46ch;
  font-family: var(--ui);
  font-size: clamp(.9rem, 1.15vw, 1.05rem);
  font-weight: 300;
  line-height: 1.55;
  letter-spacing: 0;
  color: var(--ink-soft);
}

/* =====================================================================
   THE RACK ON A PHONE
   With 27 products the desktop layout stops working here: wrapped filter
   chips grew the sticky bar to a third of the screen, and one-per-row
   cards made the grid a 21,000px scroll. Both are fixed by changing the
   shape of the controls, not by hiding information.
   ===================================================================== */
@media (max-width: 700px) {

  /* --- Filters: one line per group, swiped sideways ------------------- */
  .filters { padding-block: .9rem; }
  .filters__row { gap: .6rem; }
  .filters__bar { gap: .6rem; width: 100%; }

  .filters__search { width: 100%; }
  .filters__search input { width: 100%; font-size: 1rem; }   /* 16px stops iOS zooming on focus */

  /* Each group scrolls horizontally instead of wrapping. Bleeding to the
     screen edge is deliberate: a row that touches the edge reads as
     scrollable, where one that stops short looks like it has ended. */
  .filters__group {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    width: 100%;
    margin-inline: calc(var(--gut) * -1);
    padding-inline: var(--gut);
    scroll-snap-type: x proximity;
  }
  .filters__group::-webkit-scrollbar { display: none; }
  .chip { flex: 0 0 auto; scroll-snap-align: start; }

  .filters__count { margin: 0; padding: 0; }

  /* --- Two per row, with a plate trimmed to what you browse on --------
     Origin, size and finish stay on the slab's own page; in a grid you
     are choosing by look, name, thickness and whether it is in stock. -- */
  .grid-rack {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem 1rem;
    padding-top: 2.5rem;
  }
  .grid-rack .slab__plate { padding-top: .9rem; }
  .grid-rack .slab__name { font-size: 1rem; margin: .3rem 0 .5rem; }
  .grid-rack .slab__no { font-size: .625rem; letter-spacing: .08em; }

  /* Keep thickness — it is the one spec that decides whether a piece is
     usable for the job — and drop the rest to the detail page. */
  .grid-rack .slab__specs {
    grid-template-columns: 1fr;
    gap: .2rem;
  }
  .grid-rack .slab__specs div:not(:nth-child(3)) { display: none; }
  .grid-rack .slab__specs div:nth-child(3) { flex-direction: row; gap: .4rem; align-items: baseline; }
  .grid-rack .slab__stock { margin-top: .5rem; font-size: .625rem; }

  /* The scroll-driven pan is a depth cue at 380px wide. At 160px the same
     rotation reads as a sheared rectangle — the slab stops looking like an
     object and starts looking like a bug. So the grid keeps a fixed, gentle
     lean that still shows the cut edge, and drops the pan and the drift. */
  .grid-rack .slab__body {
    transform: perspective(2600px) rotateY(-8deg);
    filter: none;
  }
  .grid-rack .slab__drift { animation: none; }
  .grid-rack .slab:hover .slab__body,
  .grid-rack .slab:focus-visible .slab__body,
  .grid-rack .slab.is-front .slab__body {
    transform: perspective(2600px) rotateY(-2deg) translate3d(0, -4px, 0);
  }

  /* The count sat half-clipped against the bar's lower edge. */
  .filters__count { align-self: center; color: var(--ink-soft); }
}

/* Below 400px two columns get cramped, but one full-width column is worse
   for 27 items — so the cards simply tighten further. */
@media (max-width: 400px) {
  .grid-rack { gap: 1.5rem .75rem; }
  .grid-rack .slab__name { font-size: .9rem; }
}

/* =====================================================================
   PHOTOGRAPHY
   Real pictures of the yard. Every one is given an aspect ratio up front
   so the page never reflows when an image finally arrives — that is what
   a cumulative layout shift is, and it is the cheapest one to avoid.
   ===================================================================== */
.photo {
  display: block;
  position: relative;
  aspect-ratio: var(--ratio, 4 / 3);
  overflow: hidden;
  background: var(--bg-raised);
}
.photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}

/* --- Hero: the yard behind the type ------------------------------------ */
.hero__photo {
  position: absolute; inset: 0;
  z-index: -3;
}
.hero__photo .photo { width: 100%; height: 100%; aspect-ratio: auto; }
/* Held back so the headline stays legible over it — the photograph is the
   room, not the subject. */
.hero__photo img { filter: brightness(.42) saturate(.72) contrast(1.05); }
:root[data-theme="light"] .hero__photo img { filter: brightness(1.06) saturate(.7) contrast(.95); opacity: .5; }

/* --- The yard gallery -------------------------------------------------- */
.yard {
  max-width: var(--max); margin-inline: auto;
  padding: var(--pad) var(--gut);
  border-top: 1px solid var(--rule);
}
.yard__head { margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.yard__sub { margin-top: 1rem; max-width: 52ch; color: var(--ink-soft); }

.yard__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.75rem);
}
.yard__item { margin: 0; grid-column: span 1; }
.yard__item--wide { grid-column: span 2; }
.yard__item figcaption {
  margin-top: .85rem;
  font-family: var(--mono); font-size: var(--t-micro);
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-faint);
}
/* A slow push in on hover — the photograph moves, its frame does not. */
.yard__item .photo img {
  transition: transform 1.4s var(--ease), filter var(--slow) var(--ease);
}
.yard__item:hover .photo img { transform: scale(1.045); filter: brightness(1.05); }

@media (max-width: 900px) {
  .yard__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .yard__item--wide { grid-column: span 2; }
}
@media (max-width: 560px) {
  .yard__grid { grid-template-columns: 1fr; }
  .yard__item, .yard__item--wide { grid-column: span 1; }
}

/* --- A single photograph inside a page --------------------------------- */
.page-photo {
  max-width: var(--max); margin: 0 auto;
  padding: 0 var(--gut) clamp(2rem, 5vw, 4rem);
}
.page-photo figcaption {
  margin-top: 1rem; max-width: 60ch;
  font-size: var(--t-small); color: var(--ink-soft);
}
.page-photo--tight { padding-inline: 0; margin-bottom: 1.5rem; }
