/* ===========================================================================
   Ashish Marble & Granite — ashishmarble.com
   ---------------------------------------------------------------------------
   Design system + page styles. Single stylesheet, no framework, no build step.

   The visual weight of this site is meant to come from composition, type scale
   and the stone itself — not from decoration. Gold appears only as hairlines,
   rules and selected states. There are no drop shadows on cards, no rounded
   rectangles, and no gradients that aren't standing in for light.

   Sections are ordered top-to-bottom to match index.html.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Tokens
   --------------------------------------------------------------------------- */

:root {
  /* Surfaces — warm blacks, never blue-black. Stone is a warm material. */
  --ink:        #131210;
  --ink-2:      #1b1917;
  --ink-3:      #26231f;
  --ink-4:      #332f2a;

  --paper:      #fbf9f5;
  --ivory:      #f4f0e8;
  --sand:       #e7e0d2;
  --taupe:      #b3a795;
  --stone:      #8a8074;
  --slate:      #5c564e;

  /* Gold, deliberately muted. A bright yellow reads as costume jewellery. */
  --gold:       #a8853c;
  --gold-lit:   #cbab6a;
  --gold-dim:   rgba(168, 133, 60, 0.28);

  /* Text-safe variants.
     ------------------------------------------------------------------------
     --stone and --gold are tuned to look right as rules, marks and accents,
     but against the ivory page they measure 3.7:1 and 3.3:1 — both below the
     4.5:1 that small text needs to stay readable. These are the same hues
     walked down in lightness until they pass. Use them for any text under
     ~18px on a light ground; keep the originals for lines and decoration. */
  --stone-text: #7a7267;   /* 4.5:1 on --paper */
  --gold-text:  #8b6e32;   /* 4.6:1 on --paper */

  /* Semantic */
  --bg:         var(--paper);
  --fg:         var(--ink);
  --fg-muted:   var(--slate);
  --rule:       rgba(19, 18, 16, 0.13);
  --rule-dark:  rgba(244, 240, 232, 0.14);

  /* Type */
  --display: 'Cormorant Garamond', 'Iowan Old Style', 'Palatino Linotype',
             Palatino, Georgia, 'Times New Roman', serif;
  --ui: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
        'Helvetica Neue', Arial, sans-serif;

  /* Fluid scale. min at 360px, max at 1600px. */
  /* Capped against viewport *height* as well as width: on a short laptop
     screen a purely width-based hero size pushes the copy and the buttons off
     the bottom of the fold, which is where the conversion happens. */
  --t-hero:  clamp(3.1rem, min(11.4vw, 15.5vh), 10rem);
  --t-h1:    clamp(2.9rem, 8vw, 7rem);
  --t-h2:    clamp(2.4rem, 5.6vw, 5rem);
  --t-h3:    clamp(1.6rem, 2.8vw, 2.6rem);
  /* The lower bound of each clamp is the phone size, and it is the number that
     actually matters: it is what most visitors here will read. Body copy sits
     at 16px minimum — below that iOS zooms the page on any input focus, and
     long-form text becomes tiring on a small screen held at arm's length. */
  --t-lead:  clamp(1.12rem, 1.45vw, 1.35rem);
  --t-body:  clamp(1rem, 1.05vw, 1.06rem);
  --t-small: clamp(0.92rem, 1vw, 0.9rem);
  --t-micro: clamp(0.8rem, 0.9vw, 0.82rem);   /* captions, meta, list items */
  --t-eyebrow: clamp(0.7rem, 0.78vw, 0.74rem);

  /* Body weight. Inter at 350 is elegant on a large bright desktop display and
     genuinely hard to read on a phone in daylight; the mobile block below
     takes it to 400. */
  --w-body: 350;

  /* Rhythm */
  --gutter: clamp(1.25rem, 5vw, 5.5rem);
  --section: clamp(5.5rem, 13vh, 11rem);
  --maxw: 1500px;

  /* Motion */
  --ease:      cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io:   cubic-bezier(0.65, 0, 0.35, 1);
  --dur:       0.72s;
  --dur-slow:  1.15s;

  --nav-h: 84px;
}

@media (max-width: 860px) { :root { --nav-h: 68px; } }


/* ---------------------------------------------------------------------------
   2. Reset
   --------------------------------------------------------------------------- */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchors must not land under the fixed navigation. */
  scroll-padding-top: var(--nav-h);
}

/* Horizontal-overflow guard.
   ---------------------------------------------------------------------------
   `overflow-x: hidden` on the body alone is the usual reflex here, and it has
   two problems. It propagates to the viewport and turns the whole page into a
   scroll container, which silently breaks every `position: sticky` on the page
   — the navigation and the craft sequence both depend on it. And on iOS Safari
   it does not reliably stop the rubber-band pan anyway.

   `overflow-x: clip` clips without creating a scroll container, so sticky keeps
   working. It is applied to both elements because the propagation rules differ
   between browsers. The `hidden` fallback is kept for anything that predates `clip`. */
html, body {
  overflow-x: hidden;          /* fallback */
}
@supports (overflow: clip) {
  html, body {
    overflow-x: clip;
  }
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--ui);
  font-size: var(--t-body);
  font-weight: var(--w-body);
  line-height: 1.65;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, picture, canvas, svg, video {
  display: block;
  max-width: 100%;
}

button, input, select, textarea { font: inherit; color: inherit; }

a { color: inherit; text-decoration: none; }

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

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

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

.skip-link {
  position: absolute; top: 0; left: 50%; transform: translate(-50%, -120%);
  z-index: 2000; background: var(--ink); color: var(--paper);
  padding: 0.9rem 1.6rem; font-size: var(--t-small); letter-spacing: 0.08em;
  text-transform: uppercase; transition: transform 0.25s var(--ease);
}
.skip-link:focus { transform: translate(-50%, 0); }


/* ---------------------------------------------------------------------------
   3. Typography
   --------------------------------------------------------------------------- */

h1, h2, h3, h4, .display {
  font-family: var(--display);
  font-weight: 300;
  line-height: 0.95;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); line-height: 1.08; }

/* The italic is Cormorant's strongest asset. Used for the one word in a
   headline that carries the emotion, never for whole sentences. */
.em { font-style: italic; color: var(--gold); }
.em-light { font-style: italic; }

.eyebrow {
  font-family: var(--ui);
  font-size: var(--t-eyebrow);
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-text);
  display: flex;
  align-items: center;
  gap: 0.9rem;
}
.eyebrow::before {
  content: '';
  width: clamp(24px, 4vw, 56px);
  height: 1px;
  background: var(--gold);
  flex: none;
}
.eyebrow.is-plain::before { display: none; }

.lead {
  font-size: var(--t-lead);
  line-height: 1.6;
  color: var(--fg-muted);
  font-weight: 350;
  max-width: 46ch;
  text-wrap: pretty;
}

.tiny {
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--stone);
}

.note {
  font-size: var(--t-micro);
  line-height: 1.6;
  color: var(--stone-text);
  letter-spacing: 0.01em;
}


/* ---------------------------------------------------------------------------
   4. Layout primitives
   --------------------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section); position: relative; }

.section--tight { padding-block: clamp(4rem, 8vh, 7rem); }

/* Dark sections carry a faint film grain so large flat areas of near-black
   still feel like a material rather than an empty div. */
