/* ============================================================
   RKS TRADERS — SIMPLY ENDURING
   Design system · architectural / minimal / premium
   Primary tokens derive from #113642 (Deep Teal)
   and #D5BDAB (Warm Sandstone).
   ============================================================ */

/* ------------------------------ FONTS (local) ------------------------------ */
@font-face {
  font-family: "Vonca";
  src: url("../assets/fonts/vonca-light.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Vonca";
  src: url("../assets/fonts/vonca-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Vonca";
  src: url("../assets/fonts/vonca-medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Vonca";
  src: url("../assets/fonts/vonca-semibold.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../assets/fonts/montserrat-300.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../assets/fonts/montserrat-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../assets/fonts/montserrat-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Montserrat";
  src: url("../assets/fonts/montserrat-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ------------------------------ TOKENS ------------------------------ */
:root {
  /* color — teal family */
  --teal: #113642;
  --teal-950: #081E26;
  --teal-900: #0C2933;
  --teal-800: #113642;
  --teal-700: #1A4653;
  --teal-600: #275968;
  --teal-400: #4E7D8C;
  --teal-200: #A9C2CB;

  /* color — sandstone family */
  --sand: #D5BDAB;
  --sand-600: #B79B85;
  --sand-500: #C6AC97;
  --sand-400: #D5BDAB;
  --sand-300: #E2D0C1;
  --sand-200: #ECDFD4;

  /* neutrals */
  --ivory: #F5F0E9;
  --warm-white: #FAF7F2;
  --limestone: #EAE3D8;
  --greige: #A99C8D;
  --charcoal: #1E2427;
  --ink: #14232A;
  --champagne: #C9AE8C;

  /* semantic */
  --bg: var(--warm-white);
  --text: var(--ink);
  --text-muted: #5C6B70;
  --line: rgba(17, 54, 66, 0.14);
  --line-on-dark: rgba(213, 189, 171, 0.22);
  --text-on-dark: #E9E2D8;
  --text-on-dark-muted: #A9BAC0;

  /* type */
  --font-display: "Vonca", "Montserrat", sans-serif; /* official VONCA, loaded locally */
  --font-body: "Montserrat", -apple-system, "Segoe UI", sans-serif;
  --fs-hero: clamp(2.6rem, 8.5vw, 7.2rem);
  --fs-h2: clamp(1.9rem, 4.6vw, 3.9rem);
  --fs-h3: clamp(1.25rem, 2.4vw, 1.9rem);
  --fs-body: clamp(0.95rem, 1.1vw, 1.05rem);
  --fs-small: 0.82rem;
  --fs-label: 0.72rem;
  --track-label: 0.22em;

  /* layout */
  --container: 1240px;
  --container-wide: 1440px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-pad: clamp(4.5rem, 10vw, 8.5rem);

  /* motion */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-arch: cubic-bezier(0.65, 0, 0.15, 1);
  --dur-fast: 180ms;
  --dur-std: 320ms;
  --dur-reveal: 900ms;
  --dur-cine: 1400ms;

  /* z-scale */
  --z-nav: 50;
  --z-menu: 60;
  --z-widget: 40;
  --z-viewer: 70;
  --z-preloader: 80;
  --z-cursor: 90;
}

/* ------------------------------ RESET ------------------------------ */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
body {
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
ul, ol { list-style: none; }
::selection { background: var(--teal); color: var(--sand-200); }

:focus-visible {
  outline: 2px solid var(--teal-600);
  outline-offset: 3px;
  border-radius: 2px;
}
.on-dark :focus-visible, .s-dark :focus-visible { outline-color: var(--sand); }

.skip-link {
  position: fixed; top: -100%; left: 1rem; z-index: 100;
  background: var(--teal); color: var(--sand-200);
  padding: 0.7rem 1.2rem; font-size: var(--fs-small);
  letter-spacing: 0.08em; transition: top var(--dur-fast) ease;
}
.skip-link:focus { top: 1rem; }

/* ------------------------------ TYPE UTILITIES ------------------------------ */
.display { font-family: var(--font-display); font-weight: 400; line-height: 1.06; letter-spacing: 0.02em; text-transform: uppercase; }
.label {
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--teal-600);
}
.on-dark .label, .s-dark .label { color: var(--sand); }
.lede { font-size: clamp(1rem, 1.4vw, 1.18rem); font-weight: 300; line-height: 1.75; color: var(--text-muted); max-width: 34em; }
.on-dark .lede, .s-dark .lede { color: var(--text-on-dark-muted); }

.container { width: min(100% - 2 * var(--gutter), var(--container)); margin-inline: auto; }
.container-wide { width: min(100% - 2 * var(--gutter), var(--container-wide)); margin-inline: auto; }
section { position: relative; }

/* section head pattern */
.sec-head { display: grid; gap: 1.1rem; margin-bottom: clamp(2.5rem, 6vw, 4.5rem); max-width: 900px; }
.sec-head .rule { width: 56px; height: 2px; background: var(--sand-600); }
.s-dark .sec-head .rule { background: var(--sand); }
.sec-head h2 { font-size: var(--fs-h2); }

/* ------------------------------ BUTTONS ------------------------------ */
.btn {
  --btn-bg: var(--teal);
  --btn-fg: var(--sand-200);
  position: relative; display: inline-flex; align-items: center; gap: 0.8rem;
  min-height: 52px; padding: 0.9rem 1.9rem;
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--btn-fg); background: var(--btn-bg);
  border: 1px solid transparent;
  cursor: pointer; overflow: hidden;
  transition: color var(--dur-std) var(--ease-out), background-color var(--dur-std) var(--ease-out), border-color var(--dur-std) var(--ease-out);
  /* angled corner from the RKS fractured-tile geometry */
  clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
}
.btn .btn-arrow { transition: transform var(--dur-std) var(--ease-out); flex: none; }
.btn:hover .btn-arrow, .btn:focus-visible .btn-arrow { transform: translateX(5px); }
.btn:hover { background: var(--teal-700); }
.btn .btn-ico { width: 17px; height: 17px; fill: currentColor; flex: none; }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

.btn-sand { --btn-bg: var(--sand); --btn-fg: var(--teal-900); }
.btn-sand:hover { background: var(--sand-300); }

.btn-ghost {
  --btn-bg: transparent; --btn-fg: var(--teal);
  border-color: rgba(17, 54, 66, 0.55);
}
.btn-ghost:hover { border-color: var(--teal); background: rgba(17, 54, 66, 0.06); }
/* Every dark surface on the site. A ghost button inheriting the light
   variant here would render teal on teal and disappear, so the dark
   treatment is bound to the sections explicitly rather than by hope. */
.on-dark .btn-ghost, .s-dark .btn-ghost,
.hero .btn-ghost, .s-explorer .btn-ghost, .s-projects .btn-ghost,
.s-sanitary .btn-ghost, .s-gateway .btn-ghost, .s-quote .btn-ghost,
.s-stats .btn-ghost, .footer .btn-ghost, .mobile-menu .btn-ghost,
.viewer .btn-ghost, .showroom-exterior .btn-ghost {
  --btn-fg: #F1E9DF; border-color: rgba(213, 189, 171, 0.65);
  background: rgba(8, 30, 38, 0.45);
}
.on-dark .btn-ghost:hover, .s-dark .btn-ghost:hover,
.hero .btn-ghost:hover, .s-explorer .btn-ghost:hover, .s-projects .btn-ghost:hover,
.s-sanitary .btn-ghost:hover, .s-gateway .btn-ghost:hover, .s-quote .btn-ghost:hover,
.s-stats .btn-ghost:hover, .footer .btn-ghost:hover, .mobile-menu .btn-ghost:hover,
.viewer .btn-ghost:hover, .showroom-exterior .btn-ghost:hover {
  border-color: var(--sand); background: rgba(213, 189, 171, 0.16);
}
/* hero variant: guaranteed contrast over complex imagery */
.hero .btn-ghost {
  --btn-fg: #F1E9DF;
  border: 1.5px solid rgba(213, 189, 171, 0.9);
  background: rgba(8, 30, 38, 0.45);
}
.hero .btn-ghost:hover, .hero .btn-ghost:focus-visible { background: rgba(213, 189, 171, 0.22); border-color: var(--sand-200); }

.text-link {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-size: var(--fs-label); font-weight: 600; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--teal-600);
  border-bottom: 1px solid rgba(17, 54, 66, 0.25);
  padding-bottom: 0.3rem;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
.text-link:hover { color: var(--teal); border-color: var(--teal); }
/* Same context rule as the ghost button: on a dark surface the light variant
   would be teal on teal. Bind the dark treatment to the sections explicitly. */
.s-dark .text-link, .on-dark .text-link,
.hero .text-link, .s-explorer .text-link, .s-projects .text-link,
.s-sanitary .text-link, .s-gateway .text-link, .s-quote .text-link,
.s-stats .text-link, .footer .text-link, .mobile-menu .text-link {
  color: var(--sand); border-color: rgba(213, 189, 171, 0.42);
}
.s-dark .text-link:hover, .on-dark .text-link:hover,
.hero .text-link:hover, .s-explorer .text-link:hover, .s-projects .text-link:hover,
.s-sanitary .text-link:hover, .s-gateway .text-link:hover, .s-quote .text-link:hover,
.s-stats .text-link:hover, .footer .text-link:hover, .mobile-menu .text-link:hover {
  color: var(--sand-200); border-color: var(--sand);
}

/* ------------------------------ PRELOADER ------------------------------ */
.preloader {
  position: fixed; inset: 0; z-index: var(--z-preloader);
  display: none; align-items: center; justify-content: center;
  background: var(--teal-900);
  flex-direction: column; gap: 1.6rem;
}
html.show-preloader .preloader { display: flex; }
.preloader-mark { width: clamp(64px, 10vw, 96px); opacity: 0; transform: scale(0.92); }
.preloader-tag {
  font-size: var(--fs-label); letter-spacing: 0.4em; text-transform: uppercase;
  color: var(--sand); opacity: 0; font-weight: 500; padding-left: 0.4em;
}
.preloader-planes { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(4, 1fr); pointer-events: none; }
.preloader-planes span { background: var(--teal); transform: scaleY(0); transform-origin: top; }
.preloader.is-done { pointer-events: none; }

html.show-preloader.preload-anim .preloader-mark { animation: pl-mark 0.9s var(--ease-out) 0.1s forwards; }
html.show-preloader.preload-anim .preloader-tag { animation: pl-tag 0.8s var(--ease-out) 0.45s forwards; }
@keyframes pl-mark { to { opacity: 1; transform: scale(1); } }
@keyframes pl-tag { to { opacity: 1; } }

/* ------------------------------ NAVIGATION ------------------------------
   Set out from a datum, the way a section drawing is dimensioned from a
   grade line, rather than drawn as a bar. One precision rule crosses the
   viewport; the logo sits on a pier that breaks below it, the labels stand
   on it with setting out ticks, a champagne traveller rides along it to the
   active section, and the quote block is deliberately lifted above it.
   ------------------------------------------------------------------------ */
.nav {
  --nav-h: clamp(54px, 4.6vw, 64px);
  --pier-drop: clamp(10px, 1.2vw, 16px);
  position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-nav);
  padding-top: clamp(0.7rem, 1.7vw, 1.15rem);
  transition: transform 460ms var(--ease-arch), padding-top 460ms var(--ease-arch);
}
/* the surface the navigation settles onto once scrolled */
.nav::before {
  content: ""; position: absolute; inset: 0;
  background: rgba(8, 30, 38, 0.84);
  -webkit-backdrop-filter: blur(18px) saturate(1.08); backdrop-filter: blur(18px) saturate(1.08);
  opacity: 0; transition: opacity 460ms var(--ease-out);
  pointer-events: none;
}
/* An unscrolled header still has to be legible over a photograph. Measured
   against the hero frame, the Catalogs label crosses a lit slab at luma 159
   and needed this much to clear 4.5:1; the rest of the row sits above 12:1. */
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0;
  height: calc(100% + 56px);
  background: linear-gradient(180deg, rgba(8, 30, 38, 0.68), rgba(8, 30, 38, 0));
  opacity: 1; transition: opacity 460ms var(--ease-out);
  pointer-events: none;
}
.nav.is-scrolled::before { opacity: 1; }
.nav.is-scrolled::after { opacity: 0; }
.nav.is-scrolled { padding-top: clamp(0.4rem, 0.9vw, 0.62rem); }
/* clears its own overhanging pier when it retracts */
.nav.nav-hidden { transform: translateY(calc(-100% - var(--pier-drop) - 4px)); }

/* ---- the datum ---- */
.nav-datum {
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg,
    rgba(213, 189, 171, 0) 0%,
    rgba(213, 189, 171, 0.34) 6%,
    rgba(213, 189, 171, 0.34) 82%,
    rgba(213, 189, 171, 0) 100%);
  transition: background 460ms var(--ease-out);
  pointer-events: none;
}
.nav.is-scrolled .nav-datum {
  background: linear-gradient(90deg,
    rgba(213, 189, 171, 0.44) 0%,
    rgba(213, 189, 171, 0.44) 88%,
    rgba(213, 189, 171, 0.1) 100%);
}

.nav-shell {
  position: relative; z-index: 1;
  width: min(100% - 2 * var(--gutter), var(--container-wide));
  margin-inline: auto;
  height: var(--nav-h);
  display: flex; align-items: stretch; justify-content: space-between;
  gap: clamp(1rem, 3vw, 2.6rem);
}

/* ---- pier: the mark on a plane that breaks through the datum ---- */
.nav-pier {
  display: flex; align-items: center;
  padding: 0 clamp(0.85rem, 1.7vw, 1.4rem);
  margin-bottom: calc(var(--pier-drop) * -1);
  background: linear-gradient(180deg, rgba(8, 30, 38, 0.3), rgba(8, 30, 38, 0.76));
  border: 1px solid rgba(213, 189, 171, 0.16);
  border-top-color: rgba(213, 189, 171, 0.08);
  /* foundation cut, taken from the fractured tile geometry of the mark */
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 15px), calc(100% - 15px) 100%, 0 100%);
  transition: margin-bottom 460ms var(--ease-arch), background 460ms var(--ease-out),
              border-color 460ms var(--ease-out);
}
/* Sized up so the mark reads and the SIMPLY ENDURING line is legible rather
   than implied. Height only, width auto, so the 1200x275 artwork keeps its
   ratio exactly; the shell height is unchanged, the logo just occupies more
   of it. */