.section--dark,
.panel--dark {
  background: var(--ink);
  color: var(--ivory);
  --fg: var(--ivory);
  --fg-muted: var(--taupe);
  --rule: var(--rule-dark);
  position: relative;
}
.section--dark .eyebrow,
.panel--dark .eyebrow { color: var(--taupe); }

.grain::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: 0.035;
  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='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

.rule { height: 1px; background: var(--rule); border: 0; }

.grid {
  display: grid;
  gap: clamp(2rem, 4vw, 4.5rem);
}
.grid--split      { grid-template-columns: repeat(12, 1fr); align-items: center; }
.grid--split > .col-a { grid-column: 1 / span 5; }
.grid--split > .col-b { grid-column: 7 / span 6; }
.grid--split.is-flipped > .col-a { grid-column: 8 / span 5; order: 2; }
.grid--split.is-flipped > .col-b { grid-column: 1 / span 6; order: 1; }

@media (max-width: 900px) {
  .grid--split { grid-template-columns: 1fr; }
  .grid--split > .col-a,
  .grid--split > .col-b,
  .grid--split.is-flipped > .col-a,
  .grid--split.is-flipped > .col-b { grid-column: 1 / -1; order: initial; }
}

.stack { display: flex; flex-direction: column; }
.stack > * + * { margin-top: var(--gap, 1.6rem); }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-bottom: clamp(2.8rem, 6vw, 5.5rem);
}
.section-head .lead { max-width: 38ch; }


/* Flex and grid children default to `min-width: auto`, which means they refuse
   to shrink below their content — one long word or one wide image and the row
   pushes the page sideways. These are the containers whose children hold text
   or media that can outgrow a phone. */
.grid > *,
.section-head > *,
.hero__foot > *,
.footer__bottom > *,
.explorer > *,
.btn-row > * {
  min-width: 0;
}

/* No image or embed may ever be the thing that widens the page. */
img, picture, svg, video, canvas, iframe {
  max-width: 100%;
}

/* ---------------------------------------------------------------------------
   5. Motion — scroll reveals
   --------------------------------------------------------------------------- */

/* Applied by JS only when IntersectionObserver is available, so content is
   never trapped invisible if scripts fail. */
.js [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: opacity var(--dur-slow) var(--ease-out),
              transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--delay, 0ms);
  will-change: opacity, transform;
}
.js [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Headline word-by-word rise. JS wraps each word in .w > span. */
.js .split .w { display: inline-block; overflow: hidden; vertical-align: top; }
.js .split .w > span {
  display: inline-block;
  transform: translate3d(0, 105%, 0);
  transition: transform 1.05s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 52ms);
}
.js .split.is-in .w > span { transform: none; }

/* Image reveal: a curtain of the page background wipes away. */
.reveal-img { position: relative; overflow: hidden; }
.js .reveal-img::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--bg);
  transform-origin: right;
  transition: transform 1.1s var(--ease-out);
  transition-delay: var(--delay, 0ms);
}
.js .reveal-img.is-in::after { transform: scaleX(0); }
.section--dark .reveal-img::after { background: var(--ink); }

.parallax { will-change: transform; }


/* ---------------------------------------------------------------------------
   6. Buttons
   --------------------------------------------------------------------------- */

.btn {
  --btn-fg: var(--ink);
  --btn-bg: transparent;
  --btn-line: currentColor;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  padding: 1.05rem 2rem;
  min-height: 52px;
  font-family: var(--ui);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-line);
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease);
  -webkit-tap-highlight-color: transparent;
}

/* The fill wipes up from the bottom rather than fading — it reads as a
   material surface sliding into place. */
.btn::before {
  content: '';
  position: absolute; inset: 0;
  background: var(--btn-fill, var(--ink));
  transform: translate3d(0, 101%, 0);
  transition: transform 0.55s var(--ease-out);
  z-index: -1;
}
.btn:hover::before,
.btn:focus-visible::before { transform: none; }

.btn__arrow { transition: transform 0.5s var(--ease-out); }
.btn:hover .btn__arrow { transform: translateX(5px); }

.btn--solid {
  --btn-fg: var(--paper);
  --btn-bg: var(--ink);
  --btn-line: var(--ink);
  --btn-fill: var(--gold);
}
.btn--solid:hover { color: var(--ink); border-color: var(--gold); }

.btn--gold {
  --btn-fg: var(--ink);
  --btn-bg: var(--gold);
  --btn-line: var(--gold);
  --btn-fill: var(--ink);
}
.btn--gold:hover { color: var(--paper); }

/* Sits on dark ground only — over the hero and inside dark sections. It has
   to declare its own foreground, otherwise it inherits the light-background
   default and disappears into the stone. */
.btn--ghost {
  --btn-fg: var(--ivory);
  --btn-line: rgba(244, 240, 232, 0.55);
  --btn-fill: var(--ivory);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  background: rgba(19, 18, 16, 0.28);
}
.btn--ghost:hover { color: var(--ink); border-color: var(--ivory); }

.btn--light {
  --btn-fg: var(--ivory);
  --btn-line: rgba(244, 240, 232, 0.4);
  --btn-fill: var(--ivory);
}
.btn--light:hover { color: var(--ink); border-color: var(--ivory); }

.btn--sm { padding: 0.8rem 1.4rem; min-height: 44px; font-size: 0.72rem; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  align-items: center;
}

/* WhatsApp glyph, drawn rather than loaded. */
.ico-wa { width: 17px; height: 17px; fill: currentColor; flex: none; }

/* Text link with a rule that draws in from the left. */
.link {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding-bottom: 0.4rem;
  position: relative;
}
.link::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform 0.5s var(--ease-out);
}
.link:hover::after { transform: scaleX(1); transform-origin: left; }


/* ---------------------------------------------------------------------------
   7. Navigation
   --------------------------------------------------------------------------- */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 900;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  color: var(--ivory);
  transition: background 0.5s var(--ease), color 0.5s var(--ease),
              box-shadow 0.5s var(--ease), transform 0.5s var(--ease);
}
.nav::after {
  content: '';
  position: absolute; inset: auto 0 0 0; height: 1px;
  background: var(--rule-dark);
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}

/* Over the hero the bar is transparent with a soft scrim for legibility. */
.nav:not(.is-stuck) {
  background: linear-gradient(to bottom,
              rgba(10, 9, 8, 0.55), rgba(10, 9, 8, 0));
}
.nav.is-stuck {
  background: rgba(19, 18, 16, 0.92);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  backdrop-filter: saturate(140%) blur(14px);
}
.nav.is-stuck::after { opacity: 1; }

/* Hide on scroll down, show on scroll up — more room for the content. */
.nav.is-hidden { transform: translateY(-100%); }

.nav__inner {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 3rem);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex: none;
  margin-right: auto;
}
.brand__mark {
  width: 40px; height: 40px;
  flex: none;
  object-fit: contain;
}
.brand__type { display: flex; flex-direction: column; line-height: 1; }
.brand__name {
  font-family: var(--display);
  font-size: 1.32rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.brand__sub {
  font-family: var(--ui);
  font-size: 0.52rem;
  font-weight: 500;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--gold-lit);
  margin-top: 0.28rem;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2.1vw, 2.2rem);
  list-style: none;
  padding: 0;
}
.nav__links a {
  position: relative;
  font-size: 0.76rem;
  font-weight: 400;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  padding-block: 0.5rem;
  opacity: 0.82;
  transition: opacity 0.35s var(--ease);
}
.nav__links a::after {
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--gold-lit);
  transform: scaleX(0); transform-origin: right;
  transition: transform 0.45s var(--ease-out);
}
.nav__links a:hover { opacity: 1; }
.nav__links a:hover::after,
.nav__links a[aria-current='true']::after {
  transform: scaleX(1); transform-origin: left;
}
.nav__links a[aria-current='true'] { opacity: 1; }

.nav__cta { flex: none; }

.nav__toggle {
  display: none;
  width: 46px; height: 46px;
  background: none; border: 0; cursor: pointer;
  padding: 0; flex: none;
  align-items: center; justify-content: center;
}
.nav__toggle span {
  display: block;
  width: 24px; height: 1px;
  background: currentColor;
  position: relative;
  transition: background 0.3s var(--ease);
}
.nav__toggle span::before,
.nav__toggle span::after {
  content: ''; position: absolute; left: 0;
  width: 24px; height: 1px; background: currentColor;
  transition: transform 0.42s var(--ease-out);
}
.nav__toggle span::before { top: -7px; }
.nav__toggle span::after  { top: 7px; }
.nav__toggle[aria-expanded='true'] span { background: transparent; }
.nav__toggle[aria-expanded='true'] span::before { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded='true'] span::after  { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 1060px) {
  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: flex; }
  .brand__mark { width: 34px; height: 34px; }
  .brand__name { font-size: 1.1rem; }
}

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

.drawer {
  position: fixed; inset: 0;
  z-index: 890;
  background: var(--ink);
  color: var(--ivory);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(var(--nav-h) + 2rem) var(--gutter) 2rem;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.72s var(--ease-out);
  visibility: hidden;
  overflow-y: auto;
}
.drawer.is-open { clip-path: inset(0 0 0 0); visibility: visible; }

.drawer__links { list-style: none; padding: 0; }
.drawer__links li { overflow: hidden; }
.drawer__links a {
  display: block;
  font-family: var(--display);
  font-size: clamp(2rem, 9vw, 3.4rem);
  font-weight: 300;
  line-height: 1.28;
  letter-spacing: -0.01em;
  transform: translateY(105%);
  transition: transform 0.7s var(--ease-out), color 0.3s var(--ease);
  transition-delay: calc(var(--i) * 45ms);
}
.drawer.is-open .drawer__links a { transform: none; }
.drawer__links a:active { color: var(--gold-lit); }

.drawer__foot {
  margin-top: clamp(2rem, 6vh, 3.5rem);
  padding-top: 1.8rem;
  border-top: 1px solid var(--rule-dark);
  display: grid;
  gap: 1.1rem;
  opacity: 0;
  transition: opacity 0.5s var(--ease) 0.4s;
}
.drawer.is-open .drawer__foot { opacity: 1; }


/* ---------------------------------------------------------------------------
   8. Hero
   --------------------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  background: var(--ink);
  color: var(--ivory);
  overflow: hidden;
  isolation: isolate;
}

/* Layer 0 — the stage. A pool of warm light on a dark ground, so the slab
   appears to sit in a lit showroom rather than float in a void. */
.hero__stage {
  position: absolute; inset: 0;
  z-index: -3;
  background:
    radial-gradient(120% 85% at 62% 34%,
      rgba(90, 78, 60, 0.55) 0%,
      rgba(38, 33, 27, 0.55) 42%,
      rgba(12, 11, 10, 0.9) 78%),
    var(--ink);
}

/* Layer 1 — the poster. This is the LCP element: a still frame of the same
   scene the WebGL renderer draws, so first paint is instant and the upgrade
   to 3D is invisible. */
.hero__poster {
  position: absolute; inset: 0;
  z-index: -2;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 42%;
  transition: opacity 1.1s var(--ease);
}
.hero.is-live .hero__poster { opacity: 0; }

/* Layer 2 — the WebGL canvas, only ever inserted on capable devices. */
.hero__canvas {
  position: absolute; inset: 0;
  z-index: -2;
  width: 100%; height: 100%;
  opacity: 0;
  transition: opacity 1.3s var(--ease);
}
.hero.is-live .hero__canvas { opacity: 1; }

/* Layer 3 — a scrim so type stays legible over whatever the stone is doing. */
.hero__scrim {
  position: absolute; inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(10, 9, 8, 0.94) 0%,
    rgba(10, 9, 8, 0.68) 26%,
    rgba(10, 9, 8, 0.12) 58%,
    rgba(10, 9, 8, 0.45) 100%);
}

.hero__inner {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  /* The bottom padding has to clear the scroll cue, which is absolutely
     positioned inside the same box. */
  padding: calc(var(--nav-h) + 3rem) var(--gutter) clamp(4.5rem, 11vh, 7rem);
}

/* Sits directly over the lit face of the slab, where taupe-on-white vanishes.
   Bright enough to read against the brightest part of the poster. */
.hero__eyebrow {
  color: rgba(244, 240, 232, 0.92);
  margin-bottom: clamp(1.4rem, 3vh, 2.4rem);
  text-shadow: 0 1px 12px rgba(8, 7, 6, 0.75);
}
.hero__eyebrow::before { background: var(--gold-lit); }

.hero__badge span { text-shadow: 0 1px 10px rgba(8, 7, 6, 0.7); }

.hero__title {
  font-size: var(--t-hero);
  font-weight: 300;
  line-height: 0.86;
  letter-spacing: -0.035em;
  margin-bottom: clamp(1.6rem, 3.5vh, 2.6rem);
  max-width: 14ch;
}
.hero__title .em { color: var(--gold-lit); }

.hero__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1.5rem, 4vw, 3.5rem);
}

.hero__copy {
  max-width: 40ch;
  color: rgba(244, 240, 232, 0.78);
  font-size: var(--t-lead);
  line-height: 1.6;
}

.hero__badge {
  display: inline-flex;
  align-items: baseline;
  gap: 0.7rem;
  margin-bottom: 1.6rem;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid var(--gold-dim);
}
.hero__badge b {
  font-family: var(--display);
  font-size: 2.1rem;
  font-weight: 400;
  color: var(--gold-lit);
  line-height: 1;
}
.hero__badge span {
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--taupe);
}

.hero__scroll {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1.4rem, 3.5vh, 2.2rem);
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-size: 0.62rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(244, 240, 232, 0.5);
  pointer-events: none;
}
.hero__scroll i {
  display: block; width: 1px; height: 34px;
  background: linear-gradient(to bottom, var(--gold-lit), transparent);
  transform-origin: top;
  animation: drop 2.6s var(--ease-io) infinite;
}
@keyframes drop {
  0%          { transform: scaleY(0); opacity: 0; }
  30%         { transform: scaleY(1); opacity: 1; }
  70%, 100%   { transform: scaleY(1) translateY(34px); opacity: 0; }
}

@media (max-aspect-ratio: 4/5) {
  /* The portrait poster puts the slab in the upper third; keep it there. */
  .hero__poster { object-position: center 30%; }
  .hero__scrim {
    background: linear-gradient(
      to top,
      rgba(10, 9, 8, 0.96) 0%,
      rgba(10, 9, 8, 0.86) 34%,
      rgba(10, 9, 8, 0.30) 62%,
      rgba(10, 9, 8, 0.40) 100%);
  }
}