.nav-pier img {
  height: clamp(34px, 3.3vw, 45px); width: auto; display: block;
  transition: height 460ms var(--ease-arch);
}
.nav.is-scrolled .nav-pier {
  margin-bottom: 0;
  background: none; border-color: transparent;
}
.nav.is-scrolled .nav-pier img { height: clamp(30px, 2.8vw, 37px); }

/* ---- core ---- */
.nav-core { display: flex; align-items: stretch; gap: clamp(0.9rem, 2.1vw, 2.2rem); }
.nav-links { position: relative; display: flex; align-items: stretch; gap: clamp(0.7rem, 1.7vw, 1.85rem); }

.nav-link {
  position: relative; display: inline-flex; align-items: center;
  padding: 0 0.15rem;
  font-size: var(--fs-label); font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--text-on-dark);
  transition: color 300ms var(--ease-out);
}
/* setting out tick, dropped from the label to the datum */
.nav-link::after {
  content: ""; position: absolute; left: 50%; bottom: 0;
  width: 1px; height: 8px; background: var(--sand);
  transform: translateX(-50%) scaleY(0); transform-origin: bottom;
  transition: transform 340ms var(--ease-arch);
}
.nav-link:hover::after,
.nav-link:focus-visible::after,
.nav-link[aria-current="true"]::after,
.nav-link[aria-current="page"]::after { transform: translateX(-50%) scaleY(1); }

/* label swap: two stacked layers clipped to one line, never an underline */
.nav-link-mask { position: relative; display: block; overflow: hidden; height: 1.05em; }
.nav-link-mask span {
  display: block; line-height: 1.05em;
  transition: transform 420ms var(--ease-arch);
}
.nav-link-mask span:last-child { color: var(--sand); }
.nav-link:hover .nav-link-mask span,
.nav-link:focus-visible .nav-link-mask span,
.nav-link[aria-current="true"] .nav-link-mask span { transform: translateY(-1.05em); }

/* ---- traveller: a champagne segment that rides the datum ----
   Driven from JS by custom properties so it only ever animates a transform. */
.nav-traveller {
  position: absolute; left: 0; bottom: -1px;
  width: 10px; height: 2px; background: var(--sand);
  transform-origin: left center;
  transform: translate3d(var(--tv-x, 0), 0, 0) scaleX(var(--tv-s, 0));
  opacity: var(--tv-o, 0);
  transition: transform 460ms var(--ease-arch), opacity 300ms var(--ease-out);
  pointer-events: none;
}

/* ---- quote: lifted clear of the datum, the one filled plane ---- */
.nav-quote {
  position: relative; align-self: center;
  display: inline-flex; align-items: center;
  min-height: 40px; padding: 0.5rem clamp(0.95rem, 1.7vw, 1.35rem);
  margin-bottom: 7px;
  color: var(--teal-900);
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  white-space: nowrap;
}
/* Two stacked surfaces: the champagne face, and a hairline plate offset
   behind it. Both are drawn by pseudo elements below the text rather than
   as a background, so the plate reads as a separate plane instead of a
   line crossing the face. */
.nav-quote::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--sand);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition: background-color 300ms var(--ease-out);
}
.nav-quote::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  transform: translate(5px, 5px);
  border: 1px solid rgba(213, 189, 171, 0.45);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition: transform 340ms var(--ease-arch), border-color 300ms var(--ease-out);
}
.nav-quote:hover::after, .nav-quote:focus-visible::after { background: var(--sand-300); }
.nav-quote:hover::before, .nav-quote:focus-visible::before {
  transform: translate(2px, 2px); border-color: var(--sand);
}

/* ---- mobile trigger: a square icon plate, sized around the rules ----
   The button is dimensioned from the icon rather than padded around a label
   that is no longer there, so it reads as a control that was drawn this way
   rather than one with text deleted out of it. The accessible name lives on
   aria-label, which main.js swaps between Open and Close menu. */
.nav-trigger {
  display: none; position: relative; z-index: calc(var(--z-menu) + 2);
  align-self: center; align-items: center; justify-content: center; gap: 0;
  width: 46px; height: 46px; padding: 0;
  background: rgba(8, 30, 38, 0.52);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border: 1px solid rgba(213, 189, 171, 0.22);
  clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
  cursor: pointer;
  transition: background-color 300ms var(--ease-out), border-color 300ms var(--ease-out);
}
.nav-trigger:hover, .nav-trigger:focus-visible { border-color: rgba(213, 189, 171, 0.5); }
/* three rules of unequal length, like a scale; they square up on interaction */
.nt-rules { display: grid; gap: 4px; width: 20px; flex: none; }
.nt-rules i {
  display: block; width: 20px; height: 1.5px; background: var(--sand-200);
  transform-origin: left center;
  transition: transform 400ms var(--ease-arch), opacity 220ms var(--ease-out);
}
.nt-rules i:nth-child(1) { transform: scaleX(1); }
.nt-rules i:nth-child(2) { transform: scaleX(0.58); }
.nt-rules i:nth-child(3) { transform: scaleX(0.82); }
.nav-trigger:hover .nt-rules i,
.nav-trigger:focus-visible .nt-rules i { transform: scaleX(1); }
/* open: the outer rules cross, the middle one retires */
.nav-trigger[aria-expanded="true"] .nt-rules i:nth-child(1) {
  transform-origin: center; transform: translateY(5.5px) rotate(45deg);
}
.nav-trigger[aria-expanded="true"] .nt-rules i:nth-child(2) { opacity: 0; transform: scaleX(0); }
.nav-trigger[aria-expanded="true"] .nt-rules i:nth-child(3) {
  transform-origin: center; transform: translateY(-5.5px) rotate(-45deg);
}
/* Between the collapse point and a comfortable desktop the row is tight, so
   the tracking closes up a little rather than the labels being allowed to
   wrap. Above 1200px everything returns to the full architectural spacing. */
@media (max-width: 1200px) {
  .nav-link { letter-spacing: 0.11em; }
  .nav-quote { letter-spacing: 0.16em; padding-inline: 0.9rem; }
  /* the larger mark widens the pier, so the row buys the space back from
     padding and gaps rather than from the logo */
  .nav-pier { padding-inline: 0.7rem; }
  .nav-links { gap: clamp(0.7rem, 1.45vw, 1.85rem); }
}

/* the six labels plus the quote block still fit a 1024 laptop with room to
   spare once the tracking tightens, so the trigger only takes over below that */
@media (max-width: 1000px) {
  .nav-core { display: none; }
  .nav-trigger { display: inline-flex; }
  .nav-shell { align-items: center; height: auto; min-height: var(--nav-h); }
  .nav-pier { margin-bottom: 0; padding-block: 0.4rem; }
}
/* the word is what stops this reading as a generic hamburger, so it is kept
   until the header genuinely runs out of room */
/* the icon plate is already compact, so the smallest phones only need the
   pier to give up a little of its side padding */
@media (max-width: 339px) {
  .nav-pier { padding-inline: 0.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  .nav, .nav::before, .nav::after, .nav-datum, .nav-pier, .nav-pier img,
  .nav-link::after, .nav-link-mask span, .nav-traveller,
  .nav-quote, .nav-quote::before, .nt-rules i { transition-duration: 1ms; }
}

/* ------------------------------ MOBILE MENU ------------------------------ */
.mobile-menu {
  position: fixed; inset: 0; z-index: var(--z-menu);
  background: var(--teal-950);
  display: grid; grid-template-rows: auto 1fr auto;
  padding: 1.1rem var(--gutter) calc(1.5rem + env(safe-area-inset-bottom, 0px));
  clip-path: inset(0 0 100% 0);
  visibility: hidden;
  transition: clip-path 620ms var(--ease-arch), visibility 0s 620ms;
}
.mobile-menu.is-open {
  clip-path: inset(0 0 0% 0);
  visibility: visible;
  transition: clip-path 620ms var(--ease-arch);
}
/* decorative fragment, never over text */
.mobile-menu::after {
  content: ""; position: absolute; right: -22%; bottom: -14%;
  width: 78vw; aspect-ratio: 1;
  background: url("../assets/logo/mark-sand.png") no-repeat center / contain;
  opacity: 0.035; pointer-events: none;
}

.mm-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; position: relative; z-index: 1;
}
.mm-top img { height: 34px; width: auto; }

/* explicit, labelled close control */
.mm-close {
  display: inline-flex; align-items: center; gap: 0.6rem;
  min-height: 46px; padding: 0.5rem 1rem;
  border: 1px solid rgba(213, 189, 171, 0.4);
  color: var(--sand-200);
  font-size: 0.68rem; font-weight: 600;
  letter-spacing: 0.2em; text-transform: uppercase;
  clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
  transition: background-color 220ms var(--ease-out), border-color 220ms var(--ease-out);
}
.mm-close:hover { background: rgba(213, 189, 171, 0.12); border-color: var(--sand); }
.mm-close svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 1.8; fill: none; }

.mm-nav {
  display: flex; flex-direction: column; justify-content: center;
  gap: 0.1rem; position: relative; z-index: 1;
  padding-block: 1.5rem;
}
/* Each row is set out like a drawing: index number, label, and a champagne
   rule that draws itself across on press. The label is masked so it can be
   moved without touching layout. */
.mm-nav a {
  position: relative; overflow: hidden;
  display: flex; align-items: baseline; gap: 1rem;
  padding: 0.5rem 0; min-height: 54px;
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 7vw, 2.4rem);
  text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--text-on-dark);
  border-bottom: 1px solid rgba(213, 189, 171, 0.1);
  opacity: 0; transform: translateY(16px);
  transition: opacity 460ms var(--ease-out), transform 460ms var(--ease-out), color 220ms var(--ease-out);
}
.mobile-menu.is-open .mm-nav a { opacity: 1; transform: none; }
/* the rule that runs along the foot of the row */
.mm-nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: var(--sand);
  transform: scaleX(0); transform-origin: left;
  transition: transform 420ms var(--ease-arch);
}
.mm-nav a:active, .mm-nav a:focus-visible { color: var(--sand-200); }
.mm-nav a:active::after, .mm-nav a:focus-visible::after { transform: scaleX(1); }
.mm-nav a em {
  font-style: normal; display: block;
  transition: transform 420ms var(--ease-arch);
}
.mm-nav a:active em, .mm-nav a:focus-visible em { transform: translateX(9px); }
.mm-nav a i {
  font-family: var(--font-body); font-style: normal; flex: none;
  font-size: 0.62rem; letter-spacing: 0.2em; color: var(--sand-600);
  transition: color 300ms var(--ease-out);
}
.mm-nav a:active i, .mm-nav a:focus-visible i { color: var(--sand); }

.mm-foot {
  position: relative; z-index: 1;
  display: grid; gap: 0.9rem;
  padding-top: 1.2rem; border-top: 1px solid rgba(213, 189, 171, 0.14);
}
.mm-foot .mm-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
.mm-foot .btn { justify-content: center; width: 100%; }
.mm-foot address {
  font-style: normal; font-size: 0.8rem; line-height: 1.7;
  color: var(--text-on-dark-muted);
}
.mm-foot a.mm-mail { color: var(--sand); }

@media (prefers-reduced-motion: reduce) {
  .mobile-menu, .mobile-menu.is-open { transition: none; }
  .mm-nav a { transition: none; }
}


/* ------------------------------ HERO ------------------------------ */
.hero {
  position: relative; min-height: 100svh;
  display: flex; align-items: flex-end;
  background: var(--teal-900); color: var(--text-on-dark);
  overflow: clip;
}
.hero-media { position: absolute; inset: 0; }
/* Scrim tuned against the actual photograph rather than by eye. Measured luma
   of the desktop frame: the logo wall on the left reads 9 to 79, while the
   polished floor along the bottom reads 72 to 96 and sits directly behind the
   copy. So the left plane and the floor get the weight, and the lit slabs on
   the right, which are the reason the photograph is there, stay open. */