@media (max-width: 700px) {
  .hero { align-items: flex-end; }
  .hero__scroll { display: none; }
  .hero__title { max-width: 11ch; }
  .hero__inner { padding-bottom: clamp(2.5rem, 6vh, 4rem); }
}


/* ---------------------------------------------------------------------------
   9. Ticker
   --------------------------------------------------------------------------- */

.ticker {
  background: var(--ink);
  color: var(--taupe);
  border-top: 1px solid var(--rule-dark);
  border-bottom: 1px solid var(--rule-dark);
  overflow: hidden;
  padding-block: 1.15rem;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 12%, #000 88%, transparent);
}
.ticker__track {
  display: flex;
  width: max-content;
  animation: slide 46s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
.ticker__group { display: flex; flex: none; }
.ticker span {
  display: inline-flex;
  align-items: center;
  gap: 2.6rem;
  padding-inline: 1.3rem;
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
}
.ticker span::after {
  content: '';
  width: 4px; height: 4px;
  background: var(--gold);
  transform: rotate(45deg);
}
@keyframes slide { to { transform: translate3d(-50%, 0, 0); } }


/* ---------------------------------------------------------------------------
   10. Editorial split — "Every surface tells a story"
   --------------------------------------------------------------------------- */

.editorial__figure {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: var(--sand);
}
.editorial__figure img {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.14);
  will-change: transform;
}
.editorial__caption {
  position: absolute;
  left: 0; bottom: 0;
  background: var(--paper);
  padding: 0.9rem 1.3rem 0.9rem 0;
  max-width: 62%;
}
.editorial__quote {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.4vw, 2.2rem);
  font-weight: 300;
  font-style: italic;
  line-height: 1.24;
  color: var(--slate);
  padding-left: clamp(1.2rem, 2.5vw, 2rem);
  border-left: 1px solid var(--gold);
  margin-top: 0.5rem;
}


/* ---------------------------------------------------------------------------
   11. Experience figures
   --------------------------------------------------------------------------- */

.figures {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-top: 1px solid var(--rule);
}
.figures__item {
  padding: clamp(2rem, 4vw, 3.4rem) clamp(1rem, 2vw, 2rem)
           clamp(2rem, 4vw, 3.4rem) 0;
  border-right: 1px solid var(--rule);
}
.figures__item:last-child { border-right: 0; }
.figures__n {
  font-family: var(--display);
  font-size: clamp(2.6rem, 5.5vw, 4.6rem);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: -0.03em;
  margin-bottom: 0.9rem;
}
.figures__n em { font-style: italic; color: var(--gold); }
.figures__l {
  font-size: 0.78rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--stone-text);
  line-height: 1.6;
}

@media (max-width: 820px) {
  .figures { grid-template-columns: repeat(2, 1fr); }
  .figures__item:nth-child(2n) { border-right: 0; }
  .figures__item:nth-child(-n+2) { border-bottom: 1px solid var(--rule); }
  .figures__item { padding-right: 1rem; }
}
@media (max-width: 560px) {
  /* "End–to–End" is the longest of the four and will not fit at the desktop
     size in a half-width column; the dashes are not break opportunities. */
  .figures__n {
    font-size: clamp(1.75rem, 7.6vw, 2.5rem);
    overflow-wrap: anywhere;
  }
}


/* ---------------------------------------------------------------------------
   12. Stone collection
   --------------------------------------------------------------------------- */

.collection {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(0.9rem, 1.6vw, 1.6rem);
}
/* Deliberately uneven: a regular grid of equal cards is the single strongest
   signal of a template. */
.collection__item:nth-child(1) { grid-column: span 4; aspect-ratio: 16 / 11; }
.collection__item:nth-child(2) { grid-column: span 2; aspect-ratio: 3 / 4; }
.collection__item:nth-child(3) { grid-column: span 2; aspect-ratio: 3 / 4; }
.collection__item:nth-child(4) { grid-column: span 2; aspect-ratio: 3 / 4; }
.collection__item:nth-child(5) { grid-column: span 2; aspect-ratio: 3 / 4; }

.collection__item {
  position: relative;
  overflow: hidden;
  background: var(--ink-2);
  display: block;
  isolation: isolate;
}
.collection__item img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.25s var(--ease-out), filter 0.8s var(--ease);
  will-change: transform;
}
/* The scrim has to hold white text over white marble as well as over black
   granite, so it is weighted for the worst case rather than the average. */
.collection__item::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(to top,
    rgba(8, 7, 6, 0.96) 0%,
    rgba(8, 7, 6, 0.86) 22%,
    rgba(8, 7, 6, 0.52) 46%,
    rgba(8, 7, 6, 0.12) 74%,
    rgba(8, 7, 6, 0) 100%);
  transition: opacity 0.7s var(--ease);
}
.collection__item:hover img { transform: scale(1.07); }
.collection__item:hover::after { opacity: 0.86; }

.collection__body {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 2;
  padding: clamp(1.2rem, 2.2vw, 2.2rem);
  color: var(--ivory);
}
.collection__name {
  font-family: var(--display);
  font-size: clamp(1.5rem, 2.5vw, 2.4rem);
  font-weight: 300;
  line-height: 1.05;
  margin-bottom: 0.45rem;
}
.collection__desc {
  font-size: var(--t-micro);
  line-height: 1.5;
  color: rgba(244, 240, 232, 0.86);
  max-width: 34ch;
}
.collection__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold-lit);
  opacity: 0;
  transform: translateY(9px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease-out);
}
.collection__item:hover .collection__cta,
.collection__item:focus-visible .collection__cta { opacity: 1; transform: none; }

/* Touch devices never fire hover, so the call to action must always show. */
@media (hover: none) {
  .collection__cta { opacity: 1; transform: none; }
}

@media (max-width: 900px) {
  .collection { grid-template-columns: repeat(2, 1fr); }
  .collection__item:nth-child(1) { grid-column: span 2; aspect-ratio: 16 / 10; }
  .collection__item:nth-child(n+2) { grid-column: span 1; aspect-ratio: 3 / 4; }
}
@media (max-width: 520px) {
  .collection { grid-template-columns: 1fr; }
  .collection__item:nth-child(n) { grid-column: span 1; aspect-ratio: 4 / 3; }
}


/* ---------------------------------------------------------------------------
   13. Stone explorer
   --------------------------------------------------------------------------- */

.explorer {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 4vw, 4.5rem);
  align-items: start;
}

.filters { display: grid; gap: clamp(1.5rem, 3vw, 2.4rem); }
.filter__label {
  font-size: 0.74rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--stone-text);
  margin-bottom: 0.9rem;
}
.filter__opts { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.chip {
  padding: 0.62rem 1.15rem;
  min-height: 42px;
  display: inline-flex;
  align-items: center;
  font-size: 0.76rem;
  letter-spacing: 0.06em;
  color: var(--fg-muted);
  background: transparent;
  border: 1px solid var(--rule);
  cursor: pointer;
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease),
              background 0.35s var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.chip:hover { border-color: var(--taupe); color: var(--fg); }
.chip[aria-pressed='true'] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}
.section--dark .chip[aria-pressed='true'] {
  background: var(--gold); border-color: var(--gold); color: var(--ink);
}

.explorer__reset {
  margin-top: 0.4rem;
  background: none; border: 0; padding: 0.4rem 0;
  cursor: pointer;
  font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--stone);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.explorer__reset:hover { color: var(--fg); }

.explorer__stage { position: relative; }
.explorer__view {
  position: relative;
  aspect-ratio: 5 / 4;
  overflow: hidden;
  background: var(--ink-2);
}
.explorer__view img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.06);
  transition: opacity 0.85s var(--ease), transform 1.6s var(--ease-out);
}
.explorer__view img.is-active { opacity: 1; transform: scale(1); }

.explorer__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.2rem;
  padding-top: 1.5rem;
  margin-top: 1.5rem;
  border-top: 1px solid var(--rule);
}
.explorer__name {
  font-family: var(--display);
  font-size: clamp(1.7rem, 3vw, 2.6rem);
  font-weight: 300;
  line-height: 1.06;
}
.explorer__note { font-size: var(--t-small); color: var(--fg-muted); max-width: 40ch; }
.explorer__count {
  font-size: 0.74rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--stone-text);
}

.explorer__thumbs {
  display: flex;
  gap: 0.5rem;
  margin-top: 1.3rem;
  overflow-x: auto;
  scrollbar-width: thin;
  padding-bottom: 0.4rem;
  -webkit-overflow-scrolling: touch;
}
.thumb {
  flex: none;
  width: 68px; height: 68px;
  padding: 0; border: 1px solid transparent;
  background: none; cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.35s var(--ease), border-color 0.35s var(--ease);
  position: relative;
}
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb:hover { opacity: 0.85; }
.thumb[aria-pressed='true'] { opacity: 1; border-color: var(--gold); }

.explorer__empty {
  padding: 1.4rem 0;
  font-size: var(--t-small);
  color: var(--fg-muted);
}

@media (max-width: 900px) {
  .explorer { grid-template-columns: 1fr; }
  .explorer__stage { order: -1; }
}


/* ---------------------------------------------------------------------------
   14. Process — "From Slab to Space"
   --------------------------------------------------------------------------- */

.process { position: relative; }

.process__rail {
  display: flex;
  gap: clamp(1rem, 2vw, 2rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 1.5rem;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.process__rail::-webkit-scrollbar { display: none; }

.step {
  flex: none;
  width: clamp(230px, 26vw, 330px);
  scroll-snap-align: start;
  padding-top: 2rem;
  border-top: 1px solid var(--rule-dark);
  position: relative;
}
.step::before {
  content: '';
  position: absolute; top: -1px; left: 0;
  width: 0; height: 1px;
  background: var(--gold);
  transition: width 1s var(--ease-out);
  transition-delay: var(--delay, 0ms);
}
.step.is-in::before { width: 100%; }

.step__n {
  font-family: var(--ui);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  color: var(--gold);
  margin-bottom: 1.4rem;
  display: block;
}
.step__t {
  font-family: var(--display);
  font-size: clamp(1.4rem, 2.2vw, 2rem);
  font-weight: 300;
  line-height: 1.1;
  margin-bottom: 0.7rem;
}
.step__d { font-size: var(--t-small); line-height: 1.6; color: var(--taupe); }

.process__hint {
  display: flex; align-items: center; gap: 0.7rem;
  margin-top: 1.6rem;
  font-size: 0.66rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--stone);
}
@media (min-width: 1100px) { .process__hint { display: none; } }


/* ---------------------------------------------------------------------------
   15. Craft sequence — raw stone becoming a finished surface
   --------------------------------------------------------------------------- */

/* Driven by a --p custom property (0 → 1) that JS updates from scroll
   position. Everything below is pure CSS reacting to that one number. */
.craft { position: relative; height: 340vh; }

.craft__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  /* minmax(0, 1fr), not 1fr. A grid track sized `1fr` still refuses to shrink
     below its content's min-content height, so on a short viewport — a laptop
     with a small window, a phone in landscape — the slab kept its full height,
     overflowed the track and rode up over the headline. minmax(0, …) lets the
     middle row give way instead. */
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: clamp(1rem, 3vh, 2rem);
  padding-block: clamp(4.5rem, 10vh, 7rem) clamp(2rem, 5vh, 3.5rem);
  overflow: hidden;
}

.craft__slab {
  position: relative;
  justify-self: center;
  /* Stretch to whatever height the row actually has, rather than asserting an
     aspect ratio the viewport may not be able to honour. The image inside is
     absolutely positioned with object-fit: cover, so it stays composed at any
     shape and the slab can never be the thing that overflows. */
  align-self: stretch;
  width: min(78vw, 940px);
  min-height: 0;
  max-height: 100%;
  /* Keeps the pleasing proportion whenever there is room for it. */
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--ink-2);
}

/* When the viewport is too short for the full 16:9, drop the ratio entirely and
   let the row decide. Below this the slab is a letterbox rather than a
   rectangle — still legible, and never overlapping. */
@media (max-height: 720px) {
  .craft__slab { aspect-ratio: auto; }
}
.craft__slab img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Raw → polished: saturation, contrast and brightness all climb. */
  filter:
    saturate(calc(0.42 + var(--p, 0) * 0.72))
    contrast(calc(0.86 + var(--p, 0) * 0.42))
    brightness(calc(0.74 + var(--p, 0) * 0.4));
  transform: scale(calc(1.1 - var(--p, 0) * 0.1));
  transition: filter 0.25s linear, transform 0.25s linear;
}

/* Dust and roughness on the raw stone, dissolving as it is worked. */
.craft__dust {
  position: absolute; inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.6' numOctaves='4'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23d)'/%3E%3C/svg%3E");
  mix-blend-mode: soft-light;
  opacity: calc(0.55 - var(--p, 0) * 0.55);
  transition: opacity 0.25s linear;
}