.hero-media::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(8, 30, 38, 0.52) 0%, rgba(8, 30, 38, 0.16) 34%, rgba(8, 30, 38, 0.72) 78%, rgba(8, 30, 38, 0.9) 100%),
    linear-gradient(95deg, rgba(8, 30, 38, 0.86) 0%, rgba(8, 30, 38, 0.66) 30%, rgba(8, 30, 38, 0.12) 62%, rgba(8, 30, 38, 0) 100%);
}
.hero-media img {
  width: 100%; height: 100%; object-fit: cover; object-position: center;
  transform: scale(1.04);
}
@media (max-width: 767px) {
  /* Portrait frame: the signage wall sits at 39 to 48 percent of the height and
     the floor below it runs bright (luma 52 to 99) exactly where the copy goes.
     Hold the image at the top so the wall stays above the text, then ramp the
     teal up from the middle so the content block sits on a solid base. */
  .hero-media img { object-position: center top; transform: scale(1.02); }
  /* The copy block starts at about 33 percent of the viewport and the painted
     signage on the wall behind it falls at 39 to 48 percent, so the two would
     otherwise sit on top of each other. The ramp is held open across the top
     third, where the ceiling and the lit slabs are, then climbs hard just
     above the copy: the showroom stays visible where nothing is written, and
     the wall reads as dark texture wherever type sits on it. */
  .hero-media::after {
    background:
      linear-gradient(180deg,
        rgba(8, 30, 38, 0.58) 0%,
        rgba(8, 30, 38, 0.2) 12%,
        rgba(8, 30, 38, 0.24) 22%,
        rgba(8, 30, 38, 0.76) 31%,
        rgba(8, 30, 38, 0.86) 46%,
        rgba(8, 30, 38, 0.92) 70%,
        rgba(8, 30, 38, 0.96) 100%);
  }
}
.hero-planes { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(5, 1fr); pointer-events: none; z-index: 2; }
.hero-planes span { background: var(--teal-900); }

.hero-content {
  position: relative; z-index: 3;
  width: min(100% - 2 * var(--gutter), var(--container-wide));
  margin-inline: auto;
  padding: 9rem 0 clamp(3rem, 7vh, 5.5rem);
  display: grid; gap: 1.6rem;
}
.hero-kicker {
  display: flex; align-items: center; gap: 1rem;
  font-size: var(--fs-label); font-weight: 500; letter-spacing: 0.3em;
  text-transform: uppercase; color: var(--sand);
}
.hero-kicker::before { content: ""; width: 42px; height: 1px; background: var(--sand-600); }
.hero h1 { font-size: var(--fs-hero); max-width: 11em; font-weight: 300; }
.hero h1 .line { display: block; overflow: clip; }
.hero h1 .line > span { display: inline-block; }
.hero-sub { max-width: 36em; color: #C4D2D6; font-weight: 300; font-size: clamp(0.98rem, 1.3vw, 1.15rem); }
.hero-ctas { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 0.6rem; align-items: center; }

.hero-scroll {
  position: absolute; right: var(--gutter); bottom: 2.2rem; z-index: 3;
  display: flex; flex-direction: column; align-items: center; gap: 0.8rem;
  font-size: 0.62rem; letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--text-on-dark-muted); writing-mode: vertical-rl;
}
.hero-scroll::after {
  content: ""; width: 1px; height: 54px;
  background: linear-gradient(var(--sand), transparent);
  animation: scroll-pulse 2.2s var(--ease-out) infinite;
}
@keyframes scroll-pulse { 0% { transform: scaleY(0); transform-origin: top; } 55% { transform: scaleY(1); transform-origin: top; } 56% { transform-origin: bottom; } 100% { transform: scaleY(0); transform-origin: bottom; } }
@media (max-width: 700px) { .hero-scroll { display: none; } }

/* ------------------------------ INTRO / STORY ------------------------------ */
.s-intro { background: var(--ivory); padding-block: var(--section-pad); }
.intro-grid {
  display: grid; grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(2.5rem, 6vw, 6rem); align-items: start;
}
.intro-copy { display: grid; gap: 1.4rem; }
.intro-copy h2 { font-size: var(--fs-h2); }
.intro-copy p { color: var(--text-muted); max-width: 36em; }
.intro-facts { display: grid; gap: 0; border-top: 1px solid var(--line); }
.intro-fact {
  display: grid; grid-template-columns: auto 1fr; gap: 1.4rem; align-items: baseline;
  padding: 1.15rem 0; border-bottom: 1px solid var(--line);
}
.intro-fact b { font-family: var(--font-display); font-weight: 500; font-size: 1.05rem; letter-spacing: 0.06em; color: var(--teal); white-space: nowrap; text-transform: uppercase; }
.intro-fact span { color: var(--text-muted); font-size: 0.92rem; }
.vm { margin-top: 1.2rem; display: grid; gap: 1.6rem; }
.vm article { border-left: 2px solid var(--sand-600); padding-left: 1.3rem; }
.vm h3 { font-size: var(--fs-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--teal-600); margin-bottom: 0.5rem; font-weight: 600; }
.vm p { font-size: 0.92rem; color: var(--text-muted); }
@media (max-width: 860px) { .intro-grid { grid-template-columns: 1fr; } }

/* ------------------------------ PRODUCT UNIVERSE ------------------------------ */
.s-universe { background: var(--warm-white); padding-block: var(--section-pad); }
.universe-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.world {
  position: relative; background: var(--warm-white);
  padding: clamp(1.8rem, 3vw, 2.8rem);
  min-height: clamp(340px, 44vh, 460px);
  display: flex; flex-direction: column; justify-content: space-between; gap: 2rem;
  overflow: clip; cursor: pointer;
  transition: background-color 0.45s var(--ease-out);
}
.world::before {
  content: ""; position: absolute; inset: 0;
  background: var(--teal-900);
  clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
  transition: clip-path 0.55s var(--ease-arch);
}
.world:hover::before, .world:focus-within::before { clip-path: polygon(0 22%, 100% 0, 100% 100%, 0 100%); }
.world > * { position: relative; z-index: 1; }
.world-num { font-size: var(--fs-label); letter-spacing: var(--track-label); color: var(--greige); transition: color 0.4s; }
.world-body { display: grid; gap: 0.9rem; }
.world h3 { font-family: var(--font-display); font-size: clamp(1.5rem, 2.4vw, 2.1rem); text-transform: uppercase; letter-spacing: 0.04em; transition: color 0.4s; }
.world p { font-size: 0.9rem; color: var(--text-muted); transition: color 0.4s; max-width: 30em; }
.world ul { display: flex; flex-wrap: wrap; gap: 0.45rem 0.9rem; }
.world li { font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--greige); transition: color 0.4s; }
.world:hover h3, .world:focus-within h3 { color: var(--sand-200); }
.world:hover p, .world:focus-within p { color: var(--text-on-dark-muted); }
.world:hover li, .world:focus-within li { color: var(--sand-600); }
.world:hover .world-num, .world:focus-within .world-num { color: var(--sand); }
@media (max-width: 900px) { .universe-grid { grid-template-columns: 1fr; } .world { min-height: 0; } }

/* ------------------------------ SURFACE EXPLORER ------------------------------ */
.s-explorer { background: var(--teal-950); color: var(--text-on-dark); }
.explorer-wrap { position: relative; }
.explorer-stage {
  display: grid; grid-template-columns: 1fr 1fr; min-height: 100svh;
  align-items: center; gap: clamp(2rem, 5vw, 5rem);
  width: min(100% - 2 * var(--gutter), var(--container-wide)); margin-inline: auto;
  padding-block: clamp(4rem, 8vh, 6rem);
}
.explorer-copy { display: grid; gap: 1.4rem; align-content: center; }
.explorer-copy h2 { font-size: var(--fs-h2); }
.explorer-list { display: grid; margin-top: 1rem; }
.explorer-item {
  display: grid; grid-template-columns: auto 1fr auto; align-items: baseline; gap: 1.2rem;
  padding: 0.72rem 0; border-bottom: 1px solid rgba(213, 189, 171, 0.12);
  color: var(--text-on-dark-muted);
  transition: color var(--dur-std), padding-left var(--dur-std) var(--ease-out);
  cursor: default;
}
.explorer-item .idx { font-size: 0.66rem; letter-spacing: 0.2em; color: var(--teal-400); }
.explorer-item .name { font-family: var(--font-display); font-size: clamp(1.05rem, 1.9vw, 1.5rem); text-transform: uppercase; letter-spacing: 0.05em; }
.explorer-item .app { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--teal-400); }
.explorer-item.is-active, .explorer-item:hover { color: var(--sand-200); padding-left: 0.6rem; }
.explorer-item.is-active .idx, .explorer-item.is-active .app { color: var(--sand-600); }

.explorer-visual { position: relative; align-self: center; display: grid; gap: 1.1rem; width: 100%; }
.explorer-frame {
  position: relative; width: 100%; aspect-ratio: 4 / 5; max-height: 62vh;
  overflow: clip;
  clip-path: polygon(0 2.5%, 95% 0, 100% 96%, 4% 100%);
  background: var(--teal-800);
}
.explorer-frame .surface {
  position: absolute; inset: 0; opacity: 0;
  transition: opacity 0.7s var(--ease-out);
  background-size: cover; background-position: center;
}
.explorer-frame .surface.is-active { opacity: 1; }
.explorer-frame::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(160deg, rgba(8, 30, 38, 0.08), rgba(8, 30, 38, 0.28));
}
/* meta lives BELOW the frame in normal flow — never cropped by the clip-path */
.explorer-meta {
  display: flex; align-items: baseline; gap: 1.2rem; min-height: 2.4rem;
  border-left: 2px solid var(--sand-600); padding-left: 1rem;
}
.explorer-meta .m-name { font-family: var(--font-display); text-transform: uppercase; font-size: clamp(1.05rem, 1.8vw, 1.4rem); letter-spacing: 0.08em; color: var(--sand-200); }
.explorer-meta .m-app { font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--teal-400); }
@media (max-width: 900px) {
  .explorer-stage { grid-template-columns: 1fr; min-height: 0; }
  .explorer-visual { order: -1; }
  .explorer-frame { aspect-ratio: 16 / 10; max-height: none; clip-path: polygon(0 1.5%, 97% 0, 100% 98%, 2% 100%); }
}

/* ------------------------------ APPLICATIONS SELECTOR ------------------------------ */
.s-apps { background: var(--limestone); padding-block: var(--section-pad); overflow: clip; }
.apps-selector { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: stretch; }
.apps-nav { display: grid; align-content: start; border-top: 1px solid var(--line); }
.apps-tab {
  display: grid; grid-template-columns: auto 1fr; gap: 1.1rem; align-items: baseline;
  text-align: left; width: 100%;
  padding: 0.95rem 0.4rem; border-bottom: 1px solid var(--line);
  color: var(--text-muted); cursor: pointer;
  transition: color var(--dur-std), padding-left var(--dur-std) var(--ease-out), background-color var(--dur-std);
}
.apps-tab .idx { font-size: 0.64rem; letter-spacing: 0.2em; color: var(--greige); }
.apps-tab .t-name { font-family: var(--font-display); font-size: clamp(1.05rem, 1.9vw, 1.5rem); text-transform: uppercase; letter-spacing: 0.05em; }
.apps-tab .t-note { grid-column: 2; font-size: 0.8rem; color: var(--text-muted); display: none; max-width: 34em; }
.apps-tab.is-active { color: var(--teal-800); padding-left: 0.9rem; background: rgba(213, 189, 171, 0.18); }
.apps-tab.is-active .t-note { display: block; }
.apps-stage { position: relative; min-height: 460px; overflow: clip; clip-path: polygon(3% 0, 100% 2%, 97% 100%, 0 98%); background: var(--teal-900); }
.apps-stage figure { position: absolute; inset: 0; opacity: 0; transition: opacity 0.6s var(--ease-out); }
.apps-stage figure.is-active { opacity: 1; }
.apps-stage img { width: 100%; height: 100%; object-fit: cover; }
.apps-stage figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 1.6rem 1.4rem 1.1rem;
  background: linear-gradient(transparent, rgba(8, 30, 38, 0.82));
  color: var(--sand-200); font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase;
}
@media (max-width: 860px) {
  .apps-selector { grid-template-columns: 1fr; }
  .apps-stage { min-height: 0; aspect-ratio: 4/3; order: -1; }
}

/* ------------------------------ BRAND PORTFOLIO ------------------------------
   A ribbon, not a grid and not a stage. Categories are set out along a rule
   with the same traveller language as the navigation; the brands of the
   active category drift through slowly and are taken hold of by hover, focus,
   tap or swipe; whatever is held is read out on a single line beneath. The
   whole section is roughly a third of the height of the panel it replaces.
   ---------------------------------------------------------------------------- */
.s-brands { background: var(--warm-white); padding-block: var(--section-pad); overflow: clip; }

.brand-rail { display: grid; gap: clamp(1.1rem, 2.4vw, 1.6rem); }

/* ---- categories ---- */
.br-cats {
  position: relative;
  display: flex; align-items: stretch; gap: clamp(1.1rem, 2.6vw, 2.2rem);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--line);
  overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.br-cats::-webkit-scrollbar { display: none; }