/* The saw pass: a hairline of light travelling across the slab. */
.craft__cut {
  position: absolute; top: 0; bottom: 0;
  left: calc(var(--p, 0) * 340% - 40%);
  width: 2px;
  background: linear-gradient(to bottom,
    transparent, var(--gold-lit) 18%, #fff 50%, var(--gold-lit) 82%, transparent);
  box-shadow: 0 0 26px 5px rgba(203, 171, 106, 0.55);
  opacity: clamp(0, calc((var(--p, 0) - 0.18) * 7), 1);
  transition: left 0.25s linear, opacity 0.25s linear;
}
.craft__cut::after {
  content: '';
  position: absolute; top: 40%; left: -3px;
  width: 8px; height: 20%;
  background: rgba(255, 255, 255, 0.9);
  filter: blur(6px);
}

/* The polish pass: a broad specular sweep that only appears once the surface
   has been honed, and lingers as a permanent sheen. */
.craft__sheen {
  position: absolute; inset: 0;
  background: linear-gradient(
    108deg,
    transparent 0%,
    rgba(255, 252, 244, 0.05) 34%,
    rgba(255, 252, 244, 0.42) 48%,
    rgba(255, 252, 244, 0.06) 62%,
    transparent 100%);
  transform: translate3d(calc(-120% + var(--p, 0) * 220%), 0, 0);
  opacity: clamp(0, calc((var(--p, 0) - 0.45) * 3.2), 0.9);
  mix-blend-mode: screen;
  transition: transform 0.25s linear, opacity 0.25s linear;
}

/* A chamfered edge appears once the slab has been cut and finished. */
.craft__edge {
  position: absolute; inset: 0;
  border: 1px solid rgba(203, 171, 106, 0);
  box-shadow:
    inset 0 0 0 0 rgba(255, 255, 255, 0),
    inset 0 -60px 90px -60px rgba(0, 0, 0, 0.85);
  transition: border-color 0.3s linear;
  pointer-events: none;
}
.craft.is-finished .craft__edge {
  border-color: rgba(203, 171, 106, 0.5);
}

.craft__stages {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(0.6rem, 2vw, 2rem);
  align-items: start;
  border-top: 1px solid var(--rule-dark);
  padding-top: 1.3rem;
}
.craft__stage {
  opacity: 0.3;
  transition: opacity 0.45s var(--ease);
  position: relative;
  padding-top: 1rem;
}
.craft__stage::before {
  content: '';
  position: absolute; top: -1px; left: 0; right: 0;
  height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.6s var(--ease-out);
}
.craft__stage.is-on { opacity: 1; }
.craft__stage.is-on::before { transform: scaleX(1); }
.craft__stage b {
  display: block;
  font-family: var(--display);
  font-size: clamp(1rem, 1.8vw, 1.55rem);
  font-weight: 400;
  line-height: 1.15;
  margin-bottom: 0.3rem;
}
.craft__stage span { font-size: 0.72rem; color: var(--taupe); line-height: 1.5; }

.craft__head {
  text-align: center;
  position: relative;
  z-index: 2;          /* the words always win over the picture */
}
.craft__head .eyebrow { justify-content: center; }

@media (max-width: 700px) {
  .craft { height: 300vh; }
  /* Was 90vw, which ignores the wrapper's own gutter and spills past it
     on narrow screens. The parent is already width-constrained, and the row
     governs the height. */
  .craft__slab { width: 100%; aspect-ratio: 4 / 3; }
  .craft__stages { grid-template-columns: repeat(2, 1fr); gap: 0.9rem 1rem; }
  .craft__stage span { display: none; }
}


/* ---------------------------------------------------------------------------
   16. Gallery
   --------------------------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(0.7rem, 1.4vw, 1.4rem);
}
.gallery__cell { position: relative; overflow: hidden; background: var(--sand); }
.gallery__cell img,
.gallery__cell .slot {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.2s var(--ease-out);
}
.gallery__cell:hover img { transform: scale(1.05); }

/* Asymmetric editorial rhythm rather than an even masonry. */
.gallery__cell:nth-child(1) { grid-column: span 5; aspect-ratio: 4 / 5; }
.gallery__cell:nth-child(2) { grid-column: span 7; aspect-ratio: 16 / 11; }
.gallery__cell:nth-child(3) { grid-column: span 4; aspect-ratio: 1 / 1; }
.gallery__cell:nth-child(4) { grid-column: span 4; aspect-ratio: 1 / 1; }
.gallery__cell:nth-child(5) { grid-column: span 4; aspect-ratio: 1 / 1; }
.gallery__cell:nth-child(6) { grid-column: span 7; aspect-ratio: 16 / 10; }
.gallery__cell:nth-child(7) { grid-column: span 5; aspect-ratio: 4 / 5; }

/* Labelled placeholder card.
   Currently unused: every gallery and social tile now holds a real photograph
   of the business. Kept because it is the correct pattern for any future
   section that is waiting on real material — an unlabelled stand-in is how
   sites end up quietly passing stock imagery off as their own work. */
.slot {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.4rem;
  padding: clamp(1rem, 2vw, 1.7rem);
  position: relative;
  isolation: isolate;
  min-height: 100%;
  color: var(--ivory);
  background: var(--ink-2);
}
.slot__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(0.72) brightness(0.62);
}
.slot::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(10, 9, 8, 0.9), rgba(10, 9, 8, 0.25));
}
.slot__tag {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--gold-lit);
  padding: 0.28rem 0.6rem;
  margin-bottom: 0.5rem;
}
.slot__t {
  font-family: var(--display);
  font-size: clamp(1.1rem, 1.9vw, 1.6rem);
  font-weight: 300;
  line-height: 1.15;
}
.slot__d { font-size: 0.74rem; color: rgba(244, 240, 232, 0.65); line-height: 1.5; }

@media (max-width: 900px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .gallery__cell:nth-child(n) { grid-column: span 1; aspect-ratio: 1 / 1; }
  .gallery__cell:nth-child(2) { grid-column: span 2; aspect-ratio: 16 / 10; }
  .gallery__cell:nth-child(6) { grid-column: span 2; aspect-ratio: 16 / 10; }
}
@media (max-width: 520px) {
  .gallery__cell:nth-child(n) { grid-column: span 2; aspect-ratio: 4 / 3; }
}


/* ---------------------------------------------------------------------------
   17. About
   --------------------------------------------------------------------------- */

.about__body { --gap: 1.35rem; max-width: 54ch; }
.about__body p { color: var(--fg-muted); }
.about__body p:first-child {
  font-size: var(--t-lead);
  color: var(--fg);
}
/* A drop cap sets an editorial register no amount of decoration can fake. */
.about__body p:first-child::first-letter {
  float: left;
  font-family: var(--display);
  font-size: 4.1em;
  line-height: 0.78;
  font-weight: 300;
  padding: 0.06em 0.14em 0 0;
  color: var(--gold);
}

.about__figure { position: relative; }
.about__figure img,
.about__video {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--sand);
}
/* The poster and the first frame are the same image, so there is no jump when
   playback starts — the picture simply begins to move. */
.about__video { transition: opacity 0.5s var(--ease); }
.about__sign {
  position: absolute;
  /* Overhangs the image on purpose. Kept to a fixed, modest amount: a vw-based
     negative offset can push past the page gutter and create a horizontal
     scrollbar at in-between widths. */
  right: -1.5rem;
  bottom: clamp(1.5rem, 4vw, 3rem);
  background: var(--paper);
  padding: 1.3rem 1.6rem;
  max-width: 260px;
  border-left: 1px solid var(--gold);
}
.about__sign b {
  display: block;
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 400;
  margin-bottom: 0.15rem;
}
@media (max-width: 900px) { .about__sign { position: static; margin-top: 1.2rem; max-width: none; } }


/* ---------------------------------------------------------------------------
   18. Why choose us
   --------------------------------------------------------------------------- */

.reasons { border-top: 1px solid var(--rule); }
.reasons__row {
  display: grid;
  grid-template-columns: 5rem minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(1rem, 3vw, 3rem);
  align-items: baseline;
  padding-block: clamp(1.5rem, 3vw, 2.4rem);
  border-bottom: 1px solid var(--rule);
  transition: background 0.5s var(--ease), padding-inline 0.5s var(--ease);
}
.reasons__row:hover { background: rgba(244, 240, 232, 0.04); }
.reasons__n {
  font-size: 0.66rem; letter-spacing: 0.22em; color: var(--gold);
}
.reasons__t {
  font-family: var(--display);
  font-size: clamp(1.4rem, 2.5vw, 2.15rem);
  font-weight: 300;
  line-height: 1.12;
}
.reasons__d { font-size: var(--t-small); color: var(--fg-muted); line-height: 1.62; }

@media (max-width: 760px) {
  .reasons__row { grid-template-columns: 3rem 1fr; gap: 0.8rem 1.2rem; }
  .reasons__d { grid-column: 2; }
}


/* ---------------------------------------------------------------------------
   19. Testimonials
   --------------------------------------------------------------------------- */

.reviews { position: relative; overflow: hidden; }
.reviews__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(0.3) saturate(0.6);
  z-index: -2;
}
.reviews::before {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: rgba(10, 9, 8, 0.55);
}

/* The rating block.
   ---------------------------------------------------------------------------
   This replaced a three-quote carousel. The carousel was the better-looking
   component, but it needed words nobody had written: four customers rated the
   business on Google and none of them left text. A real, checkable number with
   a link to the source is worth more than an invented sentence, and it is the
   only version of this section that survives a sceptical visitor clicking
   through. */

.rating {
  text-align: center;
  display: grid;
  justify-items: center;
  gap: 0.5rem;
}
.rating__score {
  font-family: var(--display);
  font-size: clamp(4rem, 11vw, 7.5rem);
  font-weight: 300;
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: var(--ivory);
}
.rating__stars {
  color: var(--gold-lit);
  font-size: clamp(1.1rem, 2.2vw, 1.6rem);
  letter-spacing: 0.24em;
  /* The tracking pushes the row off-centre; pull it back by one gap. */
  text-indent: 0.24em;
}
.rating__meta {
  font-size: var(--t-small);
  color: var(--taupe);
  margin-bottom: 1.4rem;
}
.rating__meta strong { color: var(--ivory); font-weight: 500; }

/* The four people who actually rated the business. */
.raters {
  list-style: none;
  padding: 0;
  margin: clamp(2.5rem, 5vw, 3.5rem) auto 0;
  max-width: 640px;
  display: grid;
  gap: 1px;
  background: var(--rule-dark);
  border-block: 1px solid var(--rule-dark);
}
.rater {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.95rem 0.2rem;
  background: var(--ink);
}
.rater__name {
  font-family: var(--display);
  font-size: clamp(1.05rem, 1.8vw, 1.3rem);
  font-weight: 400;
  color: var(--ivory);
}
.rater__stars {
  color: var(--gold-lit);
  letter-spacing: 0.16em;
  font-size: 0.9rem;
  flex: none;
}

@media (max-width: 520px) {
  .rater { padding-inline: 0; }
  .rater__stars { font-size: 0.82rem; }
}


/* The placeholder banner is deliberately visible: it tells the owner exactly
   what to replace and stops the site from asserting reviews it doesn't have. */
.placeholder-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.7rem 1.1rem;
  margin-top: clamp(2.2rem, 5vw, 3.5rem);
  padding: 0.85rem 1.2rem;
  border: 1px dashed var(--gold-dim);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  color: var(--taupe);
  justify-content: center;
  text-align: center;
}
.placeholder-bar b {
  color: var(--gold-lit); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.64rem;
}


/* ---------------------------------------------------------------------------
   20. Location
   --------------------------------------------------------------------------- */

.map {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--ink-2);
  overflow: hidden;
}
.map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* The embed is only loaded when the visitor asks for it: a Google Maps iframe
   is several hundred kilobytes and third-party cookies, which is a poor trade
   for a section most visitors scroll past. */
.map__consent {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 1.1rem; text-align: center;
  padding: 2rem;
  color: var(--ivory);
  background: var(--ink-2);
  cursor: pointer;
  border: 0;
  width: 100%;
}
.map__consent img {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover;
  opacity: 0.24; filter: grayscale(1);
}
.map__consent > * { position: relative; z-index: 1; }
.map__pin {
  width: 34px; height: 34px;
  border: 1px solid var(--gold);
  transform: rotate(45deg);
  position: relative; z-index: 1;
}
.map__pin::after {
  content: ''; position: absolute; inset: 11px;
  background: var(--gold);
}

.hours {
  display: flex; align-items: center; gap: 0.7rem;
  font-size: var(--t-small);
}
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--stone); flex: none;
  position: relative;
}
.dot.is-open { background: #4c9a6a; }
.dot.is-open::after {
  content: ''; position: absolute; inset: -4px;
  border-radius: 50%; border: 1px solid #4c9a6a;
  animation: pulse 2.4s var(--ease-io) infinite;
}
@keyframes pulse {
  0%   { transform: scale(0.7); opacity: 0.9; }
  100% { transform: scale(1.7); opacity: 0; }
}

.info-list { list-style: none; padding: 0; display: grid; gap: 1.5rem; }
.info-list dt,
.info-list .k {
  font-size: 0.7rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--stone-text); margin-bottom: 0.4rem;
}
.info-list .v { font-size: 1rem; line-height: 1.6; }
.info-list a.v:hover { color: var(--gold); }


/* ---------------------------------------------------------------------------
   21. Contact
   --------------------------------------------------------------------------- */

.contact__actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  border-top: 1px solid var(--rule);
  margin-top: clamp(2.5rem, 5vw, 4rem);
}
.action {
  display: block;
  padding: clamp(1.6rem, 3vw, 2.4rem) clamp(1rem, 2vw, 1.8rem)
           clamp(1.6rem, 3vw, 2.4rem) 0;
  border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
  position: relative;
  transition: padding-left 0.5s var(--ease-out);
}
.action:last-child { border-right: 0; }
.action:hover { padding-left: 0.8rem; }
.action__k {
  font-size: 0.7rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--stone-text); display: block; margin-bottom: 0.7rem;
}
.action__v {
  font-family: var(--display);
  font-size: clamp(1.25rem, 2.1vw, 1.75rem);
  font-weight: 300;
  line-height: 1.2;
  display: flex; align-items: center; gap: 0.6rem;
}
.action__v .btn__arrow { color: var(--gold); font-size: 0.8em; }

@media (max-width: 700px) {
  .action { border-right: 0; padding-right: 0; }
}


/* ---------------------------------------------------------------------------
   22. Social
   --------------------------------------------------------------------------- */

.social-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(0.6rem, 1.2vw, 1.1rem);
}
.social-grid__cell {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--sand);
}
.social-grid__cell img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease-out);
}
.social-grid__cell:hover img { transform: scale(1.05); }


/* ---------------------------------------------------------------------------
   23. Footer
   --------------------------------------------------------------------------- */

.footer { background: var(--ink); color: var(--taupe); }
.footer a:hover { color: var(--gold-lit); }

.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 4rem);
  padding-block: clamp(3.5rem, 8vh, 6rem);
}
.footer__brand .brand { margin-right: 0; margin-bottom: 1.3rem; color: var(--ivory); }
.footer__tag { font-size: var(--t-small); max-width: 30ch; line-height: 1.65; }

.footer__h {
  font-size: 0.7rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--ivory); margin-bottom: 1.2rem;
}
.footer__list { list-style: none; padding: 0; display: grid; gap: 0.75rem; font-size: var(--t-small); }

.footer__bottom {
  display: flex; flex-wrap: wrap; gap: 1rem 2rem;
  align-items: center; justify-content: space-between;
  padding-block: 1.8rem;
  border-top: 1px solid var(--rule-dark);
  font-size: 0.76rem;
}
.footer__socials { display: flex; gap: 1.4rem; }

/* Build credit. Deliberately the quietest thing in the footer: it should be
   findable by someone who wants to know who built the site, and invisible to
   the customer who came here to buy stone. */
/* No `order` needed: the markup already places this between the copyright and
   the social links, which is where it belongs at every width. */