.br-cat {
  display: inline-flex; align-items: baseline; gap: 0.5rem;
  padding: 0.2rem 0.1rem; min-height: 34px;
  background: none; border: 0; cursor: pointer; white-space: nowrap;
  font-family: var(--font-display);
  font-size: clamp(0.95rem, 1.7vw, 1.25rem);
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--greige);
  transition: color 300ms var(--ease-out);
}
.br-cat .brc-n {
  font-family: var(--font-body); font-size: 0.6rem; font-weight: 600;
  letter-spacing: 0.12em; color: var(--sand-600);
  font-variant-numeric: tabular-nums;
}
.br-cat:hover, .br-cat:focus-visible { color: var(--teal-700); }
.br-cat.is-active { color: var(--teal); }
.br-cat.is-active .brc-n { color: var(--teal-600); }
/* the traveller rides the rule under the active category */
.br-cat-traveller {
  position: absolute; left: 0; bottom: -1px;
  width: 10px; height: 2px; background: var(--teal);
  transform-origin: left center;
  transform: translate3d(var(--ct-x, 0), 0, 0) scaleX(var(--ct-s, 0));
  opacity: var(--ct-o, 0);
  transition: transform 460ms var(--ease-arch), opacity 300ms var(--ease-out);
  pointer-events: none;
}

/* ---- ribbon ---- */
.br-ribbon {
  position: relative;
  /* the ribbon runs to both page edges, so brands read as passing through */
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  overflow: hidden;
}
/* the material fades in and out at the edges rather than stopping dead */
.br-ribbon::before, .br-ribbon::after {
  content: ""; position: absolute; top: 0; bottom: 0; width: clamp(28px, 7vw, 96px);
  z-index: 2; pointer-events: none;
}
.br-ribbon::before { left: 0; background: linear-gradient(90deg, var(--warm-white), rgba(250, 247, 242, 0)); }
.br-ribbon::after { right: 0; background: linear-gradient(270deg, var(--warm-white), rgba(250, 247, 242, 0)); }

.br-track {
  display: flex; align-items: stretch; gap: clamp(0.6rem, 1.4vw, 1rem);
  width: max-content;
  transition: opacity 220ms var(--ease-out);
}
.br-track.is-swapping { opacity: 0; }

/* drift only where a pointer can stop it; the class is set in JS */
.brand-rail.can-drift .br-track {
  animation: br-drift var(--br-duration, 48s) linear infinite;
}
.brand-rail.can-drift .br-ribbon:hover .br-track,
.brand-rail.can-drift .br-ribbon:focus-within .br-track,
.brand-rail.can-drift .br-ribbon.is-held .br-track { animation-play-state: paused; }
@keyframes br-drift {
  from { transform: translate3d(0, 0, 0); }
  /* the second, duplicated set makes the halfway point identical to the start */
  to { transform: translate3d(calc(-50% - (clamp(0.6rem, 1.4vw, 1rem) / 2)), 0, 0); }
}

/* ---- cell ---- */
.br-cell {
  flex: none; width: clamp(132px, 15vw, 178px);
  display: grid; gap: 0.5rem; align-content: start;
  padding: 0; background: none; border: 0; cursor: pointer;
  text-align: left; color: inherit;
}
.brl-plate {
  position: relative; display: grid;
  /* An auto sized track would make the image's height:100% a cyclic
     percentage and silently fall back to auto, which is what let the taller
     logos escape the plate. minmax(0, 1fr) makes the track definite, and
     stretching the image gives object-fit a real box to letterbox inside. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  place-items: stretch;
  height: clamp(74px, 8.4vw, 94px); padding: 0.9rem 1.1rem;
  background: var(--ivory);
  border: 1px solid var(--line);
  /* the RKS cut, taken down to component scale */
  clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
  transition: background-color 320ms var(--ease-out), border-color 320ms var(--ease-out),
              transform 460ms var(--ease-arch);
}
/* The artwork is fitted by object-fit, not by the element's own intrinsic
   size. Sizing it with width/height auto plus max-height:100% did not work:
   a percentage max-height on a grid item resolves against a basis the grid
   itself derives from the item, so it was ignored, the image took its full
   intrinsic ratio off max-width alone, and five of the seven tile logos ran
   up to 189% of the available height and spilled out of the plate. Giving
   the element a definite box and letting `contain` letterbox inside it keeps
   every ratio whole, from Happilac at 3.08 to Stile at 1.08. */
.brl-plate img {
  width: 100%; height: 100%;
  object-fit: contain; object-position: center;
  opacity: 0.66;
  transition: opacity 320ms var(--ease-out), transform 460ms var(--ease-arch);
}
.brl-name {
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--greige);
  transition: color 300ms var(--ease-out);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.br-cell:hover .brl-plate,
.br-cell:focus-visible .brl-plate,
.br-cell.is-active .brl-plate {
  background: #fff; border-color: rgba(17, 54, 66, 0.3);
  transform: translateY(-3px);
}
.br-cell:hover .brl-plate img,
.br-cell:focus-visible .brl-plate img,
.br-cell.is-active .brl-plate img { opacity: 1; transform: scale(1.05); }
.br-cell:hover .brl-name,
.br-cell:focus-visible .brl-name,
.br-cell.is-active .brl-name { color: var(--teal); }
/* the held brand carries a champagne shard on its top edge */
.br-cell.is-active .brl-plate::after {
  content: ""; position: absolute; left: 0; top: 0; width: 26px; height: 2px;
  background: var(--sand-600);
}

/* ---- readout ---- */
.br-readout {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.4rem 1.1rem;
  padding-top: clamp(0.7rem, 1.6vw, 1rem);
  border-top: 1px solid var(--line);
  min-height: 46px;
}
.bro-cat {
  font-size: 0.6rem; font-weight: 600; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--sand-600);
}
.bro-name {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(1.1rem, 2.1vw, 1.6rem); letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--teal);
}
.bro-note { font-size: 0.76rem; color: var(--text-muted); margin-right: auto; }
.bro-cta {
  display: inline-flex; align-items: center; gap: 0.6rem;
  min-height: 40px; padding: 0.35rem 0;
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--teal);
  border-bottom: 1px solid rgba(17, 54, 66, 0.3);
  transition: color 260ms var(--ease-out), border-color 260ms var(--ease-out), gap 320ms var(--ease-arch);
}
.bro-cta svg { width: 14px; height: 10px; flex: none; }
.bro-cta:hover, .bro-cta:focus-visible { color: var(--teal-600); border-color: var(--teal-600); gap: 0.95rem; }
.bro-cta[hidden] { display: none; }

/* ---- touch or narrow: no drift, a swipeable rail instead ----
   Keyed on both pointer type and width, so a phone and a narrow desktop
   window behave the same way rather than one of them being left with
   material that only drifts past. */
@media (hover: none), (max-width: 767px) {
  .brand-rail.can-drift .br-track { animation: none; transform: none; }
  .br-ribbon {
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.2rem;
  }
  .br-ribbon::-webkit-scrollbar { display: none; }
  /* the second set only exists to make the drift loop seamless; swiping
     through the same brands twice would just be confusing */
  .br-cell[aria-hidden="true"] { display: none; }
  .br-cell { scroll-snap-align: start; width: clamp(126px, 38vw, 160px); }
  /* the edge fades would sit over a scrolling rail and read as smudges */
  .br-ribbon::before, .br-ribbon::after { display: none; }
}

@media (max-width: 640px) {
  .br-readout { gap: 0.3rem 0.8rem; }
  .bro-note { margin-right: 0; width: 100%; }
  .bro-cta { margin-top: 0.2rem; }
}

@media (prefers-reduced-motion: reduce) {
  .brand-rail .br-track { animation: none !important; }
  .br-cat-traveller, .brl-plate, .brl-plate img, .brl-name, .bro-cta, .br-track {
    transition-duration: 1ms;
  }
  /* without drift the rail still has to reach every brand */
  .br-ribbon { overflow-x: auto; }
}

/* ------------------------------ STATS ------------------------------ */
.s-stats {
  background: var(--teal); color: var(--text-on-dark);
  padding-block: clamp(4rem, 9vw, 7rem);
  position: relative; overflow: clip;
}
.s-stats::before {
  content: ""; position: absolute; right: -8%; top: -20%;
  width: 46vw; height: 140%;
  background: url("../assets/logo/mark-sand.png") no-repeat center / contain;
  opacity: 0.05; pointer-events: none;
}
.stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 4vw, 3rem); position: relative; }
.stat { display: grid; gap: 0.5rem; border-left: 1px solid var(--line-on-dark); padding-left: clamp(1rem, 2vw, 1.8rem); }
.stat b { font-family: var(--font-display); font-weight: 400; font-size: clamp(2.4rem, 5.4vw, 4.4rem); line-height: 1; color: var(--sand-200); }
.stat span { font-size: var(--fs-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--text-on-dark-muted); }
.stats-note {
  position: relative; margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.4rem;
  border-top: 1px solid rgba(213, 189, 171, 0.14);
  display: flex; flex-wrap: wrap; gap: 0.5rem 2rem;
  font-size: 0.8rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-on-dark-muted);
}
.stats-note b { color: var(--sand); font-weight: 500; }
@media (max-width: 700px) { .stats-grid { grid-template-columns: 1fr; row-gap: 2rem; } }

/* ------------------------------ WHY RKS ------------------------------ */
.s-why { background: var(--ivory); padding-block: var(--section-pad); }
.why-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.why-panel {
  background: var(--ivory); padding: clamp(1.8rem, 3.4vw, 3rem);
  display: grid; gap: 1rem; align-content: start; min-height: 240px;
  position: relative; overflow: clip;
}
.why-panel i { font-style: normal; font-size: var(--fs-label); letter-spacing: var(--track-label); color: var(--sand-600); }
.why-panel h3 { font-family: var(--font-display); font-size: clamp(1.3rem, 2.2vw, 1.8rem); text-transform: uppercase; letter-spacing: 0.05em; color: var(--teal-800); }
.why-panel p { font-size: 0.92rem; color: var(--text-muted); max-width: 34em; }
.why-panel::after {
  content: ""; position: absolute; right: 0; bottom: 0; width: 54px; height: 54px;
  background: var(--sand); opacity: 0;
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  transition: opacity var(--dur-std);
}
.why-panel:hover::after { opacity: 0.5; }
@media (max-width: 720px) { .why-grid { grid-template-columns: 1fr; } }

/* ------------------------------ PROJECTS ------------------------------ */
.s-projects { background: var(--charcoal); color: var(--text-on-dark); padding-block: var(--section-pad); overflow: clip; }
.projects-rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(78vw, 420px);
  gap: clamp(1rem, 2vw, 1.8rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; padding-bottom: 1.2rem;
  scrollbar-width: thin; scrollbar-color: var(--sand-600) transparent;
}
.projects-rail::-webkit-scrollbar { height: 4px; }
.projects-rail::-webkit-scrollbar-thumb { background: var(--sand-600); }
.project-card { scroll-snap-align: start; display: grid; gap: 0.8rem; margin: 0; }
.project-card .p-img { overflow: clip; aspect-ratio: 3 / 4; background: var(--teal-900); }
.project-card img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease-out); }
.project-card:hover img { transform: scale(1.04); }
.project-card figcaption { font-size: 0.74rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--text-on-dark-muted); display: flex; gap: 0.8rem; align-items: baseline; }
.project-card figcaption i { font-style: normal; font-size: 0.62rem; color: var(--sand-600); }
.projects-hint { margin-top: 0.6rem; font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-on-dark-muted); display: flex; align-items: center; gap: 0.7rem; }
.projects-hint::after { content: ""; width: 48px; height: 1px; background: var(--sand-600); }

/* ------------------------------ CLIENTS ------------------------------
   Two opposing tracks that drift slowly in opposite directions. Seamless
   because each track renders its logo set twice. Pauses on hover and on
   focus, and collapses to a static grid under reduced motion.
   --------------------------------------------------------------------- */
.s-clients { background: var(--ivory); padding-block: var(--section-pad); overflow: clip; }

.client-marquee { display: grid; gap: clamp(0.7rem, 1.6vw, 1.1rem); }
.client-track {
  display: flex; width: max-content; gap: clamp(0.7rem, 1.6vw, 1.1rem);
  will-change: transform;
}
.client-track.dir-l { animation: client-drift-l 64s linear infinite; }
.client-track.dir-r { animation: client-drift-r 78s linear infinite; }
.client-marquee:hover .client-track,
.client-marquee:focus-within .client-track { animation-play-state: paused; }

@keyframes client-drift-l { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
@keyframes client-drift-r { from { transform: translate3d(-50%, 0, 0); } to { transform: translate3d(0, 0, 0); } }

.client-cell {
  flex: 0 0 auto;
  width: clamp(140px, 15vw, 190px); height: clamp(84px, 9vw, 112px);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(0.8rem, 1.6vw, 1.2rem);
  background: var(--warm-white); border: 1px solid var(--line);
  clip-path: polygon(0 0, calc(100% - 11px) 0, 100% 11px, 100% 100%, 0 100%);
  transition: border-color 300ms var(--ease-out), background-color 300ms var(--ease-out);
}
.client-cell img {
  max-height: 100%; max-width: 100%; width: auto; object-fit: contain;
  filter: grayscale(1); opacity: 0.55;
  transition: filter 380ms var(--ease-out), opacity 380ms var(--ease-out);
}
.client-cell:hover { border-color: rgba(17, 54, 66, 0.3); background: #fff; }
.client-cell:hover img { filter: none; opacity: 1; }

.client-marquee-mask {
  position: relative;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.clients-note { margin-top: 1.6rem; font-size: 0.8rem; color: var(--text-muted); }

@media (max-width: 640px) {
  .client-cell { width: 118px; height: 72px; padding: 0.7rem; }
  .client-track.dir-l { animation-duration: 46s; }
  .client-track.dir-r { animation-duration: 56s; }
}

@media (prefers-reduced-motion: reduce) {
  .client-track { animation: none !important; width: 100%; flex-wrap: wrap; justify-content: center; }
  .client-track .client-dup { display: none; }
  .client-marquee-mask { -webkit-mask-image: none; mask-image: none; }
}


/* ------------------------------ SHOWROOM ------------------------------ */
.s-showroom { background: var(--limestone); padding-block: var(--section-pad); overflow: clip; }
.showroom-grid { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: clamp(1.2rem, 2.5vw, 2rem); align-items: stretch; }
.showroom-main { overflow: clip; clip-path: polygon(0 1.5%, 98% 0, 100% 98.5%, 2% 100%); position: relative; }
.showroom-main img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/3.4; }
.showroom-side { display: grid; grid-template-rows: 1fr 1fr; gap: clamp(1.2rem, 2.5vw, 2rem); }
.showroom-side figure { overflow: clip; position: relative; margin: 0; }
.showroom-side img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.8s var(--ease-out); }
.showroom-side figure:hover img { transform: scale(1.04); }
.showroom-exterior { position: relative; margin-top: clamp(1.2rem, 2.5vw, 2rem); overflow: clip; }
.showroom-exterior img { width: 100%; object-fit: cover; aspect-ratio: 21/8; object-position: center 35%; }
.showroom-exterior .se-overlay {
  position: absolute; inset: auto 0 0 0;
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem;
  padding: clamp(1.6rem, 3vw, 2.2rem) clamp(1.2rem, 3vw, 2rem);
  /* reaches full strength before the content starts, so text and controls
     never depend on how bright the photograph happens to be */
  background: linear-gradient(to top, rgba(8, 30, 38, 0.95) 0%, rgba(8, 30, 38, 0.88) 55%, rgba(8, 30, 38, 0) 100%);
  color: var(--text-on-dark);
}
/* solid plate rather than a translucent one, for the same reason */
.showroom-exterior .btn-ghost { background: rgba(8, 30, 38, 0.82); }
.showroom-exterior .btn-ghost:hover { background: rgba(213, 189, 171, 0.2); }
.showroom-exterior address { font-style: normal; font-size: 0.9rem; line-height: 1.7; color: var(--sand-200); }
.showroom-exterior .label { color: var(--sand); }
.showroom-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; }
@media (max-width: 860px) {
  .showroom-grid { grid-template-columns: 1fr; }
  .showroom-side { grid-template-rows: none; grid-template-columns: 1fr 1fr; }
  .showroom-side img { aspect-ratio: 1/1; }
}

/* ---- mobile showroom: compact swipe gallery, uncropped storefront ----
   Interiors become a horizontal snap rail instead of tall stacked photos,
   and the exterior is shown whole rather than cover cropped, because the
   point of that photograph is the building and the signage. */
@media (max-width: 767px) {
  .showroom-grid {
    display: grid; grid-auto-flow: column;
    grid-auto-columns: 78%; grid-template-columns: none;
    gap: 0.7rem;
    overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    padding-bottom: 0.7rem;
    scrollbar-width: thin; scrollbar-color: var(--sand-600) transparent;
  }
  .showroom-grid::-webkit-scrollbar { height: 3px; }
  .showroom-grid::-webkit-scrollbar-thumb { background: var(--sand-600); }
  .showroom-main, .showroom-side figure { scroll-snap-align: start; margin: 0; }
  .showroom-main { clip-path: polygon(0 1.5%, 98% 0, 100% 98.5%, 2% 100%); }
  .showroom-main img { aspect-ratio: 4/3; height: auto; }
  /* the side pair stops being a grid and joins the rail */
  .showroom-side { display: contents; }
  .showroom-side img { aspect-ratio: 4/3; height: auto; }

  .showroom-exterior { margin-top: 1.1rem; }
  .showroom-exterior img {
    /* show the whole storefront: no aspect lock, no cover crop */
    aspect-ratio: auto; object-fit: contain; object-position: center;
    width: 100%; height: auto;
    background: var(--teal-950);
  }
  .showroom-exterior .se-overlay {
    position: static; background: var(--teal-900);
    flex-direction: column; align-items: stretch; gap: 1rem;
    padding: 1.2rem;
  }
  /* A 1fr 1fr split gave both buttons 118px at 320px while the desktop
     1.9rem side padding ate 61px of it, leaving a 56px content box for a
     label that needs 137px. Size the pair from their labels instead: flex
     basis auto lets GET DIRECTIONS take the width it actually needs and
     CALL US take the rest, so they stay a balanced pair without wrapping. */
  .showroom-actions { display: flex; flex-wrap: nowrap; gap: 0.5rem; }
  .showroom-actions .btn {
    flex: 1 1 auto; min-width: min-content; width: auto;
    justify-content: center; white-space: nowrap;
    padding-inline: clamp(0.65rem, 3vw, 1.4rem);
    letter-spacing: 0.13em;
    gap: 0.5rem;
  }
  .showroom-hint {
    display: flex; align-items: center; gap: 0.7rem;
    margin-top: 0.5rem;
    font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--greige);
  }
  .showroom-hint::after { content: ""; flex: 1; height: 1px; background: var(--line); }
}
.showroom-hint { display: none; }

/* ------------------------------ FOUNDER ------------------------------ */
.s-founder { background: var(--warm-white); padding-block: var(--section-pad); overflow: clip; }
.founder-photo-grid { display: grid; grid-template-columns: minmax(280px, 420px) 1fr; gap: clamp(2rem, 5vw, 5rem); align-items: center; }
.founder-photo { position: relative; overflow: clip; clip-path: polygon(0 2%, 96% 0, 100% 98%, 3% 100%); }
.founder-photo img { width: 100%; height: auto; }
.founder-copy { display: grid; gap: 1.4rem; }
.founder-name {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(2rem, 5vw, 4rem); line-height: 1.05; letter-spacing: 0.02em;
  color: var(--teal-800);
}
.founder-name small { display: block; font-family: var(--font-body); font-size: var(--fs-label); font-weight: 600; letter-spacing: var(--track-label); color: var(--sand-600); margin-top: 0.9rem; }
.founder-story p { color: var(--text-muted); max-width: 36em; }
.founder-story p + p { margin-top: 1rem; }
.founder-side { display: grid; gap: 1.1rem; border-left: 2px solid var(--sand); padding-left: clamp(1.2rem, 2.5vw, 2rem); margin-top: 0.6rem; }
.founder-side .fs-line { display: grid; gap: 0.2rem; }
.founder-side b { font-family: var(--font-display); font-weight: 500; text-transform: uppercase; letter-spacing: 0.06em; color: var(--teal); font-size: 1.02rem; }
.founder-side span { font-size: 0.85rem; color: var(--text-muted); }
@media (max-width: 820px) {
  .founder-photo-grid { grid-template-columns: 1fr; }
  .founder-photo { max-width: 420px; }
}

/* ------------------------------ REVIEWS ------------------------------ */
.s-reviews { background: var(--ivory); padding-block: var(--section-pad); }
.reviews-head-row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1.5rem; margin-bottom: clamp(2rem, 5vw, 3.5rem); }
.reviews-head-row .sec-head { margin-bottom: 0; }
.reviews-rail {
  display: grid; grid-auto-flow: column; grid-auto-columns: min(84vw, 380px);
  gap: clamp(1rem, 2vw, 1.6rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; padding-bottom: 1.2rem;
  scrollbar-width: thin; scrollbar-color: var(--sand-600) transparent;
}
.reviews-rail::-webkit-scrollbar { height: 4px; }
.reviews-rail::-webkit-scrollbar-thumb { background: var(--sand-600); }
.review-card {
  scroll-snap-align: start;
  border: 1px solid var(--line); background: var(--warm-white);
  padding: clamp(1.4rem, 2.5vw, 2rem);
  display: grid; grid-template-rows: auto 1fr auto; gap: 1rem; align-items: start;
  clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}
.review-card .r-stars { display: inline-flex; gap: 0.25rem; }
.review-card .r-stars svg { width: 14px; height: 14px; fill: var(--sand-600); }
.review-card .r-text { font-size: 0.92rem; color: var(--text-muted); line-height: 1.7; }
.review-card .r-name { font-weight: 600; font-size: 0.82rem; letter-spacing: 0.06em; color: var(--teal-800); }
.review-card .r-src { font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--greige); margin-top: 0.15rem; }

/* ------------------------------ BONDS ------------------------------ */
.s-bonds { background: var(--sand); color: var(--teal-900); padding-block: clamp(3.5rem, 8vw, 6rem); overflow: clip; }
.bonds-grid { display: grid; grid-template-columns: 1fr auto; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.bonds-copy { display: grid; gap: 1rem; max-width: 560px; }
.bonds-copy h2 { font-size: clamp(1.6rem, 3.6vw, 2.8rem); }
.bonds-copy p { color: #6E5847; font-size: 0.95rem; }
.bonds-copy .label { color: #8A6F5B; }
.bonds-packs { display: flex; gap: clamp(1.2rem, 3vw, 2.4rem); align-items: flex-end; }
.bond-pack { display: grid; gap: 0.7rem; justify-items: center; margin: 0; }
.bond-pack .bp-img { width: clamp(130px, 16vw, 200px); overflow: clip; }
.bond-pack img { width: 100%; height: auto; }
.bond-pack figcaption { font-size: 0.72rem; letter-spacing: 0.16em; text-transform: uppercase; color: #6E5847; font-weight: 600; }
@media (max-width: 780px) { .bonds-grid { grid-template-columns: 1fr; } }

/* ------------------------------ SANITARY ------------------------------ */
.s-sanitary { background: var(--teal-900); color: var(--text-on-dark); padding-block: var(--section-pad); overflow: clip; }
.sanitary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2.5rem, 6vw, 6rem); }
.sanitary-cats { display: grid; align-content: start; border-top: 1px solid var(--line-on-dark); }
.sanitary-cat {
  display: grid; grid-template-columns: auto 1fr; gap: 1.4rem; align-items: baseline;
  padding: 0.95rem 0.2rem; border-bottom: 1px solid var(--line-on-dark);
  transition: padding-left var(--dur-std) var(--ease-out), background-color var(--dur-std);
}
.sanitary-cat:hover { padding-left: 0.8rem; background: rgba(213, 189, 171, 0.05); }
.sanitary-cat .idx { font-size: 0.64rem; letter-spacing: 0.2em; color: var(--teal-400); }
.sanitary-cat .name { font-family: var(--font-display); font-size: clamp(1.05rem, 1.8vw, 1.45rem); text-transform: uppercase; letter-spacing: 0.06em; color: var(--sand-200); }
.sanitary-side { display: grid; gap: 1.6rem; align-content: start; }
.sanitary-brands { display: grid; gap: 1rem; margin-top: 0.6rem; }
.sanitary-brand {
  display: grid; grid-template-columns: 110px 1fr; gap: 1.4rem; align-items: center;
  border: 1px solid var(--line-on-dark); padding: 1.1rem 1.3rem;
}
.sanitary-brand .sb-logo { background: var(--warm-white); padding: 0.55rem 0.8rem; display: flex; align-items: center; justify-content: center; height: 64px; }
.sanitary-brand .sb-logo img { max-height: 100%; max-width: 100%; width: auto; object-fit: contain; }
.sanitary-brand .sb-name { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.06em; font-size: 1.05rem; color: var(--sand-200); }
.sanitary-brand .sb-note { font-size: 0.8rem; color: var(--text-on-dark-muted); }
@media (max-width: 860px) { .sanitary-grid { grid-template-columns: 1fr; } }

/* ------------------------------ CATALOG GATEWAY ------------------------------ */
.s-gateway { background: var(--teal-950); color: var(--text-on-dark); padding-block: var(--section-pad); overflow: clip; }
.gateway-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2.5rem, 6vw, 5rem); align-items: center; }
.gateway-copy { display: grid; gap: 1.4rem; }
.gateway-stack { position: relative; height: clamp(300px, 42vw, 460px); perspective: 1200px; }
.gateway-stack .gw-card {
  position: absolute; width: min(58%, 300px); aspect-ratio: 1000/720;
  background-size: cover; background-position: top center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
  transition: transform 0.5s var(--ease-out);
  outline: 1px solid rgba(213, 189, 171, 0.18);
}
.gateway-stack .gw-card:nth-child(1) { left: 4%; top: 8%; transform: rotate(-4deg); z-index: 1; }
.gateway-stack .gw-card:nth-child(2) { left: 26%; top: 26%; transform: rotate(2deg); z-index: 2; }
.gateway-stack .gw-card:nth-child(3) { left: 46%; top: 6%; transform: rotate(6deg); z-index: 1; }
@media (max-width: 860px) { .gateway-grid { grid-template-columns: 1fr; } .gateway-stack { order: -1; height: 300px; } }