.footer__credit { color: var(--stone); }
.footer__credit a {
  color: var(--taupe);
  padding-bottom: 2px;
  border-bottom: 1px solid var(--gold-dim);
  transition: color 0.35s var(--ease), border-color 0.35s var(--ease);
}
.footer__credit a:hover {
  color: var(--gold-lit);
  border-bottom-color: var(--gold);
}

@media (max-width: 700px) {
  /* Stacked, the credit reads better directly under the copyright line than
     wedged between it and the social links. */
  .footer__bottom { flex-direction: column; align-items: flex-start; gap: 0.7rem; }
  .footer__socials { margin-top: 0.4rem; }
}

@media (max-width: 900px) {
  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  .footer__top { grid-template-columns: 1fr; }
}


/* ---------------------------------------------------------------------------
   24. Sticky mobile action bar
   --------------------------------------------------------------------------- */

.dock {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 880;
  display: none;
  background: rgba(19, 18, 16, 0.96);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--rule-dark);
  transform: translateY(100%);
  transition: transform 0.5s var(--ease-out);
  padding-bottom: env(safe-area-inset-bottom);
}
.dock.is-up { transform: none; }
.dock__grid { display: grid; grid-template-columns: 1fr 1fr 1fr; }
.dock a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-height: 58px;
  padding: 0.5rem;
  color: var(--ivory);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border-right: 1px solid var(--rule-dark);
  -webkit-tap-highlight-color: transparent;
}
.dock a:last-child { border-right: 0; }
.dock a.is-primary { background: var(--gold); color: var(--ink); }
.dock svg { width: 17px; height: 17px; fill: currentColor; }

@media (max-width: 1060px) {
  .dock { display: block; }
  /* Keep the dock from covering the last of the footer. */
  body { padding-bottom: 58px; }
}


/* ---------------------------------------------------------------------------
   25. Cursor
   --------------------------------------------------------------------------- */

/* Fine pointers only. A custom cursor on a touch device is dead weight.
   The ring is 30px wide and centred on the pointer, so at the right-hand edge
   of the screen half of it sits outside the viewport. A fixed element that
   sticks out like that can extend the scrollable area, so it lives inside a
   clipping layer rather than relying on the page-level overflow guard. */
.cursor-layer {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 1000;
}
.cursor {
  position: fixed;
  top: 0; left: 0;
  width: 30px; height: 30px;
  margin: -15px 0 0 -15px;
  border: 1px solid rgba(168, 133, 60, 0.75);
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s var(--ease), width 0.35s var(--ease-out),
              height 0.35s var(--ease-out), margin 0.35s var(--ease-out),
              background 0.35s var(--ease);
  will-change: transform;
}
.cursor.is-on { opacity: 1; }
.cursor.is-lg {
  width: 62px; height: 62px; margin: -31px 0 0 -31px;
  background: rgba(168, 133, 60, 0.14);
}




/* ---------------------------------------------------------------------------
   26. Mobile typography
   ---------------------------------------------------------------------------
   The type on this site is set for an editorial desktop reading distance:
   light weights, small labels and wide letter-spacing. On a phone — held
   further from the eye than a monitor, often outdoors, often by someone over
   forty choosing stone for their home — those same settings are the difference
   between skimming the page and giving up on it.

   This block does four things, in order of how much they matter:
     1. takes the body weight from 350 to 400, so strokes survive at small size
     2. opens the line-height, because short measures need more leading
     3. lifts the floor under every small label to ~12.5px
     4. pulls back the widest letter-spacing, which hurts below about 13px
   None of it changes the desktop design.
   --------------------------------------------------------------------------- */

@media (max-width: 760px) {
  :root {
    --w-body: 400;
    --t-body: 1.02rem;
    --t-lead: 1.14rem;
    --t-small: 0.95rem;
    --t-micro: 0.85rem;
    --t-eyebrow: 0.72rem;
  }

  body { line-height: 1.72; }

  .lead { line-height: 1.62; }

  /* Long-form copy: the About story and any prose block. */
  .about__body p,
  .reasons__d,
  .step__d,
  .collection__desc,
  .explorer__note {
    line-height: 1.68;
  }

  /* Uppercase micro-labels. Below roughly 13px, 0.24em of tracking stops
     helping the eye group letters and starts pulling words apart. */
  .eyebrow,
  .filter__label,
  .explorer__count,
  .action__k,
  .footer__h,
  .info-list dt,
  .info-list .k,
  .reasons__n,
  .step__n {
    letter-spacing: 0.16em;
  }

  .filter__label,
  .explorer__count,
  .action__k,
  .footer__h,
  .info-list dt,
  .info-list .k { font-size: 0.76rem; }

  .figures__l { font-size: 0.82rem; letter-spacing: 0.14em; line-height: 1.55; }
  .review__who { font-size: 0.8rem; letter-spacing: 0.16em; }
  .tiny, .note { letter-spacing: 0.02em; }

  /* Touch targets. These read as text, so they cannot grow visually — but the
     box behind them can, and that is what a thumb actually aims at. */
  .link { padding-block: 0.55rem; }
  .explorer__reset { padding-block: 0.7rem; }
  .collection__cta { padding-block: 0.35rem; }

  /* Controls and links. A 12px button label on a phone is a guess, not a read. */
  .btn { font-size: 0.82rem; letter-spacing: 0.14em; }
  .btn--sm { font-size: 0.78rem; }
  .link { font-size: 0.84rem; letter-spacing: 0.12em; }
  .chip { font-size: 0.85rem; }
  .collection__cta { font-size: 0.78rem; letter-spacing: 0.14em; }
  .explorer__reset { font-size: 0.78rem; }
  .nav__links a, .footer__bottom { font-size: 0.82rem; }
  .footer__list { font-size: 0.92rem; }

  /* The dock labels sit under icons and were the smallest text on the site. */
  .dock a { font-size: 0.68rem; letter-spacing: 0.1em; }

  /* Hero supporting copy — the sentence that has to do the selling. */
  .hero__copy { font-size: 1.06rem; line-height: 1.62; }
  .hero__badge span { font-size: 0.78rem; letter-spacing: 0.16em; }

  .ticker span { font-size: 0.78rem; letter-spacing: 0.18em; }
  .process__hint { font-size: 0.76rem; letter-spacing: 0.16em; }

  /* The brand lockup's sub-label was 8.3px — decorative to the point of
     illegible on the one screen where the shop's name matters most. */
  .brand__sub { font-size: 0.58rem; letter-spacing: 0.24em; }
}

/* Very small phones still in wide use in India: keep the gains, lose the
   tracking that costs horizontal room. */
@media (max-width: 380px) {
  .brand__sub { letter-spacing: 0.18em; }
  .btn { letter-spacing: 0.1em; }
  .dock a { letter-spacing: 0.06em; }
}


/* ---------------------------------------------------------------------------
   27. Accessibility & print
   --------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; }
  .js .split .w > span { transform: none !important; }
  .js .reveal-img::after { transform: scaleX(0) !important; }
  .cursor { display: none; }
  .craft { height: auto; }
  .craft__sticky { position: static; height: auto; }
}

@media print {
  .nav, .dock, .cursor, .hero__canvas, .ticker { display: none !important; }
  .hero { min-height: auto; }
  body { color: #000; background: #fff; }
}