/* ---- mobile material library ----
   The absolutely positioned card stack could reach past the right edge on
   narrow screens. Below 767px it becomes a centred fan that is measured from
   the container, so both gutters stay equal and nothing touches the edge. */
@media (max-width: 767px) {
  .gateway-stack {
    height: auto; order: -1; perspective: none;
    display: flex; justify-content: center; align-items: flex-start;
    gap: 0; padding: 0.5rem 0 1rem;
  }
  .gateway-stack .gw-card {
    position: relative; left: auto; top: auto;
    width: 46%; max-width: 190px;
    box-shadow: 0 14px 34px rgba(0, 0, 0, 0.4);
  }
  /* the desktop nth-child rules carry left offsets; they must be cleared here
     or the fan is pushed past the right edge */
  .gateway-stack .gw-card:nth-child(1) { left: auto; top: auto; transform: rotate(-5deg) translateX(12%); z-index: 1; }
  .gateway-stack .gw-card:nth-child(2) { left: auto; top: auto; transform: rotate(0deg); z-index: 3; }
  .gateway-stack .gw-card:nth-child(3) { left: auto; top: auto; transform: rotate(5deg) translateX(-12%); z-index: 2; }
}
@media (max-width: 380px) {
  .gateway-stack .gw-card { width: 50%; }
  .gateway-stack .gw-card:nth-child(1) { left: auto; top: auto; transform: rotate(-4deg) translateX(16%); }
  .gateway-stack .gw-card:nth-child(3) { left: auto; top: auto; transform: rotate(4deg) translateX(-16%); }
}

/* ------------------------------ LOCATION / QUOTE ------------------------------ */
.s-quote { background: var(--teal-900); color: var(--text-on-dark); padding-block: var(--section-pad); position: relative; overflow: clip; }
.s-quote::before {
  content: ""; position: absolute; left: -6%; bottom: -30%;
  width: 40vw; height: 120%;
  background: url("../assets/logo/mark-sand.png") no-repeat center / contain;
  opacity: 0.04; pointer-events: none;
}
/* Both columns size to their own content. Stretching them left the form box
   taller than the fields inside it, which read as dead space under the submit
   button once the delivery note was taken out. */
.quote-grid {
  display: grid; grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(2.5rem, 6vw, 5.5rem);
  align-items: start; position: relative;
}
.quote-intro { display: grid; gap: 1.4rem; align-content: start; }
.quote-contacts {
  display: grid; gap: 1.35rem; margin-top: 0.6rem;
  padding-top: 1.5rem; border-top: 1px solid var(--line-on-dark);
}
.quote-line { display: grid; gap: 0.35rem; }
.quote-line .label { font-size: 0.64rem; color: var(--sand); }
.quote-line a {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.7vw, 1.32rem);
  letter-spacing: 0.05em; color: var(--sand-200);
  justify-self: start;
  transition: color 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.quote-line a:hover { color: var(--sand); transform: translateX(3px); }
/* the Visit line is an address, so keep it at body scale for readability */
.quote-line:last-child a { font-family: var(--font-body); font-size: 0.95rem; letter-spacing: 0; line-height: 1.6; }
.quote-alt { display: grid; gap: 0.6rem; margin-top: 1rem; padding-top: 1.6rem; border-top: 1px solid var(--line-on-dark); }
.quote-alt p { font-size: 0.9rem; color: var(--text-on-dark-muted); }

.quote-form { display: grid; gap: 1.3rem; grid-template-columns: 1fr 1fr; align-content: start; }
.field { display: grid; gap: 0.45rem; }
.field-full { grid-column: 1 / -1; }
.field label {
  font-size: var(--fs-label); font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--sand);
}
.field label .req { color: var(--sand); }
.field label .opt {
  font-weight: 400; letter-spacing: 0.02em; text-transform: none;
  color: var(--text-on-dark-muted);
}
.field input, .field select, .field textarea {
  width: 100%; min-height: 54px;
  background: rgba(213, 189, 171, 0.08);
  border: 1px solid rgba(213, 189, 171, 0.42);
  color: #F2ECE4;
  font: inherit; font-size: 0.95rem;
  padding: 0.85rem 1rem;
  transition: border-color 200ms var(--ease-out), background-color 200ms var(--ease-out), box-shadow 200ms var(--ease-out);
  border-radius: 0;
}
.field textarea { min-height: 128px; resize: vertical; }
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23D5BDAB' stroke-width='1.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center;
}
.field select option { color: var(--ink); background: var(--warm-white); }
.field input:hover, .field select:hover, .field textarea:hover { border-color: rgba(213, 189, 171, 0.62); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--sand);
  background: rgba(213, 189, 171, 0.13);
  box-shadow: 0 0 0 3px rgba(213, 189, 171, 0.16);
}
.field input::placeholder, .field textarea::placeholder { color: rgba(233, 226, 216, 0.52); }
.field .err { display: none; font-size: 0.78rem; color: #F0BCA6; }
.field.has-error input, .field.has-error select, .field.has-error textarea {
  border-color: #D9906F; background: rgba(217, 144, 111, 0.1);
}
.field.has-error .err { display: block; }
.quote-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 1.4rem; }
.quote-status { grid-column: 1 / -1; display: none; padding: 1.1rem 1.3rem; font-size: 0.9rem; border: 1px solid var(--line-on-dark); }
.quote-status.ok { display: block; border-color: rgba(168, 205, 176, 0.5); color: #CBE3CF; }
.quote-status.fail { display: block; border-color: #C77F62; color: #EFC5B2; }
@media (max-width: 860px) { .quote-grid { grid-template-columns: 1fr; } .quote-form { grid-template-columns: 1fr; } }

/* ------------------------------ FOOTER ------------------------------
   The closing plane. A single architectural surface: a direct invitation,
   a compact information band, then an oversized SIMPLY ENDURING wordmark
   that sits on the horizon line and is cropped by the page edge, echoing
   the way the hero opens. No column grid, no repeated site map.
   --------------------------------------------------------------------- */
.footer {
  position: relative; overflow: clip;
  background: var(--teal-950); color: var(--text-on-dark);
  border-top: 1px solid rgba(213, 189, 171, 0.12);
}
.footer-inner {
  position: relative; z-index: 1;
  padding: clamp(3rem, 6vw, 5rem) 0 0;
}

/* ---- 1. closing invitation ---- */
.footer-lead {
  display: grid; grid-template-columns: 1.35fr auto;
  gap: clamp(1.5rem, 4vw, 3.5rem); align-items: end;
  padding-bottom: clamp(2rem, 4vw, 3rem);
}
.footer-lead h2 {
  font-family: var(--font-display); text-transform: uppercase;
  font-size: clamp(1.75rem, 4.4vw, 3.4rem); line-height: 1.06;
  letter-spacing: 0.02em; color: var(--sand-200); max-width: 15em;
}
.footer-lead .fl-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; }

/* ---- 2. information band: address / contact / links ---- */
.footer-band {
  display: grid;
  grid-template-columns: 1.1fr 1fr auto;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding: clamp(1.6rem, 3vw, 2.2rem) 0;
  border-top: 1px solid rgba(213, 189, 171, 0.14);
  border-bottom: 1px solid rgba(213, 189, 171, 0.14);
}
.footer-band h3 {
  font-size: 0.64rem; font-weight: 600; letter-spacing: var(--track-label);
  text-transform: uppercase; color: var(--sand); margin-bottom: 0.85rem;
}
.footer-band address, .footer-band p { font-style: normal; font-size: 0.88rem; line-height: 1.75; color: var(--text-on-dark-muted); }
.footer-band a {
  color: var(--text-on-dark-muted); display: inline-block;
  transition: color 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.footer-band a:hover { color: var(--sand-200); transform: translateX(3px); }
.footer-contact-list { display: grid; gap: 0.3rem; }

/* compact link cluster, not a site map */
.footer-jump { display: grid; gap: 0.45rem; align-content: start; }
.footer-jump a { font-size: 0.86rem; white-space: nowrap; }

.footer-social { display: flex; gap: 0.6rem; margin-top: 1rem; }
.footer-social a {
  width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-on-dark); color: var(--sand-200);
  clip-path: polygon(0 0, calc(100% - 8px) 0, 100% 8px, 100% 100%, 0 100%);
  transition: background-color 220ms var(--ease-out), border-color 220ms var(--ease-out), color 220ms var(--ease-out);
}
.footer-social a:hover { background: rgba(213, 189, 171, 0.12); border-color: var(--sand); color: var(--sand); transform: none; }
.footer-social svg { width: 15px; height: 15px; fill: currentColor; }

/* ---- 3. the brand horizon: the tagline as an architectural signature ----
   The wordmark must sit INSIDE the footer container, not the viewport. It used
   to be sized in vw while living in a container ~200px narrower than the
   viewport, so at 1440px it measured 1380px inside a 1240px box and the tail
   ("...ENDURIN") was swallowed by the overflow clip below.
   Fixed by sizing in container query units: VONCA sets "SIMPLY ENDURING" at
   8.264x the font size with the 0.005em tracking included, so the phrase fills
   the full container at 12.10cqw. 11.4cqw leaves ~6% as breathing room. */
.footer-horizon {
  position: relative;
  padding-top: clamp(2rem, 4vw, 3rem);
  container-type: inline-size;
  overflow: clip;
}
.footer-wordmark {
  display: block; width: 100%;
  font-family: var(--font-display); text-transform: uppercase;
  /* fallback for browsers without container query units, deliberately
     conservative since it can only measure the viewport */
  font-size: clamp(2.6rem, 10.2vw, 9.1rem);
  /* the real rule: derived from the container, so it can never overrun */
  font-size: clamp(2.6rem, 11.4cqw, 11rem);
  line-height: 0.86; letter-spacing: 0.005em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(213, 189, 171, 0.34);
  white-space: nowrap;
  text-align: center;
  /* the wordmark rises out of the horizon line */
  transform: translateY(0.16em);
  user-select: none;
}
/* if text stroke is unsupported the wordmark must not vanish */
@supports not ((-webkit-text-stroke: 1px currentColor) or (text-stroke: 1px currentColor)) {
  .footer-wordmark { color: rgba(213, 189, 171, 0.16); }
}
.footer-horizon .fh-line {
  position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, rgba(213,189,171,0.5), rgba(213,189,171,0.06));
}

/* ---- 4. micro footer ---- */
.footer-micro {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding: 1.1rem 0 1.3rem;
  font-size: 0.72rem; color: var(--text-on-dark-muted);
}
.footer-credit { color: var(--text-on-dark-muted); }
/* only the studio name is the link, never the whole sentence */
.footer-credit .naotix {
  position: relative;
  display: inline-block;
  color: var(--sand); font-weight: 600; letter-spacing: 0.06em;
  text-decoration: none; cursor: pointer;
  transition: color 200ms var(--ease-out);
}
.footer-credit .naotix::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px;
  background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 260ms var(--ease-arch);
}
.footer-credit .naotix:hover,
.footer-credit .naotix:focus-visible { color: var(--sand-200); }
.footer-credit .naotix:hover::after,
.footer-credit .naotix:focus-visible::after { transform: scaleX(1); }

/* The address reveals above the name on hover and focus. It is drawn from a
   data attribute in a pseudo element, so it is never part of the document
   text: the footer still reads "Designed & Developed by Naotix" when copied
   or read aloud, and no browser title tooltip is involved. */
.footer-credit .naotix::before {
  content: attr(data-url);
  position: absolute; bottom: calc(100% + 9px); left: 50%;
  transform: translate(-50%, 4px);
  padding: 0.34rem 0.62rem;
  background: var(--teal-900);
  border: 1px solid rgba(213, 189, 171, 0.26);
  clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 0 100%);
  font-size: 0.66rem; font-weight: 600; letter-spacing: 0.1em;
  color: var(--sand-200); white-space: nowrap;
  opacity: 0; pointer-events: none; visibility: hidden;
  transition: opacity 220ms var(--ease-out), transform 300ms var(--ease-arch), visibility 0s 220ms;
}
.footer-credit .naotix:hover::before,
.footer-credit .naotix:focus-visible::before {
  opacity: 1; transform: translate(-50%, 0); visibility: visible; transition-delay: 0s;
}
/* touch devices have no hover, so the name carries a standing underline
   instead and the address label never appears */
/* Touch devices: no hover, so neither the address label nor the underline has
   any reason to exist. The name carries the champagne colour on its own, which
   is already the site's link signal. The rule is `content: none` on both
   pseudo elements rather than a cosmetic override, so nothing is painted. */
@media (hover: none), (pointer: coarse) {
  .footer-credit .naotix::before,
  .footer-credit .naotix::after { content: none; }
  /* 44px tall hit area, cancelled by matching negative margins so the
     legal row keeps exactly the same layout */
  .footer-credit .naotix { padding: 0.8rem 0.2rem; margin: -0.8rem -0.2rem; }
}
@media (prefers-reduced-motion: reduce) {
  .footer-credit .naotix::before,
  .footer-credit .naotix::after { transition-duration: 1ms; }
}

@media (max-width: 900px) {
  .footer-lead { grid-template-columns: 1fr; align-items: start; }
  .footer-band { grid-template-columns: 1fr 1fr; }
  .footer-jump { grid-column: 1 / -1; grid-auto-flow: column; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 0.5rem 1rem; }
}
/* ---- mobile brand horizon ----
   One line of SIMPLY ENDURING cannot fill a narrow viewport without becoming
   hairline thin, so on mobile it stacks into two lines sized to the container
   and keeps the stroke weight readable. */
@media (max-width: 767px) {
  .footer-horizon { padding-top: 1.8rem; }
  .footer-wordmark {
    font-size: clamp(2.1rem, 15.5vw, 3.6rem);
    line-height: 0.92;
    white-space: normal;
    /* the stacked mobile lines stay left aligned with the rest of the footer;
       only the single line desktop signature is centred */
    text-align: left;
    -webkit-text-stroke-width: 0.8px;
    transform: translateY(0.1em);
  }
  .footer-wordmark .fw-line { display: block; }
}
@media (max-width: 640px) {
  .footer-band { grid-template-columns: 1fr; gap: 1.6rem; }
  .footer-jump { grid-auto-flow: row; grid-template-columns: 1fr 1fr; }
  .footer-jump a { min-height: 40px; display: flex; align-items: center; }
  .footer-lead .fl-actions { width: 100%; }
  .footer-lead .fl-actions .btn { flex: 1 1 100%; justify-content: center; }
  .footer-micro { flex-direction: column; align-items: flex-start; }
  /* clear the sticky WhatsApp / Call / Quote bar */
  .footer-micro { padding-bottom: calc(56px + 1.4rem + env(safe-area-inset-bottom, 0px)); }
}
@media (max-width: 767px) {
  .footer-micro { padding-bottom: calc(56px + 1.4rem + env(safe-area-inset-bottom, 0px)); }
}


/* ------------------------------ WHATSAPP WIDGET ------------------------------ */
.wa-widget { position: fixed; right: 1.4rem; bottom: 1.4rem; z-index: var(--z-widget); display: grid; justify-items: end; gap: 0.9rem; }
.wa-toggle {
  width: 56px; height: 56px; border-radius: 50%;
  background: var(--teal); color: var(--sand-200);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 30px rgba(8, 30, 38, 0.35);
  border: 1px solid rgba(213, 189, 171, 0.25);
  opacity: 0; transform: translateY(14px); pointer-events: none;
  transition: opacity var(--dur-std) var(--ease-out), transform var(--dur-std) var(--ease-out), background-color var(--dur-fast);
}
.wa-widget.is-visible .wa-toggle { opacity: 1; transform: none; pointer-events: auto; }
.wa-toggle:hover { background: var(--teal-700); }
.wa-toggle svg { width: 24px; height: 24px; fill: currentColor; }
.wa-panel {
  width: min(320px, calc(100vw - 2.8rem));
  background: var(--teal-900); color: var(--text-on-dark);
  border: 1px solid var(--line-on-dark);
  padding: 1.5rem; display: grid; gap: 1rem;
  clip-path: polygon(0 0, calc(100% - 18px) 0, 100% 18px, 100% 100%, 0 100%);
  opacity: 0; transform: translateY(10px); pointer-events: none; visibility: hidden;
  transition: opacity var(--dur-std) var(--ease-out), transform var(--dur-std) var(--ease-out), visibility 0s var(--dur-std);
}
.wa-widget.is-open .wa-panel { opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition-delay: 0s; }
.wa-panel .wp-title { font-family: var(--font-display); text-transform: uppercase; letter-spacing: 0.1em; font-size: 1.05rem; color: var(--sand-200); }
.wa-panel p { font-size: 0.85rem; color: var(--text-on-dark-muted); }
.wa-panel .btn { justify-content: center; width: 100%; }
/* Below 768px the floating button is unmounted by main.js because WhatsApp
   already sits in the bottom action bar. This rule is only a safety net for
   the no JavaScript case, so no invisible tap target is ever left behind. */
@media (max-width: 767px) { .wa-widget { display: none !important; } }

/* mobile sticky action bar */
.mobile-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-widget);
  display: none; grid-template-columns: 1fr 1fr 1fr;
  background: rgba(12, 41, 51, 0.96);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-top: 1px solid rgba(213, 189, 171, 0.18);
  transform: translateY(100%);
  transition: transform var(--dur-std) var(--ease-out);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.mobile-bar.is-visible { transform: none; }
.mobile-bar a {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  min-height: 56px; font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--sand-200);
}
.mobile-bar a + a { border-left: 1px solid rgba(213, 189, 171, 0.14); }
.mobile-bar svg { width: 16px; height: 16px; fill: currentColor; }
@media (max-width: 767px) { .mobile-bar { display: grid; } }

/* ------------------------------ CATALOG PAGE ------------------------------ */
.cat-hero {
  background: var(--teal-900); color: var(--text-on-dark);
  padding: clamp(9rem, 18vh, 12rem) 0 clamp(3rem, 6vw, 4.5rem);
  position: relative; overflow: clip;
}
.cat-hero::before {
  content: ""; position: absolute; inset: 0;
  background: url("../assets/showroom/showroom-05.webp") right center / cover no-repeat;
  opacity: 0.18;
}
.cat-hero::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, var(--teal-900) 30%, rgba(12, 41, 51, 0.55)); }
.cat-hero .container-wide { position: relative; z-index: 1; display: grid; gap: 1.3rem; }
.cat-hero h1 { font-size: clamp(2.2rem, 6vw, 4.6rem); max-width: 12em; }
.cat-hero .lede { color: var(--text-on-dark-muted); }
.cat-count { font-size: var(--fs-label); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--sand-600); }

/* ---------------------- CATALOG SELECTOR ----------------------
   One control instead of a wall of buttons. Desktop opens an
   architectural panel grouped by category; mobile opens a full
   height sheet. Both share the same markup and state.
   -------------------------------------------------------------- */
/* ---------------------- CATALOGUE TOOLBAR ----------------------
   One control strip: brand selector, search, result count. Both
   fields share the same height, border and cut corner so they read
   as a single instrument rather than two unrelated widgets.
   ---------------------------------------------------------------- */
.cat-toolbar {
  position: sticky; top: 0; z-index: 30;
  background: rgba(250, 247, 242, 0.94);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
  padding: 0.85rem 0;
}
.cat-toolbar-inner {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(0.7rem, 1.6vw, 1.25rem);
}

/* shared field shell so the two controls match exactly */
.cat-select-btn,
.cat-search input {
  height: 52px; width: 100%;
  background: var(--warm-white);
  border: 1px solid rgba(17, 54, 66, 0.26);
  color: var(--teal-800);
  border-radius: 0;
  clip-path: polygon(0 0, calc(100% - 13px) 0, 100% 13px, 100% 100%, 0 100%);
  transition: border-color 220ms var(--ease-out), background-color 220ms var(--ease-out);
}
.cat-select-btn:hover,
.cat-search input:hover { border-color: rgba(17, 54, 66, 0.5); }
.cat-select-btn:focus-visible,
.cat-search input:focus { outline: none; border-color: var(--teal-600); background: var(--ivory); }

/* ---- brand selector ---- */
.cat-select { position: relative; min-width: 0; }
.cat-select-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0 1rem 0 1.1rem; text-align: left; cursor: pointer;
}
.cat-select-btn .cs-label {
  display: block; font-size: 0.56rem; font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--greige); margin-bottom: 0.15rem;
}
.cat-select-btn .cs-value {
  display: block; font-family: var(--font-display);
  font-size: 0.98rem; letter-spacing: 0.05em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cat-select-btn .cs-caret {
  width: 10px; height: 10px; flex: none;
  border-right: 1.6px solid var(--teal-600); border-bottom: 1.6px solid var(--teal-600);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 320ms var(--ease-arch);
}
.cat-select.is-open .cs-caret { transform: rotate(-135deg) translate(-2px, -2px); }

/* ---- search ----
   The icon is absolutely positioned and explicitly sized. Without these
   rules an inline svg falls back to 300x150 with a black fill, which is
   what produced the large black circle. */
.cat-search { position: relative; min-width: 0; }
.cat-search input {
  font: inherit; font-size: 0.92rem;
  padding: 0 2.6rem 0 2.7rem;
  -webkit-appearance: none; appearance: none;
}
.cat-search input::placeholder { color: var(--greige); opacity: 1; }
.cat-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.cat-search .cs-icon {
  position: absolute; left: 1rem; top: 50%; transform: translateY(-50%);
  width: 16px; height: 16px; flex: none; pointer-events: none;
  fill: none; stroke: var(--greige); stroke-width: 1.7;
  stroke-linecap: round;
  transition: stroke 220ms var(--ease-out);
}
.cat-search input:focus ~ .cs-icon { stroke: var(--teal-600); }
.cat-search-clear {
  position: absolute; right: 0.55rem; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; display: none;
  align-items: center; justify-content: center;
  color: var(--greige); cursor: pointer;
  transition: color 200ms var(--ease-out);
}
.cat-search.has-value .cat-search-clear { display: inline-flex; }
.cat-search-clear:hover { color: var(--teal); }
.cat-search-clear svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 1.8; }

/* ---- result count ---- */
.cat-count {
  margin: 0; justify-self: end; white-space: nowrap;
  font-size: 0.64rem; font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--teal-600);
  font-variant-numeric: tabular-nums;
}
.cat-count b { font-weight: 600; color: var(--teal); }

/* field labels: mobile only */
.cat-field-label { display: none; }

/* ---- dropdown panel ---- */
.cat-select-panel {
  position: absolute; top: calc(100% + 8px); left: 0;
  width: min(400px, 88vw);
  background: var(--teal-950); color: var(--text-on-dark);
  border: 1px solid rgba(213, 189, 171, 0.22);
  clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
  padding: 0.7rem 0;
  max-height: min(64vh, 460px); overflow-y: auto; overscroll-behavior: contain;
  opacity: 0; transform: translateY(-8px); pointer-events: none; visibility: hidden;
  transition: opacity 220ms var(--ease-out), transform 300ms var(--ease-arch), visibility 0s 220ms;
  z-index: 60;
  box-shadow: 0 26px 60px rgba(8, 30, 38, 0.28);
}
.cat-select.is-open .cat-select-panel {
  opacity: 1; transform: none; pointer-events: auto; visibility: visible; transition-delay: 0s;
}
.cat-group-label {
  padding: 0.7rem 1.1rem 0.35rem;
  font-size: 0.56rem; font-weight: 600;
  letter-spacing: var(--track-label); text-transform: uppercase;
  color: var(--sand);
}
.cat-option {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; min-height: 44px; padding: 0.5rem 1.1rem;
  background: none; border: 0; text-align: left; cursor: pointer;
  color: var(--text-on-dark-muted); font-size: 0.86rem;
  transition: color 200ms var(--ease-out), background-color 200ms var(--ease-out), padding-left 240ms var(--ease-out);
}
.cat-option:hover, .cat-option:focus-visible { color: var(--sand-200); background: rgba(213, 189, 171, 0.08); padding-left: 1.4rem; }
.cat-option .co-count { font-size: 0.68rem; color: var(--teal-400); font-variant-numeric: tabular-nums; }
.cat-option[aria-selected="true"] {
  color: var(--sand); background: rgba(213, 189, 171, 0.1); padding-left: 0.85rem;
}
.cat-option[aria-selected="true"]::before {
  content: ""; width: 6px; height: 6px; margin-right: 0.55rem; flex: none;
  background: var(--sand); clip-path: polygon(0 0, 100% 18%, 82% 100%, 12% 88%);
}

/* the backdrop belongs to the mobile sheet; never paint it on desktop */
@media (min-width: 768px) { .cat-sheet-backdrop { display: none !important; } }
.cat-sheet-backdrop {
  position: fixed; inset: 0; z-index: 44;
  background: rgba(8, 30, 38, 0.5);
  opacity: 0; pointer-events: none; visibility: hidden;
  transition: opacity 260ms var(--ease-out), visibility 0s 260ms;
}
body.cat-sheet-open .cat-sheet-backdrop { opacity: 1; pointer-events: auto; visibility: visible; transition-delay: 0s; }
.cat-sheet-head { display: none; }

/* ---- tablet ---- */
@media (max-width: 900px) {
  .cat-toolbar-inner { grid-template-columns: minmax(0, 260px) minmax(0, 1fr); row-gap: 0.6rem; }
  .cat-count { grid-column: 1 / -1; justify-self: start; }
}

/* ---- mobile: labelled stack, selector becomes a bottom sheet ---- */
@media (max-width: 767px) {
  /* backdrop-filter makes an element the containing block for fixed children,
     which would anchor the bottom sheet to the toolbar instead of the viewport.
     Mobile therefore uses a solid bar, and the stacked toolbar scrolls away
     rather than pinning ~220px of a small viewport. */
  .cat-toolbar {
    position: static;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    background: var(--warm-white);
    padding: 0.9rem 0 1rem;
  }
  .cat-toolbar-inner { grid-template-columns: 1fr; gap: 0.85rem; }
  /* toolbar and grid share one gutter so the controls align with the cards */
  .cat-toolbar, .cat-body { --gutter: 22px; }
  .cat-field { display: grid; gap: 0.35rem; min-width: 0; }
  .cat-field-label {
    display: block; font-size: 0.56rem; font-weight: 600;
    letter-spacing: var(--track-label); text-transform: uppercase; color: var(--greige);
  }
  /* the label sits above, so the control does not need its own */
  .cat-select-btn .cs-label { display: none; }
  .cat-select-btn .cs-value { font-size: 1rem; }
  /* 16px minimum, otherwise iOS Safari zooms the page on focus */
  .cat-search input { font-size: 16px; }
  .cat-count { justify-self: start; padding-top: 0.1rem; }

  .cat-select-panel {
    position: fixed; z-index: 45;
    left: 0; right: 0; bottom: 0; top: auto;
    width: 100%; max-height: 76vh;
    clip-path: none; border: 0;
    border-top: 1px solid rgba(213, 189, 171, 0.24);
    padding-bottom: calc(0.9rem + env(safe-area-inset-bottom, 0px));
    opacity: 1; transform: translateY(100%);
    transition: transform 360ms var(--ease-arch), visibility 0s 360ms;
    box-shadow: 0 -20px 60px rgba(8, 30, 38, 0.4);
  }
  .cat-select.is-open .cat-select-panel { transform: none; }
  .cat-sheet-head {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 1rem 1.1rem 0.7rem;
    border-bottom: 1px solid rgba(213, 189, 171, 0.14);
    position: sticky; top: 0; background: var(--teal-950); z-index: 1;
  }
  .cat-sheet-head b {
    font-family: var(--font-display); font-size: 0.95rem;
    letter-spacing: 0.08em; text-transform: uppercase; color: var(--sand-200);
  }
  .cat-sheet-close {
    display: inline-flex; align-items: center; gap: 0.5rem;
    min-height: 44px; padding: 0.4rem 0.85rem;
    border: 1px solid rgba(213, 189, 171, 0.4); color: var(--sand-200);
    font-size: 0.62rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  }
  .cat-sheet-close svg { width: 11px; height: 11px; stroke: currentColor; stroke-width: 1.8; fill: none; }
  .cat-option { min-height: 50px; }
}

/* ---- results transition when filters change ---- */
.cat-grid.is-swapping { opacity: 0; transform: translateY(6px); }
.cat-grid { transition: opacity 200ms var(--ease-out), transform 260ms var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  .cat-select-panel, .cat-sheet-backdrop, .cs-caret, .cat-option, .cat-grid { transition: none; }
}


.cat-body { background: var(--warm-white); padding-block: clamp(2.5rem, 6vw, 4rem) var(--section-pad); min-height: 50vh; }
.cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: clamp(1.2rem, 2.5vw, 2rem); }
.cat-card {
  display: grid; grid-template-rows: auto 1fr; border: 1px solid var(--line);
  background: var(--warm-white); overflow: clip;
  transition: box-shadow 0.4s var(--ease-out), border-color 0.4s;
}
.cat-card:hover { box-shadow: 0 18px 44px rgba(17, 54, 66, 0.14); border-color: rgba(17, 54, 66, 0.3); }
.cat-card-cover { position: relative; aspect-ratio: 10/7; overflow: clip; background: var(--limestone); }
.cat-card-cover img { width: 100%; height: 100%; object-fit: cover; object-position: top center; transition: transform 0.7s var(--ease-out); }
.cat-card:hover .cat-card-cover img { transform: scale(1.045); }
.cat-card-cover .cc-pages {
  position: absolute; top: 0.8rem; right: 0.8rem;
  background: rgba(12, 41, 51, 0.85); color: var(--sand-200);
  font-size: 0.66rem; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.35rem 0.6rem;
}
.cat-card-body { display: grid; gap: 0.8rem; padding: 1.3rem; align-content: space-between; }
.cat-card-meta { display: grid; gap: 0.35rem; }
.cat-card .cc-brand { font-size: 0.68rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--sand-600); }
.cat-card h3 { font-family: var(--font-display); font-size: 1.15rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--teal-800); }
.cat-card .cc-specs { font-size: 0.78rem; color: var(--text-muted); }
.cat-card-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }
.cat-card-actions .btn { min-height: 44px; padding: 0.55rem 1.1rem; font-size: 0.66rem; }
.cat-empty { display: none; padding: 3.5rem 0; text-align: center; color: var(--text-muted); }
.cat-empty.is-visible { display: block; }
.cat-note { margin-top: clamp(2.5rem, 6vw, 4rem); font-size: 0.85rem; color: var(--text-muted); max-width: 60em; border-top: 1px solid var(--line); padding-top: 1.6rem; }

/* ------------------------------ PDF VIEWER ------------------------------ */
.viewer {
  position: fixed; inset: 0; z-index: var(--z-viewer);
  background: rgba(8, 30, 38, 0.97);
  display: none; grid-template-rows: auto 1fr;
}
.viewer.is-open { display: grid; }
.viewer-bar {
  display: flex; align-items: center; gap: 1rem;
  padding: 0.8rem var(--gutter);
  background: var(--teal-950); border-bottom: 1px solid var(--line-on-dark);
  color: var(--text-on-dark);
}
.viewer-title { display: grid; gap: 0.1rem; margin-right: auto; min-width: 0; }
.viewer-title b { font-family: var(--font-display); font-weight: 400; text-transform: uppercase; letter-spacing: 0.06em; font-size: 1rem; color: var(--sand-200); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.viewer-title span { font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-on-dark-muted); }
.viewer-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.viewer-actions .btn { min-height: 42px; padding: 0.5rem 1rem; font-size: 0.64rem; }
.viewer-close {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-on-dark); color: var(--sand-200); flex: none;
  transition: background-color var(--dur-fast);
}
.viewer-close:hover { background: rgba(213, 189, 171, 0.1); }
.viewer-frame { position: relative; }
.viewer-frame iframe { width: 100%; height: 100%; border: 0; }
.viewer-loading {
  position: absolute; inset: 0; display: flex; flex-direction: column; gap: 1rem;
  align-items: center; justify-content: center; color: var(--text-on-dark-muted);
  font-size: 0.8rem; letter-spacing: 0.14em; text-transform: uppercase; pointer-events: none;
  transition: opacity 0.4s;
}
.viewer-loading .spin {
  width: 40px; height: 40px; border: 2px solid rgba(213, 189, 171, 0.2);
  border-top-color: var(--sand); border-radius: 50%;
  animation: vspin 0.9s linear infinite;
}
@keyframes vspin { to { transform: rotate(360deg); } }
.viewer.is-loaded .viewer-loading { opacity: 0; }
@media (max-width: 640px) {
  .viewer-bar { flex-wrap: wrap; }
  .viewer-title { flex: 1 1 100%; order: -1; }
}

/* ------------------------------ CURSOR ------------------------------
   RKS precision cursor. Two offset angular planes derived from the
   fragmented geometry of the RKS symbol — asymmetric, sharp, with
   controlled negative space. Fine-pointer devices only.
   --------------------------------------------------------------------- */
@media (pointer: fine) and (hover: hover) {
  .rks-cursor {
    position: fixed; top: 0; left: 0; width: 0; height: 0;
    z-index: var(--z-cursor); pointer-events: none;
    will-change: transform; opacity: 0;
    transition: opacity 220ms var(--ease-out);
  }
  html.has-cursor .rks-cursor { opacity: 1; }

  /* hide the native cursor only once the custom one is live */
  html.has-cursor, html.has-cursor * { cursor: none; }
  /* …but never in text-entry contexts */
  html.has-cursor input, html.has-cursor textarea,
  html.has-cursor select, html.has-cursor [contenteditable] { cursor: auto; }
  html.has-cursor input[type="text"], html.has-cursor input[type="tel"],
  html.has-cursor input[type="email"], html.has-cursor input[type="search"],
  html.has-cursor textarea { cursor: text; }

  /* max-width:none — the global `svg { max-width:100% }` would otherwise
     clamp these to 0 because the cursor wrapper is a 0×0 anchor point */
  .rks-cursor svg { position: absolute; overflow: visible; max-width: none; display: block; }

  /* --- normal state: asymmetric angular pointer, tip on the hotspot --- */
  .rks-cursor-pointer {
    left: -1px; top: -1px; width: 22px; height: 22px;
    transition: opacity 200ms var(--ease-out), transform 320ms var(--ease-arch);
    transform: scale(1) rotate(0deg); transform-origin: 1px 1px;
  }
  .rks-cursor-pointer .plane-a { fill: var(--sand); }
  .rks-cursor-pointer .plane-b { fill: var(--sand); opacity: 0.55; }

  /* --- hover state: fragmented geometric frame (two opposing corners) --- */
  .rks-cursor-frame {
    left: 0; top: 0; width: 34px; height: 34px; margin: -17px 0 0 -17px;
    opacity: 0; transform: scale(0.55) rotate(-14deg);
    transition: opacity 240ms var(--ease-out), transform 380ms var(--ease-arch);
  }
  .rks-cursor-frame path { stroke: var(--sand); stroke-width: 1.5; fill: none; }
  .rks-cursor-frame .shard { fill: var(--sand); stroke: none; opacity: 0.9; }

  .rks-cursor-label {
    position: absolute; left: 0; top: 0;
    transform: translate(-50%, -50%) scale(0.8);
    font-family: var(--font-body); font-size: 0.5rem; font-weight: 600;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--teal-950); white-space: nowrap;
    opacity: 0; transition: opacity 200ms var(--ease-out), transform 320ms var(--ease-arch);
  }
  .rks-cursor-plate {
    position: absolute; left: 0; top: 0; width: 46px; height: 46px;
    margin: -23px 0 0 -23px; background: var(--sand);
    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 10px 100%, 0 calc(100% - 10px));
    opacity: 0; transform: scale(0.5) rotate(-10deg);
    transition: opacity 240ms var(--ease-out), transform 380ms var(--ease-arch);
  }

  /* interactive: links, buttons, controls */
  .rks-cursor.is-link .rks-cursor-pointer { opacity: 0; transform: scale(0.4) rotate(-18deg); }
  .rks-cursor.is-link .rks-cursor-frame { opacity: 1; transform: scale(1) rotate(0deg); }

  /* genuine view/open actions — carries a short label on a solid plate */
  .rks-cursor.is-view .rks-cursor-pointer { opacity: 0; transform: scale(0.4) rotate(-18deg); }
  .rks-cursor.is-view .rks-cursor-frame { opacity: 0; transform: scale(1.2) rotate(6deg); }
  .rks-cursor.is-view .rks-cursor-plate { opacity: 1; transform: scale(1) rotate(0deg); }
  .rks-cursor.is-view .rks-cursor-label { opacity: 1; transform: translate(-50%, -50%) scale(1); }

  /* press feedback */
  .rks-cursor.is-down .rks-cursor-frame { transform: scale(0.86) rotate(0deg); }
  .rks-cursor.is-down .rks-cursor-plate { transform: scale(0.9) rotate(0deg); }
  .rks-cursor.is-down .rks-cursor-pointer { transform: scale(0.82) rotate(0deg); }

  /* text fields: stand down entirely, native caret takes over */
  .rks-cursor.is-text { opacity: 0 !important; }
}

/* Never on touch, and never under reduced motion */
@media (hover: none), (pointer: coarse) { .rks-cursor { display: none !important; } }
@media (prefers-reduced-motion: reduce) { .rks-cursor { display: none !important; } }

/* ------------------------------ TOUCH TARGETS ------------------------------ */
/* Below the desktop breakpoint, grow inline links to a comfortable 44px hit
   area. Width-based (not pointer-based) so tablets and small laptops with
   touchscreens get it too. */
@media (max-width: 1020px) {
  .text-link { min-height: 44px; align-items: center; padding-bottom: 0; }
  .footer-panel a, .footer-panel address a { display: inline-flex; align-items: center; min-height: 44px; }
  /* phone + directions links are primary conversion targets */
  .quote-line a { display: inline-flex; align-items: center; min-height: 44px; }
  .mobile-menu-foot a { min-height: 48px; }
  .explorer-item, .sanitary-cat { min-height: 48px; align-items: center; }
  .apps-tab { min-height: 52px; }
}

/* ------------------------------ MOTION / REVEAL ------------------------------ */
html.motion-ok [data-reveal] { opacity: 0; }
html.motion-ok [data-reveal-clip] { clip-path: inset(0 0 100% 0); }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.motion-ok [data-reveal], html.motion-ok [data-reveal-clip] { opacity: 1; clip-path: none; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}

/* ------------------------------ MISC ------------------------------ */
@media (max-width: 480px) {
  :root { --gutter: 1.1rem; }
  .hero-content { padding-top: 7.5rem; }
  .btn { width: 100%; justify-content: center; }
  .hero-ctas .btn, .showroom-actions .btn, .cat-card-actions .btn, .viewer-actions .btn { width: auto; }
}
