@import url("https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,500;1,400&family=Jost:wght@300;400;500&family=JetBrains+Mono:wght@400&display=swap");

/* =========================================================================
   JPT DECOR & DESIGN — "Atelier"
   core.css — the single stylesheet for all four pages.

   CONTENTS
   01  Tokens
   02  Reset & base elements
   03  Typography primitives
   04  Layout: wrap, sections, rules, grids
   05  Global furniture: skip-link, grain, wipe, cursor, preloader
   06  Header, wordmark, nav, fullscreen menu
   07  Buttons & links
   08  Animation start-states (html.js-anim ONLY) + splitter
   09  .frame image-slot system (html.js-frames gating)
   10  Hero
   11  Marquee
   12  Statement / editorial blocks
   13  .scrollfilm  (showpiece)
   14  .hscroll     (portfolio pinned track + ≤900px swipe fallback)
   15  Services, process, counters, testimonials
   16  Page banners & CTA bands
   17  Gallery + filters
   18  FAQ
   19  Forms
   20  Footer
   21  Utilities
   22  Breakpoints (640 / 900 / 1200 / 1440)
   23  prefers-reduced-motion
   24  Print

   RULES HONOURED THROUGHOUT
   - Content is visible by default. Every hidden start-state is scoped to
     `html.js-anim` (§08) or `html.js-frames` (§09). A CSS-only visit is complete.
   - Zero border-radius. No box-shadows. No backdrop-filter.
   - Small text uses --brass-deep, never --brass.
   ========================================================================= */


/* =========================================================================
   01  TOKENS
   ========================================================================= */

:root {
  /* Colour */
  --ink:        #08080A;
  --ink-2:      #101014;
  --paper:      #FAF9F7;
  --bone:       #EFEDE8;
  --smoke:      #6E6E73;
  --line:       #DDD9D2;
  --brass:      #B08D57;   /* large text, rules, icons ONLY (3.0:1) */
  --brass-deep: #7A6238;   /* safe for small text (5.1:1) */
  --danger:     #B42318;

  /* Type families */
  --font-display: 'Playfair Display', Georgia, serif;
  --font-body:    'Jost', -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;

  /* Type scale */
  --d0: clamp(3.2rem, 13vw, 12rem);
  --d1: clamp(2.4rem, 7vw, 6rem);
  --d2: clamp(1.6rem, 3.2vw, 2.6rem);
  --t1: clamp(1.05rem, 1.6vw, 1.35rem);
  --t0: 1rem;
  --tm: 0.7rem;

  /* Space */
  --s1: .5rem;
  --s2: 1rem;
  --s3: 1.5rem;
  --s4: 2.5rem;
  --s5: 4rem;
  --s6: 6.5rem;
  --s7: 10rem;

  /* Measure */
  --wrap: 1360px;
  --gutter: clamp(1.25rem, 5vw, 4.5rem);

  /* Motion */
  --ease: cubic-bezier(.19, 1, .22, 1);
  --dur: 700ms;

  /* Elevation ladder (z only — no shadows anywhere) */
  --z-grain: 900;
  --z-wipe: 950;
  --z-pre: 990;
  --z-cursor: 1000;
  --z-header: 800;
  --z-menu: 850;
}


/* =========================================================================
   02  RESET & BASE
   ========================================================================= */

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

* { margin: 0; padding: 0; }

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--t0);
  font-weight: 300;
  line-height: 1.65;
  overflow-x: hidden;
  min-height: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; }

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

img { height: auto; border: 0; }

svg { fill: none; stroke: currentColor; stroke-width: 1.5; }

ul, ol { list-style: none; }

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

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  border-radius: 0;
}

button { cursor: pointer; }

table { border-collapse: collapse; width: 100%; }

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

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

/* Never remove focus on dark surfaces — swap to the brass tint instead. */
.sec--ink :focus-visible,
.menu :focus-visible,
.site-footer :focus-visible,
.cta-band :focus-visible,
.scrollfilm :focus-visible { outline-color: var(--brass); }

hr { border: 0; }


/* =========================================================================
   03  TYPOGRAPHY PRIMITIVES
   ========================================================================= */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

h1 { font-size: var(--d1); line-height: .95; }
h2 { font-size: var(--d1); line-height: .95; }
h3 { font-size: var(--d2); line-height: 1.1; }
h4 { font-size: 1.15rem; line-height: 1.25; }

em { font-style: italic; }

p { text-wrap: pretty; }

p + p { margin-top: var(--s2); }

.display-0 { font-size: var(--d0); line-height: .88; letter-spacing: -0.02em; }
.display-1 { font-size: var(--d1); line-height: .95; }
.display-2 { font-size: var(--d2); line-height: 1.1; }

.lede {
  font-size: var(--t1);
  line-height: 1.55;
  font-weight: 300;
  color: var(--smoke);
  max-width: 46ch;
}

.body { max-width: 62ch; color: var(--smoke); }

/* Mono meta — the recurring editorial eyebrow. */
.eyebrow,
.meta {
  font-family: var(--font-mono);
  font-size: var(--tm);
  font-weight: 400;
  letter-spacing: .28em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--brass-deep);
}

.meta--smoke { color: var(--smoke); }

.num {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  color: var(--brass-deep);
}

/* Rules: 1px hairline, or 3px currentColor. Nothing else. */
.rule {
  display: block;
  width: 100%;
  height: 1px;
  background: var(--line);
  transform-origin: left center;
}

.rule--heavy {
  height: 3px;
  background: currentColor;
  width: 4rem;
}

.rule--brass { background: var(--brass); }


/* =========================================================================
   04  LAYOUT
   ========================================================================= */

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

.wrap--narrow { max-width: 860px; }

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

.sec--tight { padding-block: var(--s5); }
.sec--tall  { padding-block: var(--s7); }

.sec--paper { background: var(--paper); color: var(--ink); }
.sec--bone  { background: var(--bone);  color: var(--ink); }

.sec--ink {
  background: var(--ink);
  color: var(--paper);
}

.sec--ink .lede,
.sec--ink .body { color: #B9B9BE; }

.sec--ink .rule { background: rgba(250, 249, 247, .18); }
.sec--ink .eyebrow,
.sec--ink .meta,
.sec--ink .num { color: var(--brass); }

.sec__head {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  margin-bottom: var(--s4);
}

.sec__head .rule { margin-block: var(--s1); }

.grid {
  display: grid;
  gap: var(--s4);
  grid-template-columns: 1fr;
}

.grid--2 { grid-template-columns: 1fr; }
.grid--3 { grid-template-columns: 1fr; }
.grid--4 { grid-template-columns: 1fr; }

.cols {
  display: grid;
  gap: var(--s4);
  grid-template-columns: 1fr;
}


/* =========================================================================
   05  GLOBAL FURNITURE
   ========================================================================= */

/* --- Skip link ---------------------------------------------------------- */
.skip-link {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1010;
  transform: translateY(-120%);
  background: var(--ink);
  color: var(--paper);
  padding: var(--s2) var(--s3);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  min-height: 44px;
  display: flex;
  align-items: center;
  transition: transform 200ms var(--ease);
}

.skip-link:focus { transform: translateY(0); }

/* --- Film grain --------------------------------------------------------- */
.grain {
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- Page-transition curtain -------------------------------------------- */
.wipe {
  position: fixed;
  inset: 0;
  z-index: var(--z-wipe);
  background: var(--ink);
  transform: translateY(100%);
  pointer-events: none;
  will-change: transform;
}

/* --- Custom cursor ------------------------------------------------------ */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  mix-blend-mode: difference;
  will-change: transform;
}

.cursor__ring,
.cursor__dot {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  transform: translate(-50%, -50%);
  transition: transform 260ms var(--ease), opacity 200ms linear;
}

.cursor__ring {
  width: 34px;
  height: 34px;
  border: 1px solid var(--paper);
}

.cursor__dot {
  width: 4px;
  height: 4px;
  background: var(--paper);
}

.cursor.is-hover .cursor__ring { transform: translate(-50%, -50%) scale(2.2); }
.cursor.is-hover .cursor__dot  { opacity: 0; }

/* The custom cursor exists only when motion.js says it does. Native cursor
   is never hidden otherwise (§6.7). */
html.js-cursor,
html.js-cursor a,
html.js-cursor button { cursor: none; }

@media (hover: none), (pointer: coarse) {
  .cursor { display: none !important; }
  html.js-cursor,
  html.js-cursor a,
  html.js-cursor button { cursor: auto; }
}

/* --- Preloader (index.html only) ---------------------------------------- */
.preloader {
  position: fixed;
  inset: 0;
  z-index: var(--z-pre);
  background: var(--ink);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  padding: var(--gutter);
}

.preloader.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 400ms var(--ease), visibility 0s linear 400ms;
}

.preloader__mark {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 9vw, 5rem);
  line-height: 1;
  letter-spacing: .06em;
}

.preloader__count {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  color: var(--brass);
  font-variant-numeric: tabular-nums;
}

.preloader__bar {
  width: min(320px, 70vw);
  height: 1px;
  background: rgba(250, 249, 247, .22);
  position: relative;
  overflow: hidden;
}

.preloader__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brass);
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
  transition: transform 200ms linear;
}

/* No-JS: the preloader must never trap the page. */
html:not(.js-anim) .preloader { display: none; }


/* =========================================================================
   06  HEADER, WORDMARK, NAV, MENU
   ========================================================================= */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: var(--z-header);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 400ms var(--ease), border-color 400ms var(--ease),
              color 400ms var(--ease);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  min-height: 72px;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: var(--s1);
}

.site-header--over-dark { color: var(--paper); }

.site-header.is-solid {
  background: var(--paper);
  color: var(--ink);
  border-bottom-color: var(--line);
}

/* --- Wordmark ----------------------------------------------------------- */
.wordmark {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 44px;
  color: inherit;
}

.wordmark__mark {
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1;
  letter-spacing: .06em;
}

.wordmark__sub {
  font-family: var(--font-mono);
  font-size: .5rem;
  letter-spacing: .4em;
  text-transform: uppercase;
  line-height: 1;
  opacity: .78;
}

/* --- Desktop nav (shown ≥900px) ----------------------------------------- */
.nav { display: none; }

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--s3);
}

.nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s1);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  position: relative;
  color: inherit;
}

.nav__link::after {
  content: "";
  position: absolute;
  left: var(--s1);
  right: var(--s1);
  bottom: 12px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease);
}

.nav__link:hover::after,
.nav__link:focus-visible::after { transform: scaleX(1); }

.nav__link[aria-current="page"] { color: var(--brass-deep); }
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

.site-header--over-dark:not(.is-solid) .nav__link[aria-current="page"] { color: var(--brass); }

/* --- Nav toggle (≤900px) ------------------------------------------------- */
.nav-toggle {
  width: 48px;
  height: 48px;
  border: 1px solid currentColor;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;
  color: inherit;
  background: transparent;
}

.nav-toggle span {
  display: block;
  width: 18px;
  height: 1px;
  background: currentColor;
  transition: transform 300ms var(--ease), opacity 200ms linear;
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(3px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-3px) rotate(-45deg); }

/* --- Fullscreen menu ----------------------------------------------------- */
.menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  background: var(--ink);
  color: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: calc(72px + var(--s4)) var(--gutter) var(--s5);
  overflow-y: auto;
}

.menu[hidden] { display: none; }

.menu__list {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  border-top: 1px solid rgba(250, 249, 247, .14);
}

.menu__item { border-bottom: 1px solid rgba(250, 249, 247, .14); }

.menu__link {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  min-height: 64px;
  padding-block: var(--s2);
  font-family: var(--font-display);
  font-size: var(--d2);
  line-height: 1.1;
  color: inherit;
  transition: color 300ms var(--ease), transform 500ms var(--ease);
}

.menu__link:hover,
.menu__link:focus-visible {
  color: var(--brass);
  transform: translateX(8px);
}

.menu__link[aria-current="page"] { color: var(--brass); }

.menu__index {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  color: var(--brass);
}

.menu__foot {
  margin-top: var(--s5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
}

.menu__foot a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}


/* =========================================================================
   07  BUTTONS & LINKS
   ========================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s1);
  min-height: 52px;
  min-width: 44px;
  padding: 0 var(--s3);
  border: 1px solid currentColor;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  position: relative;
  overflow: hidden;
  color: var(--ink);
  background: transparent;
  transition: color 420ms var(--ease), border-color 420ms var(--ease);
}

/* Fill sweep — transform only, no layout properties. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: bottom center;
  transition: transform 420ms var(--ease);
  z-index: 0;
}

.btn > * { position: relative; z-index: 1; }

.btn:hover,
.btn:focus-visible { color: var(--paper); }
.btn:hover::before,
.btn:focus-visible::before { transform: scaleY(1); }

.btn--solid {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.btn--solid::before { background: var(--paper); }
.btn--solid:hover,
.btn--solid:focus-visible { color: var(--ink); }

.btn--light {
  color: var(--paper);
  border-color: var(--paper);
}

.btn--light::before { background: var(--paper); }
.btn--light:hover,
.btn--light:focus-visible { color: var(--ink); }

.btn--ghost { border-color: var(--line); }

.btn svg { width: 16px; height: 16px; }

/* Inline editorial link */
.link {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  border-bottom: 1px solid currentColor;
  transition: color 300ms var(--ease), gap 300ms var(--ease);
}

.link:hover,
.link:focus-visible { color: var(--ink); gap: var(--s2); }

.sec--ink .link,
.cta-band .link { color: var(--brass); }

.sec--ink .link:hover,
.cta-band .link:hover { color: var(--paper); }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: center;
}


/* =========================================================================
   08  ANIMATION START-STATES — html.js-anim ONLY
   Nothing below hides content unless motion.js has declared itself.
   ========================================================================= */

html.js-anim [data-anim="fade-up"] {
  opacity: 0;
  transform: translate3d(0, 32px, 0);
  will-change: transform, opacity;
}

html.js-anim [data-anim="clip"] {
  clip-path: inset(0 0 100% 0);
  will-change: clip-path;
}

html.js-anim [data-anim="line"] {
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}

html.js-anim [data-anim="split"] .char__i {
  transform: translate3d(0, 110%, 0);
  will-change: transform;
}

/* `scale` scrubs its inner img; it must never hide the image. */
html.js-anim [data-anim="scale"] { overflow: hidden; }
html.js-anim [data-anim="scale"] img,
html.js-anim [data-anim="scale"] .frame__img { transform: scale(1.08); }

/* Once motion.js reveals, it sets .is-in — kept as a CSS-side safety net so a
   half-finished tween still ends visible. */
html.js-anim [data-anim].is-in {
  opacity: 1;
  transform: none;
  clip-path: inset(0);
}

html.js-anim [data-anim="line"].is-in { transform: scaleX(1); }
html.js-anim [data-anim="split"].is-in .char__i { transform: none; }

[data-parallax] { will-change: transform; }

[data-magnetic] { transition: transform 500ms var(--ease); }

/* --- §6.3 character splitter -------------------------------------------- */
/* Words wrap; characters inside a word never do. The splitter emits a real
   text space between .word elements, so lines break at spaces only. */
.word {
  display: inline-block;
  white-space: nowrap;
}

.char {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}

.char__i {
  display: inline-block;
  will-change: transform;
}

/* The mask is only needed WHILE the characters slide up. Leaving it on after
   the reveal clips descenders and commas (g, y, p, ",") off the baseline. */
html.js-anim [data-anim="split"].is-in .char { overflow: visible; }

/* --- Counters ------------------------------------------------------------ */
.counters {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.counter {
  border-top: 1px solid rgba(250, 249, 247, .18);
  padding-top: var(--s2);
}

.counter__value {
  font-family: var(--font-display);
  font-size: clamp(3rem, 9vw, 5.5rem);
  line-height: .9;
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: .1em;
}

.counter__suffix { font-size: .4em; color: var(--brass); }

.counter__label {
  margin-top: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}


/* =========================================================================
   09  .frame — image-slot system
   Placeholder shows by default when a slot is empty or errored; images fade
   in only under html.js-frames so a CSS-only visit shows them immediately.
   ========================================================================= */

.frame {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--bone);
  width: 100%;
}

.sec--ink .frame,
.scrollfilm .frame,
.cta-band .frame { background: var(--ink-2); }

.frame img,
.frame__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.04);
  transition: opacity 600ms var(--ease), filter 700ms var(--ease),
              transform 900ms var(--ease);
  position: relative;
  z-index: 1;
}

.frame:hover img,
.frame:hover .frame__img { filter: grayscale(.15) contrast(1.02); }

/* Aspect helpers so a missing image never collapses the layout. */
.frame--16x9 { aspect-ratio: 16 / 9; }
.frame--4x5  { aspect-ratio: 4 / 5; }
.frame--1x1  { aspect-ratio: 1 / 1; }
.frame--3x2  { aspect-ratio: 3 / 2; }

/* Hatched placeholder — always painted underneath; the image covers it. */
.frame::before {
  content: attr(data-label);
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: flex-end;
  padding: var(--s3);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  background-color: var(--bone);
  background-image: repeating-linear-gradient(
    45deg,
    var(--line) 0,
    var(--line) 1px,
    transparent 1px,
    transparent 9px
  );
}

.sec--ink .frame::before,
.scrollfilm .frame::before,
.cta-band .frame::before {
  color: var(--brass);
  background-color: var(--ink-2);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(250, 249, 247, .10) 0,
    rgba(250, 249, 247, .10) 1px,
    transparent 1px,
    transparent 9px
  );
}

/* site.js gating (§7): opacity 0 → 1 on load; .is-empty exposes placeholder. */
html.js-frames .frame img { opacity: 0; }
html.js-frames .frame img.is-loaded { opacity: 1; }
html.js-frames .frame.is-empty img { display: none; }

.frame__caption {
  margin-top: var(--s2);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s2);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

.frame__caption span + span::before {
  content: "·";
  margin-right: var(--s2);
  color: var(--line);
}


/* =========================================================================
   10  HERO
   ========================================================================= */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  color: var(--paper);
  background: var(--ink);
  overflow: hidden;
  padding-block: calc(72px + var(--s5)) var(--s5);
}

/* NOTE: a <div> layer, not an <img> — a missing file renders clean dark. */
.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--ink);
  background-image: var(--hero-img);
  background-size: cover;
  background-position: center;
  filter: grayscale(1) contrast(1.05);
  will-change: transform;
}

.hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(8, 8, 10, .72) 0%,
    rgba(8, 8, 10, .40) 38%,
    rgba(8, 8, 10, .82) 100%
  );
}

.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.hero__eyebrow { color: var(--brass); }

.hero__title {
  font-size: var(--d0);
  line-height: .88;
  letter-spacing: -0.02em;
  max-width: 16ch;
}

.hero__title em {
  font-style: italic;
  color: var(--brass);
}

.hero__lede {
  color: #C6C6CB;
  max-width: 44ch;
}

.hero__actions { margin-top: var(--s2); }

.hero__scroll {
  margin-top: var(--s4);
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
  min-height: 44px;
}

.hero__scroll::after {
  content: "";
  width: 56px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
  animation: cue 2.4s var(--ease) infinite;
}

@keyframes cue {
  0%, 100% { transform: scaleX(.35); opacity: .5; }
  50%      { transform: scaleX(1);   opacity: 1; }
}


/* =========================================================================
   11  MARQUEE
   ========================================================================= */

.marquee {
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
  padding-block: var(--s3);
  border-block: 1px solid rgba(250, 249, 247, .12);
  position: relative;
}

.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee 34s linear infinite;
  will-change: transform;
}

.marquee:hover .marquee__track { animation-play-state: paused; }

.marquee__group {
  display: flex;
  flex: 0 0 auto;
  gap: var(--s4);
  padding-right: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--bone);
}

.marquee__group span { color: inherit; }

@keyframes marquee {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}


/* =========================================================================
   12  STATEMENT / EDITORIAL BLOCKS
   ========================================================================= */

.statement__title { max-width: 18ch; }

.statement__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
  margin-top: var(--s4);
}

.statement__cols p { color: var(--smoke); max-width: 56ch; }

.statement .rule { margin-top: var(--s5); }

/* Numbered editorial blocks (services on index, elements on atelier). */
.block {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s2);
  padding-block: var(--s4);
  border-top: 1px solid var(--line);
}

.sec--ink .block { border-top-color: rgba(250, 249, 247, .18); }

.block__num {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  color: var(--brass-deep);
}

.sec--ink .block__num { color: var(--brass); }

.block__title { font-size: var(--d2); }

.block__body { color: var(--smoke); max-width: 52ch; }

.sec--ink .block__body { color: #B9B9BE; }

/* Atelier service depth blocks */
.service {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
  padding-block: var(--s5);
  border-top: 1px solid var(--line);
}

.service__body { display: flex; flex-direction: column; gap: var(--s2); }

.includes {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  margin-top: var(--s2);
}

.includes li {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  padding-block: 6px;
  color: var(--smoke);
}

.includes svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  margin-top: .35em;
  color: var(--brass-deep);
}

/* Small card grid (Individual elements) */
.card {
  border-top: 1px solid var(--line);
  padding-top: var(--s2);
  display: flex;
  flex-direction: column;
  gap: var(--s1);
}

.card__title { font-family: var(--font-display); font-size: 1.25rem; line-height: 1.2; }
.card__body { color: var(--smoke); font-size: .95rem; }

/* Process steps */
.steps {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
  counter-reset: step;
}

.step { border-top: 3px solid currentColor; padding-top: var(--s2); }
.step__num { color: var(--brass-deep); }
.sec--ink .step__num { color: var(--brass); }
.step__title { font-family: var(--font-display); font-size: 1.4rem; margin-top: var(--s1); }
.step__body { color: var(--smoke); margin-top: var(--s1); }

/* Testimonials */
.quotes {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.quote {
  border-top: 1px solid var(--line);
  padding-top: var(--s3);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.quote blockquote {
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1.35;
  font-style: italic;
}

.quote figcaption {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

/* Pricing method list (atelier, ink) */
.method {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
}

.method__item {
  border-top: 1px solid rgba(250, 249, 247, .18);
  padding-top: var(--s2);
}

.method__item h3 { font-size: 1.25rem; }
.method__item p { color: #B9B9BE; margin-top: var(--s1); }

/* Venue groups (portfolio) */
.venues {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.venues__group { border-top: 1px solid var(--line); padding-top: var(--s2); }
.venues__group h3 { font-size: 1.15rem; font-family: var(--font-display); }

.venues__list { margin-top: var(--s2); display: flex; flex-direction: column; }

.venues__list li {
  padding-block: 8px;
  color: var(--smoke);
  border-bottom: 1px solid var(--line);
}


/* =========================================================================
   13  .scrollfilm — THE SHOWPIECE
   Default (no JS / reduced motion): not pinned, first frame visible, caption
   lines stacked as a readable list. Never blank.
   ========================================================================= */

.scrollfilm {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  overflow: hidden;
}

.scrollfilm__stage {
  position: relative;
  width: 100%;
  min-height: 70svh;
  overflow: hidden;
  background: var(--ink);
}

.scrollfilm__frame {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-color: var(--ink);
  background-image: var(--film-img);
  filter: grayscale(1) contrast(1.06);
  will-change: transform, opacity;
}

.scrollfilm__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.06);
}

/* CSS-only default: only the first frame paints, stacked in DOM order. */
.scrollfilm__frame + .scrollfilm__frame { opacity: 0; }

/* Under JS, motion.js owns opacity for every layer. */
html.js-anim .scrollfilm__frame + .scrollfilm__frame { opacity: 0; }

.scrollfilm__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.06);
}

.scrollfilm__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(8, 8, 10, .55) 0%,
    rgba(8, 8, 10, .25) 45%,
    rgba(8, 8, 10, .85) 100%
  );
  pointer-events: none;
}

.scrollfilm__caption {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: var(--s5) var(--gutter) var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

/* CSS-only: caption lines read as a plain stacked list. */
.scrollfilm__line {
  font-family: var(--font-display);
  font-size: var(--d2);
  line-height: 1.1;
  max-width: 22ch;
  display: block;
  position: relative;
  padding-left: var(--s3);
}

.scrollfilm__line::before {
  content: "";
  position: absolute;
  left: 0;
  top: .65em;
  width: var(--s2);
  height: 1px;
  background: var(--brass);
}

/* Under JS the lines overlay one another and swap at thresholds. */
html.js-anim .scrollfilm__caption { display: grid; }
html.js-anim .scrollfilm__line {
  grid-area: 1 / 1;
  opacity: 0;
  transition: opacity 500ms var(--ease), transform 600ms var(--ease);
  transform: translate3d(0, 12px, 0);
}
html.js-anim .scrollfilm__line.is-active {
  opacity: 1;
  transform: none;
}

.scrollfilm__progress {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  height: 1px;
  background: rgba(250, 249, 247, .2);
}

.scrollfilm__progress::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brass);
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
}

/* CSS-only: show the rail full so it does not read as broken. */
html:not(.js-anim) .scrollfilm__progress::after { transform: scaleX(1); }

.scrollfilm__meta {
  position: relative;
  z-index: 2;
  max-width: var(--wrap);
  margin-inline: auto;
  padding: var(--s2) var(--gutter) var(--s5);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}


/* =========================================================================
   14  .hscroll — portfolio pinned horizontal track
   ≤900px: no pin. Native overflow-x swipe track with scroll-snap.
   ========================================================================= */

.hscroll {
  position: relative;
  overflow: hidden;
  padding-block: var(--s5);
  background: var(--paper);
}

.hscroll__track {
  display: flex;
  gap: var(--s3);
  padding-inline: var(--gutter);
  will-change: transform;

  /* Mobile-first: this IS the fallback — a real swipe track. */
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scroll-padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--brass) var(--line);
}

.hscroll__track::-webkit-scrollbar { height: 3px; }
.hscroll__track::-webkit-scrollbar-track { background: var(--line); }
.hscroll__track::-webkit-scrollbar-thumb { background: var(--brass); }

.hscroll__panel {
  flex: 0 0 auto;
  width: min(78vw, 420px);
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.hscroll__panel .frame { aspect-ratio: 4 / 5; }

.hscroll__hint {
  margin-top: var(--s3);
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  min-height: 44px;
}

.hscroll__hint::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}


/* =========================================================================
   15  COUNTERS SECTION / STATS BANDS  (see §08 for .counter internals)
   ========================================================================= */

.counters-sec { background: var(--ink); color: var(--paper); }


/* =========================================================================
   16  PAGE BANNERS & CTA BANDS
   ========================================================================= */

.banner {
  background: var(--ink);
  color: var(--paper);
  padding-block: calc(72px + var(--s5)) var(--s5);
  position: relative;
  overflow: hidden;
}

.banner__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.banner__title { font-size: var(--d1); line-height: .95; max-width: 18ch; }
.banner__title em { font-style: italic; color: var(--brass); }
.banner .lede { color: #C6C6CB; }
.banner .eyebrow { color: var(--brass); }

.cta-band {
  background: var(--ink);
  color: var(--paper);
  padding-block: var(--s6);
  position: relative;
  overflow: hidden;
}

.cta-band__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  align-items: flex-start;
}

.cta-band__title { font-size: var(--d1); line-height: .95; max-width: 14ch; }
.cta-band__title em { font-style: italic; color: var(--brass); }
.cta-band p { color: #B9B9BE; max-width: 44ch; }


/* =========================================================================
   17  FILTERS & GALLERY
   ========================================================================= */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1);
  margin-bottom: var(--s4);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line);
}

.filters__btn {
  min-height: 44px;
  padding: 0 var(--s2);
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  background: transparent;
  transition: color 300ms var(--ease), background 300ms var(--ease),
              border-color 300ms var(--ease);
}

.filters__btn:hover { border-color: var(--ink); color: var(--ink); }

.filters__btn[aria-pressed="true"] {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.gallery {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4) var(--s3);
}

.gallery__item {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.gallery__item[hidden] { display: none; }

.gallery__item .frame { aspect-ratio: 4 / 5; }

.gallery__title { font-family: var(--font-display); font-size: 1.2rem; line-height: 1.2; }

.gallery__meta {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

.gallery__empty {
  padding: var(--s5) 0;
  border-top: 1px solid var(--line);
  color: var(--smoke);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
}

.gallery__empty[hidden] { display: none; }


/* =========================================================================
   18  FAQ
   ========================================================================= */

.faq { border-top: 1px solid var(--line); }

.faq__item { border-bottom: 1px solid var(--line); }

.faq__q {
  width: 100%;
  min-height: 60px;
  padding: var(--s2) 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  text-align: left;
  font-family: var(--font-display);
  font-size: 1.2rem;
  line-height: 1.25;
  color: var(--ink);
  transition: color 300ms var(--ease);
}

.faq__q:hover { color: var(--brass-deep); }

.faq__icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  position: relative;
  color: var(--brass-deep);
}

.faq__icon::before,
.faq__icon::after {
  content: "";
  position: absolute;
  background: currentColor;
  transition: transform 400ms var(--ease), opacity 300ms linear;
}

.faq__icon::before { left: 0; right: 0; top: 50%; height: 1px; }
.faq__icon::after  { top: 0; bottom: 0; left: 50%; width: 1px; }

.faq__q[aria-expanded="true"] .faq__icon::after { transform: scaleY(0); }

/* Answer: closed by default via max-height, but text stays in the DOM and is
   fully visible when JS is absent (site.js sets max-height inline). */
.faq__a {
  overflow: hidden;
  transition: max-height 450ms var(--ease);
}

html.js-anim .faq__a,
html.js-frames .faq__a { max-height: 0; }

.faq__a-inner {
  padding-bottom: var(--s3);
  color: var(--smoke);
  max-width: 62ch;
}


/* =========================================================================
   19  FORMS
   ========================================================================= */

.form {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.form__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  min-width: 0;
}

.field--full { grid-column: 1 / -1; }

.label {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  display: flex;
  align-items: center;
  gap: .4em;
}

.req { color: var(--danger); }

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 52px;
  font-size: 1rem;           /* prevents iOS zoom */
  font-family: var(--font-body);
  font-weight: 300;
  line-height: 1.5;
  padding: var(--s2);
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--ink);
  transition: border-color 300ms var(--ease);
  appearance: none;
  -webkit-appearance: none;
}

.field textarea {
  min-height: 168px;
  resize: vertical;
}

.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--brass-deep) 50%),
                    linear-gradient(135deg, var(--brass-deep) 50%, transparent 50%);
  background-position: calc(100% - 20px) calc(50% + 2px), calc(100% - 14px) calc(50% + 2px);
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: var(--s5);
}

.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--smoke); }

.field input:focus,
.field select:focus,
.field textarea:focus { border-color: var(--ink); }

.field input::placeholder,
.field textarea::placeholder { color: var(--smoke); opacity: 1; }

.hint { font-size: .85rem; color: var(--smoke); }

/* Errors: hidden until the field is flagged. */
.error {
  display: none;
  align-items: flex-start;
  gap: var(--s1);
  color: var(--danger);
  font-size: .85rem;
  line-height: 1.4;
}

.error svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  margin-top: .2em;
}

.field.has-error .error { display: flex; }

.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--danger); }

.field.has-error .label { color: var(--danger); }

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
}

.form__status {
  min-height: 44px;
  display: flex;
  align-items: center;
  padding: var(--s2);
  border-left: 3px solid var(--line);
  font-size: .95rem;
  color: var(--smoke);
  background: var(--bone);
}

.form__status:empty { display: none; }

.form__status.is-ok { border-left-color: var(--brass-deep); color: var(--ink); }
.form__status.is-error { border-left-color: var(--danger); color: var(--danger); }

/* Contact aside card */
.contact-card {
  border-top: 3px solid var(--ink);
  padding-top: var(--s3);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.contact-card dl { display: flex; flex-direction: column; gap: var(--s2); }
.contact-card dt {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}
.contact-card dd { color: var(--ink); }

.contact-card a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-bottom: 1px solid var(--line);
  transition: border-color 300ms var(--ease);
}

.contact-card a:hover { border-color: var(--ink); }


/* =========================================================================
   20  FOOTER
   ========================================================================= */

.site-footer {
  background: var(--ink);
  color: var(--paper);
  padding-block: var(--s5) var(--s4);
}

.site-footer__inner {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.site-footer h2,
.site-footer h3 {
  font-family: var(--font-mono);
  font-size: var(--tm);
  font-weight: 400;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}

.site-footer__col { display: flex; flex-direction: column; gap: var(--s2); }

.site-footer__list { display: flex; flex-direction: column; }

/* ≥44px targets on every footer link — the v1 regression. */
.site-footer__list a,
.site-footer a.footer-link {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--bone);
  transition: color 300ms var(--ease);
}

.site-footer__list a:hover,
.site-footer a.footer-link:hover { color: var(--brass); }

.site-footer .wordmark { color: var(--paper); }

.site-footer__note {
  color: #9A9AA0;
  font-size: .9rem;
  max-width: 40ch;
}

.site-footer__base {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  margin-top: var(--s5);
  padding-top: var(--s2);
  border-top: 1px solid rgba(250, 249, 247, .18);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s3);
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}


/* =========================================================================
   21  UTILITIES
   ========================================================================= */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.stack { display: flex; flex-direction: column; gap: var(--s2); }
.stack--lg { gap: var(--s4); }

.mt-1 { margin-top: var(--s1); }
.mt-2 { margin-top: var(--s2); }
.mt-3 { margin-top: var(--s3); }
.mt-4 { margin-top: var(--s4); }
.mt-5 { margin-top: var(--s5); }

.text-brass { color: var(--brass-deep); }
.sec--ink .text-brass { color: var(--brass); }

[hidden] { display: none !important; }


/* =========================================================================
   22  BREAKPOINTS — mobile-first: 375 / 640 / 900 / 1200 / 1440
   ========================================================================= */

/* --- 375px: smallest supported. Guard against overflow. ----------------- */
@media (max-width: 374.98px) {
  :root { --gutter: 1.1rem; }
  .hscroll__panel { width: 84vw; }
}

/* --- 640px --------------------------------------------------------------- */
@media (min-width: 640px) {
  .grid--2,
  .grid--3,
  .grid--4 { grid-template-columns: repeat(2, 1fr); }

  .counters { grid-template-columns: repeat(2, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .gallery { grid-template-columns: repeat(2, 1fr); }
  .statement__cols { grid-template-columns: repeat(2, 1fr); gap: var(--s4); }
  .form__grid { grid-template-columns: repeat(2, 1fr); }
  .site-footer__inner { grid-template-columns: repeat(2, 1fr); }
  .venues { grid-template-columns: repeat(2, 1fr); }
  .method { grid-template-columns: repeat(2, 1fr); }
  .quotes { grid-template-columns: repeat(2, 1fr); }

  .block { grid-template-columns: 4rem 1fr; column-gap: var(--s3); }
  .block__num { grid-row: span 2; }

  .hscroll__panel { width: min(56vw, 460px); }
  .scrollfilm__stage { min-height: 78svh; }
}

/* --- 900px: desktop nav, real pinning, wider editorial grids ------------- */
@media (min-width: 900px) {
  .nav { display: block; }
  .nav-toggle { display: none; }
  .menu { display: none !important; }

  .site-header__inner { min-height: 84px; }

  .grid--3 { grid-template-columns: repeat(3, 1fr); }
  .grid--4 { grid-template-columns: repeat(4, 1fr); }
  .counters { grid-template-columns: repeat(4, 1fr); }
  .steps { grid-template-columns: repeat(4, 1fr); }
  .gallery { grid-template-columns: repeat(3, 1fr); }
  .quotes { grid-template-columns: repeat(3, 1fr); }
  .venues { grid-template-columns: repeat(3, 1fr); }
  .method { grid-template-columns: repeat(3, 1fr); }

  .service { grid-template-columns: 5fr 7fr; gap: var(--s5); align-items: start; }
  .service--flip .frame { order: 2; }

  .cols--contact { grid-template-columns: 7fr 4fr; gap: var(--s5); }
  .cols--split   { grid-template-columns: 1fr 1fr; gap: var(--s5); }

  .sec__head--split {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--s5);
  }

  .hero { align-items: center; }
  .hero__inner { gap: var(--s4); }

  .scrollfilm__stage { min-height: 100svh; }

  /* Pinned mode owns the layout only when GSAP is live. */
  html.js-anim .scrollfilm__caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--s5);
  }

  html.js-anim .scrollfilm__progress {
    position: absolute;
    left: 0;
    right: 0;
    bottom: var(--s4);
  }

  /* Pinned horizontal track: JS drives translateX, so drop native scrolling. */
  html.js-anim .hscroll__track {
    overflow: visible;
    scroll-snap-type: none;
  }

  html.js-anim .hscroll__hint { display: none; }

  .hscroll__panel { width: min(38vw, 520px); }

  .site-footer__inner { grid-template-columns: 2fr 1fr 1fr 1fr; }
}

/* --- 1200px -------------------------------------------------------------- */
@media (min-width: 1200px) {
  .sec { padding-block: var(--s7); }
  .hscroll__panel { width: min(32vw, 560px); }
  .statement__cols { grid-template-columns: repeat(2, minmax(0, 34ch)); gap: var(--s5); }
  .cols--contact { grid-template-columns: 7fr 3fr; }
}

/* --- 1440px -------------------------------------------------------------- */
@media (min-width: 1440px) {
  :root { --gutter: 4.5rem; }
  .hero__title { max-width: 14ch; }
  .hscroll__panel { width: 520px; }
}

/* Very short viewports: don't let 100svh heroes clip their content. */
@media (max-height: 560px) {
  .hero { min-height: auto; padding-block: calc(72px + var(--s4)) var(--s4); }
  .scrollfilm__stage { min-height: 460px; }
}


/* =========================================================================
   23  REDUCED MOTION
   Everything static, everything visible. This block must undo every
   start-state above, including ones scoped to html.js-anim.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  /* All declarative animation targets: fully revealed and static. */
  [data-anim],
  html.js-anim [data-anim],
  html.js-anim [data-anim="fade-up"],
  html.js-anim [data-anim="clip"],
  html.js-anim [data-anim="line"] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    will-change: auto !important;
  }

  html.js-anim [data-anim="line"] { transform: scaleX(1) !important; }

  [data-anim="split"] .char,
  html.js-anim [data-anim="split"] .char { overflow: visible; }

  [data-anim="split"] .char__i,
  html.js-anim [data-anim="split"] .char__i { transform: none !important; }

  html.js-anim [data-anim="scale"] img,
  html.js-anim [data-anim="scale"] .frame__img { transform: none !important; }

  [data-parallax],
  [data-magnetic] { transform: none !important; will-change: auto !important; }

  /* Scrollfilm: unpinned, first frame only, captions stacked and readable. */
  .scrollfilm__frame,
  html.js-anim .scrollfilm__frame {
    opacity: 1 !important;
    transform: none !important;
    position: relative;
    inset: auto;
    aspect-ratio: 16 / 9;
  }

  .scrollfilm__frame + .scrollfilm__frame,
  html.js-anim .scrollfilm__frame + .scrollfilm__frame { display: none; }

  .scrollfilm__stage { min-height: 0; }

  html.js-anim .scrollfilm__caption,
  .scrollfilm__caption {
    display: flex !important;
    position: static !important;
    flex-direction: column;
  }

  html.js-anim .scrollfilm__line,
  .scrollfilm__line {
    opacity: 1 !important;
    transform: none !important;
    grid-area: auto;
  }

  html.js-anim .scrollfilm__progress { position: static !important; }
  .scrollfilm__progress::after { transform: scaleX(1) !important; }

  /* Horizontal track: native swipe, never pinned. */
  html.js-anim .hscroll__track,
  .hscroll__track {
    transform: none !important;
    overflow-x: auto !important;
    scroll-snap-type: x mandatory !important;
  }

  html.js-anim .hscroll__hint { display: flex !important; }

  /* Marquee holds still but stays legible. */
  .marquee__track {
    animation: none !important;
    transform: none !important;
  }

  .hero__scroll::after { animation: none !important; transform: scaleX(1) !important; }

  /* Frames: no fade gating, no custom cursor, no curtain. */
  html.js-frames .frame img { opacity: 1 !important; }
  .cursor { display: none !important; }
  html.js-cursor,
  html.js-cursor a,
  html.js-cursor button { cursor: auto !important; }
  .wipe { display: none !important; }
  .preloader { display: none !important; }
}


/* =========================================================================
   24  PRINT
   ========================================================================= */

@media print {
  @page { margin: 18mm; }

  html, body {
    background: #fff !important;
    color: #000 !important;
    font-size: 11pt;
  }

  .grain,
  .wipe,
  .cursor,
  .preloader,
  .site-header,
  .menu,
  .nav-toggle,
  .marquee,
  .hero__scroll,
  .filters,
  .form__actions,
  .hscroll__hint,
  .scrollfilm__progress,
  .skip-link { display: none !important; }

  main { padding-top: 0 !important; }

  .sec,
  .sec--ink,
  .banner,
  .cta-band,
  .scrollfilm,
  .site-footer,
  .counters-sec {
    background: #fff !important;
    color: #000 !important;
    padding-block: 12pt !important;
  }

  .sec--ink .lede,
  .sec--ink .body,
  .lede,
  .body,
  .banner .lede,
  .cta-band p { color: #333 !important; }

  .eyebrow,
  .meta,
  .num,
  .label,
  .gallery__meta,
  .frame__caption { color: #000 !important; }

  a { color: #000 !important; text-decoration: underline; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 8pt; }
  a[href^="#"]::after { content: ""; }

  [data-anim],
  .char__i,
  .scrollfilm__frame,
  .scrollfilm__line {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    position: static !important;
  }

  .scrollfilm__frame + .scrollfilm__frame { display: none; }

  .frame { border: 1px solid #999; }
  .frame img { filter: none !important; opacity: 1 !important; }

  .hscroll__track { overflow: visible !important; flex-wrap: wrap; transform: none !important; }
  .hscroll__panel { width: 45% !important; }

  .faq__a { max-height: none !important; overflow: visible !important; }
  .gallery__item[hidden] { display: flex !important; }

  h1, h2, h3 { break-after: avoid; }
  .block, .service, .quote, .faq__item, .gallery__item { break-inside: avoid; }
}


/* =========================================================================
   ==========================================================================
   25  HTML INTEGRATION LAYER
   ==========================================================================

   The HTML, CSS and JS were authored in parallel and diverged: the markup
   settled on a different (and now authoritative) class vocabulary from the
   one sections 01–24 above were written against, and motion.js/site.js set
   state hooks that had no CSS counterpart.

   This section adapts the CSS to the shipped markup. It is additive except
   where a rule above is factually wrong about the JS contract — those are
   corrected inline and flagged with a FIX comment.

   Rules obeyed throughout:
     • Nothing here hides content except under html.js-anim / html.js-frames.
     • Zero border-radius, zero box-shadow, zero backdrop-filter.
     • Small text uses --brass-deep on paper, --brass only on ink.
     • Every interactive target is ≥44px tall.
     • Reduced-motion neutralisers for everything new live in §25.16.
   ========================================================================= */


/* -------------------------------------------------------------------------
   25.1  CORRECTIONS to rules above that contradict the JS
   ------------------------------------------------------------------------- */

/* FIX: motion.js sets `has-cursor` on <html> (motion.js §6.7), never
   `js-cursor`. The native cursor was being hidden by a class that is never
   applied — and would have stayed hidden if it ever were. */
html.has-cursor,
html.has-cursor a,
html.has-cursor button,
html.has-cursor [data-magnetic] { cursor: none; }

@media (hover: none), (pointer: coarse) {
  html.has-cursor,
  html.has-cursor a,
  html.has-cursor button { cursor: auto; }
}

/* The cursor only paints once motion.js has seen a pointer. */
.cursor { opacity: 0; transition: opacity 200ms linear; }
.cursor.is-visible { opacity: 1; }
.cursor[hidden] { display: none !important; }

/* FIX: the `.is-in` safety net in §08 could never actually fire, because the
   inline styles GSAP writes always beat a plain stylesheet declaration. In
   practice a ScrollTrigger.refresh() (fired on font swap / late image load,
   spec §6.1.6) can re-apply a completed tween's *from* state and strand a
   headline off-screen — observed on the hero h1. `.is-in` is only ever added
   in a tween's onComplete, so forcing the end state once it is present is
   always correct, and it is the difference between a readable page and an
   invisible one.
   [data-magnetic] is excluded: motion.js keeps writing transforms there for
   the cursor-drift long after the reveal has completed. */
html.js-anim [data-anim].is-in { opacity: 1 !important; }

html.js-anim [data-anim="fade-up"].is-in:not([data-magnetic]) {
  transform: none !important;
}

html.js-anim [data-anim="clip"].is-in { clip-path: inset(0) !important; }
html.js-anim [data-anim="line"].is-in { transform: scaleX(1) !important; }
html.js-anim [data-anim="split"].is-in .char__i { transform: none !important; }


/* FIX: motion.js toggles `is-on` on caption lines, not `is-active`. */
html.js-anim .scrollfilm__line.is-on { opacity: 1; transform: none; }

/* FIX: site.js never removes the `hidden` attribute from .faq__a — it drives
   the panel purely with inline max-height. Left as-is the accordion could
   never open, so .faq__a must ignore [hidden] and rely on max-height.
   !important is required here because core.css already carries a global
   `[hidden] { display: none !important }`. */
.faq__a[hidden] { display: block !important; }

/* FIX: .counters and .venues are full-bleed <section>s in the markup; the
   grid lives on .counters__grid / .venues__grid. */
.counters,
.venues { display: block; grid-template-columns: none; gap: 0; }

/* FIX: the hero scrim is its own element in the markup — don't double-darken
   with the .hero__media::after gradient as well. */
.hero__media::after { content: none; }

/* FIX: .hero__scroll's animated ::after is replaced by a real
   .hero__scroll-line element in the markup. */
.hero__scroll::after { content: none; }

/* FIX: the nav toggle ships two bars, not three. */
.nav-toggle[aria-expanded="true"] > :nth-child(1) {
  transform: translateY(3px) rotate(45deg);
}
.nav-toggle[aria-expanded="true"] > :nth-child(2) {
  transform: translateY(-3px) rotate(-45deg);
  opacity: 1;
}

/* FIX: the pinned horizontal track must only lose native scrolling when
   motion.js has actually pinned it (.is-pinned). If GSAP fails to load,
   js-anim is still present but the track stays a swipe track — leaving it
   overflow:visible would blow out the page horizontally. */
.hscroll:not(.is-pinned) .hscroll__track {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  transform: none;
}


/* -------------------------------------------------------------------------
   25.2  TYPOGRAPHY UTILITIES used by the markup (.d1 .d2 .t1 .t0 .mono .icon)
   ------------------------------------------------------------------------- */

.d1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--d1);
  line-height: .95;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.d2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--d2);
  line-height: 1.12;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.d1 em,
.d2 em { font-style: italic; color: var(--brass-deep); }

/* motion.js adds .is-split once the headline has been rebuilt out of .char
   spans. Those spans are inline-blocks, so the element needs its own
   baseline handling to avoid a stray descender gap under the line. */
[data-anim="split"].is-split { line-height: .95; }
[data-anim="split"].is-split .char { vertical-align: bottom; }
.hero__title.is-split { line-height: .88; }

.t1 {
  font-size: var(--t1);
  line-height: 1.55;
  font-weight: 300;
  color: var(--smoke);
  max-width: 46ch;
}

.t0 {
  font-size: var(--t0);          /* 16px floor — never smaller */
  line-height: 1.7;
  color: var(--smoke);
  max-width: 62ch;
}

/* Mono micro-label: wide tracking, uppercase, brass-deep on paper. */
.mono {
  font-family: var(--font-mono);
  font-size: var(--tm);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  font-style: normal;
}

/* Standalone eyebrows sit on their own line with breathing room. */
.eyebrow { display: block; margin-bottom: var(--s3); }

.icon {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
}


/* -------------------------------------------------------------------------
   25.3  SECTION FURNITURE — rhythm, gutters and the ink/paper alternation
   ------------------------------------------------------------------------- */

/* Sections that own their own horizontal gutter (no inner .wrap in markup). */
.banner,
.page-banner,
.services-detail,
.elements,
.pricing-method,
.gallery-section,
.venues,
.cta-band,
.hero,
.statement,
.services,
.counters,
.process,
.testimonials,
.contact-layout,
.faq,
.scrollfilm__caption {
  padding-inline: var(--gutter);
}

/* …but never double up when a .wrap is nested inside one of them. */
.banner > .wrap,
.page-banner > .wrap,
.services-detail > .wrap,
.elements > .wrap,
.pricing-method > .wrap,
.gallery-section > .wrap,
.venues > .wrap,
.cta-band > .wrap,
.statement > .wrap,
.services > .wrap,
.counters > .wrap,
.process > .wrap,
.testimonials > .wrap,
.contact-layout > .wrap,
.faq > .wrap { padding-inline: 0; }

/* Direct children of gutter-owning sections stay inside the measure. */
.banner > *,
.page-banner > *,
.services-detail > *,
.elements > *,
.pricing-method > *,
.gallery-section > *,
.venues > *,
.cta-band > * {
  max-width: var(--wrap);
  margin-inline: auto;
}

/* Vertical rhythm. */
.statement,
.services,
.counters,
.process,
.testimonials,
.services-detail,
.elements,
.pricing-method,
.gallery-section,
.venues,
.contact-layout,
.faq,
.cta-band {
  position: relative;
  padding-block: var(--s6);
}

/* --- The alternation. Full-bleed ink bands against paper. ---------------- */
.statement,
.services,
.process,
.services-detail,
.gallery-section,
.contact-layout,
.hscroll {
  background: var(--paper);
  color: var(--ink);
}

.testimonials,
.elements,
.venues,
.faq {
  background: var(--bone);
  color: var(--ink);
}

.counters,
.pricing-method,
.page-banner {
  background: var(--ink);
  color: var(--paper);
}

/* Generic ink-surface treatment for every dark band (spec §3 contrast). */
.counters,
.pricing-method,
.page-banner,
.banner,
.cta-band,
.scrollfilm,
.site-footer,
.menu { --on-dark: 1; }

.counters .t0,   .pricing-method .t0,   .page-banner .t0,
.banner .t0,     .cta-band .t0,         .scrollfilm .t0,
.counters .t1,   .pricing-method .t1,   .page-banner .t1,
.banner .t1,     .cta-band .t1,         .scrollfilm .t1 { color: #C6C6CB; }

.counters .mono, .pricing-method .mono, .page-banner .mono,
.banner .mono,   .cta-band .mono,       .scrollfilm .mono,
.site-footer .mono, .menu .mono,
.counters .eyebrow, .pricing-method .eyebrow, .page-banner .eyebrow,
.banner .eyebrow, .cta-band .eyebrow { color: var(--brass); }

.counters .d1 em, .pricing-method .d1 em, .page-banner .d1 em,
.banner .d1 em,  .cta-band .d1 em,      .scrollfilm .d1 em,
.counters .d2 em, .pricing-method .d2 em, .page-banner .d2 em,
.banner .d2 em,  .cta-band .d2 em { color: var(--brass); }

.counters .rule, .pricing-method .rule, .page-banner .rule,
.banner .rule,   .cta-band .rule,       .site-footer .rule {
  background: rgba(250, 249, 247, .20);
}


/* -------------------------------------------------------------------------
   25.4  HEADER + NAV + MENU
   ------------------------------------------------------------------------- */

/* The markup has no .site-header__inner — the <header> itself is the row. */
.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  min-height: 72px;
  padding-inline: var(--gutter);
  padding-block: var(--s1);
  /* Every page opens on a dark surface (hero / banner / page-banner), so the
     header starts light and inverts to ink once .is-solid lands. */
  color: var(--paper);
}

.site-header > * { flex: 0 0 auto; }

.site-header.is-solid { color: var(--ink); }

/* Desktop nav — hidden below 900px, where .nav-toggle takes over. */
.nav-desktop,
.nav-inline { display: none; }

.nav-desktop > a,
.nav-inline > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s1);
  position: relative;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: inherit;
}

.nav-desktop > a::after,
.nav-inline > a::after {
  content: "";
  position: absolute;
  left: var(--s1);
  right: var(--s1);
  bottom: 10px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 420ms var(--ease);
}

.nav-desktop > a:hover::after,
.nav-desktop > a:focus-visible::after,
.nav-inline > a:hover::after,
.nav-inline > a:focus-visible::after { transform: scaleX(1); }

.nav-desktop > a[aria-current="page"],
.nav-inline > a[aria-current="page"] { color: var(--brass); }

.site-header.is-solid .nav-desktop > a[aria-current="page"],
.site-header.is-solid .nav-inline > a[aria-current="page"] { color: var(--brass-deep); }

/* The Enquire button inside the nav must not grow the underline pseudo. */
.nav-desktop > a.btn::after,
.nav-inline > a.btn::after { content: none; }

.nav-toggle__bar,
.nav-toggle__line {
  display: block;
  width: 18px;
  height: 1px;
  background: currentColor;
  transition: transform 300ms var(--ease), opacity 200ms linear;
}

/* --- Fullscreen menu (markup uses li > a, plus close / cta / meta) -------- */
.menu__list { border-top: 1px solid rgba(250, 249, 247, .16); }

.menu__list li { border-bottom: 1px solid rgba(250, 249, 247, .16); }

.menu__list a {
  display: flex;
  align-items: center;
  min-height: 64px;
  padding-block: var(--s2);
  font-family: var(--font-display);
  font-size: var(--d2);
  line-height: 1.1;
  color: var(--paper);
  transition: color 300ms var(--ease), transform 500ms var(--ease);
}

.menu__list a:hover,
.menu__list a:focus-visible { color: var(--brass); transform: translateX(8px); }

.menu__list a[aria-current="page"] { color: var(--brass); }

.menu__close {
  position: absolute;
  top: var(--s2);
  right: var(--gutter);
  min-height: 44px;
  min-width: 44px;
  padding-inline: var(--s2);
  border: 1px solid rgba(250, 249, 247, .3);
  color: var(--paper);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  transition: border-color 300ms var(--ease), color 300ms var(--ease);
}

.menu__close:hover { border-color: var(--brass); color: var(--brass); }

.menu__cta { margin-top: var(--s5); align-self: flex-start; }

.menu__meta {
  margin-top: var(--s5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s1) var(--s4);
  align-items: center;
}

.menu__meta a,
.menu__foot a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass);
}

.menu__meta a:hover,
.menu__foot a:hover { color: var(--paper); }

/* site.js sets .is-open after un-hiding the menu and forcing a reflow, so a
   transition on it actually runs. */
.menu {
  opacity: 0;
  transition: opacity 320ms var(--ease);
}

.menu.is-open { opacity: 1; }

.menu.is-open .menu__list a { transform: none; }

/* Scroll lock (site.js sets both). */
html.menu-open { overflow: hidden; }
body.is-loading { overflow: hidden; }


/* -------------------------------------------------------------------------
   25.5  BUTTONS — .btn--primary / .btn--enquire / .btn--ghost in context
   ------------------------------------------------------------------------- */

.btn--primary {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}

.btn--primary::before { background: var(--paper); }
.btn--primary:hover,
.btn--primary:focus-visible { color: var(--ink); }

/* On dark bands the primary button flips to a paper block. */
.hero .btn--primary,
.cta-band .btn--primary,
.page-banner .btn--primary,
.banner .btn--primary {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--paper);
}

.hero .btn--primary::before,
.cta-band .btn--primary::before,
.page-banner .btn--primary::before,
.banner .btn--primary::before { background: var(--ink); }

.hero .btn--primary:hover,
.hero .btn--primary:focus-visible,
.cta-band .btn--primary:hover,
.cta-band .btn--primary:focus-visible { color: var(--paper); }

/* Hero ghost button reads on the dark scrim. */
.hero .btn--ghost,
.page-banner .btn--ghost,
.banner .btn--ghost {
  color: var(--paper);
  border-color: rgba(250, 249, 247, .55);
}

.hero .btn--ghost::before,
.page-banner .btn--ghost::before,
.banner .btn--ghost::before { background: var(--paper); }

.hero .btn--ghost:hover,
.hero .btn--ghost:focus-visible { color: var(--ink); }

/* Header Enquire pill — inherits the header's current colour so it works
   both over the dark hero and against the solid paper header. */
.btn--enquire,
.nav-inline .btn--ghost {
  min-height: 44px;
  padding-inline: var(--s2);
  margin-left: var(--s2);
  color: inherit;
  border-color: currentColor;
}

.btn--enquire::before,
.nav-inline .btn--ghost::before { background: currentColor; }

.site-header:not(.is-solid) .btn--enquire:hover,
.site-header:not(.is-solid) .btn--enquire:focus-visible,
.site-header:not(.is-solid) .nav-inline .btn--ghost:hover { color: var(--ink); }

.site-header.is-solid .btn--enquire:hover,
.site-header.is-solid .btn--enquire:focus-visible { color: var(--paper); }

.menu__cta {
  color: var(--paper);
  border-color: rgba(250, 249, 247, .55);
}
.menu__cta::before { background: var(--paper); }
.menu__cta:hover,
.menu__cta:focus-visible { color: var(--ink); }


/* -------------------------------------------------------------------------
   25.6  HERO — cinematic full-bleed
   ------------------------------------------------------------------------- */

.hero {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

/* FIX: the markup sets `--hero-img:url('assets/images/…')` inline, but a
   url() inside a custom property is resolved against the stylesheet that
   *consumes* it (core.css, i.e. /assets/css/) — not the page. That made the
   hero image 404 and the section render as flat black. Resolving the path
   here, relative to core.css, is the only fix available from the CSS side.
   The inline custom property is left in place and simply overridden. */
.hero__media { background-image: url("../images/hero-hall.jpg"); }

.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(8, 8, 10, .78) 0%,
      rgba(8, 8, 10, .34) 34%,
      rgba(8, 8, 10, .52) 68%,
      rgba(8, 8, 10, .92) 100%),
    linear-gradient(to right,
      rgba(8, 8, 10, .58) 0%,
      rgba(8, 8, 10, .10) 60%,
      rgba(8, 8, 10, 0) 100%);
}

.hero__content {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s3);
}

.hero__content .eyebrow { color: var(--brass); margin-bottom: 0; }

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--d0);
  line-height: .88;
  letter-spacing: -0.025em;
  max-width: 15ch;
  color: var(--paper);
}

.hero__title em { font-style: italic; color: var(--brass); }

.hero__lede {
  color: #D2D2D6;
  max-width: 46ch;
}

.hero__ctas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s2);
}

.hero__scroll {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--wrap);
  margin: var(--s5) auto 0;
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  color: var(--brass);
}

.hero__scroll-label {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: inherit;
}

.hero__scroll-line {
  display: block;
  width: 72px;
  height: 1px;
  background: currentColor;
  transform-origin: left center;
  animation: cue 2.4s var(--ease) infinite;
}


/* -------------------------------------------------------------------------
   25.7  MARQUEE
   ------------------------------------------------------------------------- */

.marquee__item {
  flex: 0 0 auto;
  white-space: nowrap;
  padding-right: var(--s4);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--bone);
}


/* -------------------------------------------------------------------------
   25.8  HOME SECTIONS — statement / services / counters / process / quotes
   ------------------------------------------------------------------------- */

.statement .d1 { max-width: 18ch; }
.statement .rule { margin-block: var(--s4); }

.statement__cols {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s3);
}

/* --- Services (index): four numbered editorial rows --------------------- */
.services__list {
  display: grid;
  grid-template-columns: 1fr;
  border-top: 1px solid var(--line);
}

.services__list .service {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s1);
  padding-block: var(--s4);
  border-top: 0;
  border-bottom: 1px solid var(--line);
  color: inherit;
  transition: background 500ms var(--ease), padding-inline 500ms var(--ease);
}

.services__list .service:hover,
.services__list .service:focus-visible { background: var(--bone); }

.service__num {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  color: var(--brass-deep);
}

.service__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--d2);
  line-height: 1.1;
}

.services__list .service .t0 { max-width: 48ch; }

/* --- Counters (ink band) ------------------------------------------------- */
.counters__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.counters__grid .counter {
  border-top: 1px solid rgba(250, 249, 247, .22);
  padding-top: var(--s2);
}

.counter__num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(3rem, 9vw, 5.5rem);
  line-height: .9;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}

.counter__label {
  margin-top: var(--s2);
  color: var(--brass);
}

/* --- Process ------------------------------------------------------------- */
.process .d1 { max-width: 16ch; margin-bottom: var(--s5); }

.process__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.process__step {
  border-top: 3px solid var(--ink);
  padding-top: var(--s2);
  display: flex;
  flex-direction: column;
  gap: var(--s1);
}

.process__num { color: var(--brass-deep); }

.process__step .d2 { font-size: 1.5rem; }

/* --- Testimonials -------------------------------------------------------- */
.testimonials__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
}

.testimonial {
  border-top: 1px solid var(--line);
  padding-top: var(--s3);
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.testimonial p {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.4;
  color: var(--ink);
  max-width: none;
}

.testimonial cite { font-style: normal; color: var(--brass-deep); }

/* --- CTA band ------------------------------------------------------------ */
.cta-band .d1 { max-width: 14ch; }
.cta-band .t1 { margin-top: var(--s3); }
.cta-band .btn { margin-top: var(--s4); }
.cta-band > .wrap { display: flex; flex-direction: column; align-items: flex-start; }


/* -------------------------------------------------------------------------
   25.9  SCROLLFILM — the pinned showpiece
   motion.js pins the .scrollfilm section itself, so the section is exactly
   one viewport tall and .scrollfilm__pin fills it.
   ------------------------------------------------------------------------- */

.scrollfilm {
  height: 100svh;
  min-height: 520px;
}

.scrollfilm__pin {
  position: relative;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.scrollfilm__stage {
  position: absolute;
  inset: 0;
  min-height: 0;
  height: 100%;
}

/* FIX: same inline-custom-property URL resolution problem as .hero__media —
   `--frame-img` set in the markup resolves against /assets/css/. Frames are
   addressed by their authored data-frame index, in spec §8.5 order. */
.scrollfilm__frame[data-frame="0"] { background-image: url("../images/ceiling-drape.jpg"); }
.scrollfilm__frame[data-frame="1"] { background-image: url("../images/hero-hall.jpg"); }
.scrollfilm__frame[data-frame="2"] { background-image: url("../images/ceremony-arch.jpg"); }
.scrollfilm__frame[data-frame="3"] { background-image: url("../images/place-setting.jpg"); }

.scrollfilm__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(var(--s5) + var(--s2));
  z-index: 2;
  padding: 0 var(--gutter);
  max-width: none;
}

.scrollfilm__caption > * {
  max-width: var(--wrap);
  margin-inline: auto;
  width: 100%;
}

.scrollfilm__line { color: var(--paper); max-width: 20ch; }

.scrollfilm__progress {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: var(--s4);
  width: auto;
  max-width: none;
  z-index: 2;
}

.scrollfilm__progress-fill {
  display: block;
  position: absolute;
  inset: 0;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: left center;
}

/* CSS-only / static fallback: never show an empty rail. */
html:not(.js-anim) .scrollfilm__progress-fill,
.scrollfilm.is-static .scrollfilm__progress-fill { transform: scaleX(1); }

/* Static fallback (no GSAP): motion.js adds .is-static and turns every
   caption line on — stack them as a readable list instead of overlaying. */
.scrollfilm.is-static .scrollfilm__caption {
  display: flex !important;
  flex-direction: column;
  gap: var(--s2);
}

.scrollfilm.is-static .scrollfilm__line,
.scrollfilm.is-static .scrollfilm__line.is-on {
  grid-area: auto;
  opacity: 1 !important;
  transform: none !important;
}

/* Mode B (the shipping default): motion.js owns every layer's opacity, so
   drop the CSS-only "first frame wins" rule that would fight it. */
.scrollfilm.is-frames .scrollfilm__frame + .scrollfilm__frame { opacity: 0; }
.scrollfilm.is-frames .scrollfilm__video { display: none; }

/* Mode A simply swaps which layer paints. */
.scrollfilm.is-video .scrollfilm__frame { display: none; }


/* -------------------------------------------------------------------------
   25.10  ATELIER — service blocks, elements, pricing method
   ------------------------------------------------------------------------- */

.services-detail {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.service-block {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
  padding-block: var(--s6);
  border-top: 1px solid var(--line);
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
}

.services-detail > .service-block:first-child { border-top: 0; padding-top: 0; }

.service-block__media { aspect-ratio: 4 / 5; }

.service-block__copy {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.service-block__copy .eyebrow { margin-bottom: 0; }
.service-block__copy .d2 { margin-bottom: var(--s1); }

.inclusion-list {
  display: flex;
  flex-direction: column;
  margin-top: var(--s3);
  border-top: 1px solid var(--line);
}

.inclusion-list li {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
  min-height: 44px;
  padding-block: var(--s2);
  border-bottom: 1px solid var(--line);
  color: var(--smoke);
  font-size: var(--t0);
  line-height: 1.6;
}

.inclusion-list .icon { color: var(--brass-deep); margin-top: .28em; }

/* --- Individual elements ------------------------------------------------- */
.elements .d1 { max-width: 14ch; margin-bottom: var(--s5); }

.elements__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4) var(--s3);
}

.element-card {
  border-top: 3px solid var(--ink);
  padding-top: var(--s2);
  display: flex;
  flex-direction: column;
  gap: var(--s1);
}

.element-card .d2 { font-size: 1.4rem; }

/* --- Pricing method (ink) ------------------------------------------------ */
.pricing-method .d1 { max-width: 16ch; margin-bottom: var(--s5); }

.pricing-method__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4) var(--s3);
}

.pricing-method__item {
  border-top: 1px solid rgba(250, 249, 247, .22);
  padding-top: var(--s2);
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.pricing-method__item .mono { color: var(--brass); }
.pricing-method__item .t1 { color: #C6C6CB; max-width: 34ch; }


/* -------------------------------------------------------------------------
   25.11  PORTFOLIO — hscroll, filters, gallery, venues
   ------------------------------------------------------------------------- */

.hscroll__caption {
  margin-top: var(--s2);
  color: var(--brass-deep);
}

/* Pinned mode: the section is one viewport tall and JS drives translateX. */
.hscroll.is-pinned {
  height: 100svh;
  display: flex;
  align-items: center;
  padding-block: 0;
}

.hscroll.is-pinned .hscroll__track {
  overflow: visible;
  scroll-snap-type: none;
  width: max-content;
}

/* Swipe mode keeps a visible affordance. */
.hscroll.is-swipe .hscroll__track { padding-bottom: var(--s2); }

.hscroll__panel .frame { aspect-ratio: 4 / 5; }

/* --- Gallery ------------------------------------------------------------- */
.gallery-section .d1 { max-width: 14ch; margin-bottom: var(--s5); }

.filter-btn {
  min-height: 44px;
  padding-inline: var(--s2);
  border: 1px solid var(--line);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
  transition: color 300ms var(--ease), background 300ms var(--ease),
              border-color 300ms var(--ease);
}

.filter-btn:hover { border-color: var(--ink); color: var(--ink); }

.filter-btn[aria-pressed="true"],
.filter-btn.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.gallery__item .mono { margin-top: var(--s2); }
.gallery__item.is-hidden { display: none; }

/* site.js injects .gallery__empty; the markup also ships .gallery-empty. */
.gallery-empty,
.gallery__empty {
  padding: var(--s5) 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

.gallery-empty[hidden],
.gallery__empty[hidden] { display: none; }

/* --- Venues -------------------------------------------------------------- */
.venues .d1 { max-width: 14ch; margin-bottom: var(--s5); }

.venues__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4) var(--s3);
}

.venues__group ul { margin-top: var(--s2); }

.venues__group li {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding-block: var(--s1);
  border-bottom: 1px solid var(--line);
  color: var(--smoke);
}


/* -------------------------------------------------------------------------
   25.12  CONTACT — banner, layout, form, contact card, FAQ
   ------------------------------------------------------------------------- */

.page-banner {
  padding-block: calc(72px + var(--s6)) var(--s6);
  overflow: hidden;
}

.page-banner .d1 { max-width: 16ch; color: var(--paper); }
.page-banner .t1 { margin-top: var(--s3); }

/* The atelier/portfolio banner uses the same shape. */
.banner {
  padding-block: calc(72px + var(--s6)) var(--s6);
}

.banner > * { display: block; }

.banner__title {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--paper);
}

.banner .t1 { margin-top: var(--s3); color: #C6C6CB; }

.contact-layout__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s6) var(--s5);
  align-items: start;
}

.enquiry-form {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.enquiry-form .btn { align-self: flex-start; margin-top: var(--s2); }

.form__status[hidden] { display: none; }
.form__status.is-success { border-left-color: var(--brass-deep); color: var(--ink); }
.form__status.is-error   { border-left-color: var(--danger);  color: var(--danger); }
.form__status.is-pending { border-left-color: var(--smoke);   color: var(--smoke); }

/* Contact card (the markup uses a <ul>, not a <dl>). */
.contact-card__list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--line);
}

.contact-card__list li {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-block: var(--s2);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}

.contact-card__label {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

.contact-card__list a {
  align-self: flex-start;
  border-bottom: 1px solid var(--line);
}

.contact-card .eyebrow { margin-bottom: var(--s2); }

/* --- FAQ ----------------------------------------------------------------- */
.faq .d1 { max-width: 14ch; margin-bottom: var(--s5); }

.faq__list { border-top: 1px solid var(--line); }

.faq__item h3 { font-size: inherit; line-height: inherit; margin: 0; }

.faq__q { position: relative; padding-right: var(--s4); }

/* The markup has no .faq__icon element — draw the +/− from the button. */
.faq__q::after {
  content: "";
  position: absolute;
  right: 2px;
  top: 50%;
  width: 14px;
  height: 1px;
  background: var(--brass-deep);
}

.faq__q::before {
  content: "";
  position: absolute;
  right: 8px;
  top: calc(50% - 7px);
  width: 1px;
  height: 15px;
  background: var(--brass-deep);
  transition: transform 400ms var(--ease);
  transform-origin: center;
}

.faq__q[aria-expanded="true"]::before { transform: scaleY(0); }

.faq__a p {
  padding-bottom: var(--s3);
  color: var(--smoke);
  max-width: 68ch;
}

/* Error row icon colour (markup puts a bare <svg> inside .error). */
.error svg { color: var(--danger); }
.error__text { flex: 1 1 auto; min-width: 0; }


/* -------------------------------------------------------------------------
   25.13  FOOTER — three naming schemes, one appearance
   ------------------------------------------------------------------------- */

.footer__grid,
.site-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--s4);
  align-items: start;
}

.site-footer__top {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}

.footer__brand,
.site-footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.footer__brand .t0,
.site-footer__brand .t0 { color: #9A9AA0; max-width: 34ch; }

.footer__nav,
.footer__contact,
.site-footer__nav,
.site-footer__meta,
.site-footer__top nav {
  display: flex;
  flex-direction: column;
}

.site-footer a {
  display: flex;
  align-items: center;
  min-height: 44px;                    /* spec §10 — the v1 regression */
  color: var(--bone);
  transition: color 300ms var(--ease);
}

.site-footer a:hover,
.site-footer a:focus-visible { color: var(--brass); }

.site-footer a[aria-current="page"] { color: var(--brass); }

/* The wordmark is a column, not a row — restore it. */
.site-footer .wordmark {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  color: var(--paper);
}

.footer__nav a,
.site-footer__nav a,
.site-footer__top nav a {
  font-family: var(--font-mono);
  font-size: var(--tm);
  letter-spacing: .28em;
  text-transform: uppercase;
}

.footer__bottom,
.site-footer__bottom {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
  margin-top: var(--s5);
  padding-top: var(--s2);
  border-top: 1px solid rgba(250, 249, 247, .18);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s1) var(--s3);
}

.footer__bottom .mono,
.site-footer__bottom .mono { color: var(--brass); }


/* -------------------------------------------------------------------------
   25.14  .frame defaults for the shipped markup
   ------------------------------------------------------------------------- */

/* Every .frame in the markup relies on CSS for its box — without an
   aspect-ratio an empty placeholder would collapse to 0px. */
.frame { aspect-ratio: 4 / 5; }

/* site.js adds .is-filled once an image has decoded. Drop the hatched
   placeholder then, so it can't ghost through a transparent PNG edge. */
.frame.is-filled::before { content: none; }

.service-block__media.frame { aspect-ratio: 4 / 5; }

/* Frames sitting on a dark band take the ink placeholder treatment. */
.counters .frame,
.pricing-method .frame,
.page-banner .frame,
.banner .frame { background: var(--ink-2); }


/* -------------------------------------------------------------------------
   25.15  BREAKPOINTS for everything added above (640 / 900 / 1200 / 1440)
   ------------------------------------------------------------------------- */

@media (min-width: 640px) {
  .statement__cols { grid-template-columns: repeat(2, 1fr); gap: var(--s4); }
  .counters__grid { grid-template-columns: repeat(2, 1fr); }
  .process__list { grid-template-columns: repeat(2, 1fr); }
  .testimonials__list { grid-template-columns: repeat(2, 1fr); }
  .elements__grid { grid-template-columns: repeat(2, 1fr); }
  .pricing-method__grid { grid-template-columns: repeat(2, 1fr); }
  .venues__grid { grid-template-columns: repeat(2, 1fr); }
  .footer__grid,
  .site-footer__grid { grid-template-columns: repeat(2, 1fr); }

  .services__list .service {
    grid-template-columns: 5rem 1fr;
    column-gap: var(--s4);
  }
  .service__num { grid-row: span 2; padding-top: .5em; }

  .service-block__media { aspect-ratio: 16 / 9; }
}

@media (min-width: 900px) {
  .nav-desktop,
  .nav-inline {
    display: flex;
    align-items: center;
    gap: var(--s2);
  }

  .site-header { min-height: 84px; }

  .counters__grid { grid-template-columns: repeat(4, 1fr); }
  .process__list { grid-template-columns: repeat(4, 1fr); }
  .testimonials__list { grid-template-columns: repeat(3, 1fr); }
  .elements__grid { grid-template-columns: repeat(3, 1fr); }
  .pricing-method__grid { grid-template-columns: repeat(3, 1fr); }
  .venues__grid { grid-template-columns: repeat(3, 1fr); }

  .service-block {
    grid-template-columns: 5fr 7fr;
    gap: var(--s5);
    align-items: center;
  }
  .service-block__media { aspect-ratio: 4 / 5; }
  .service-block--reverse .service-block__media { order: 2; }

  .contact-layout__grid { grid-template-columns: 7fr 4fr; }

  .footer__grid { grid-template-columns: 2fr 1fr 1fr; }
  .site-footer__grid { grid-template-columns: 2fr 1fr 1fr; }
  .site-footer__top { flex-direction: row; justify-content: space-between; align-items: flex-start; }
  .site-footer__top nav { flex-direction: row; gap: var(--s3); }

  .hero {
    justify-content: center;
    padding-block: calc(84px + var(--s3)) var(--s4);
  }
  .hero__content { gap: var(--s3); }
  /* Auto margin pins the cue to the bottom when there's room, and simply
     follows the CTAs when the display type has eaten the viewport — it can
     never overlap them the way an absolutely-positioned cue would. */
  .hero__scroll { margin-top: auto; padding-top: var(--s4); }

  .services__list .service { grid-template-columns: 6rem 1fr 2fr; align-items: baseline; }
  .services__list .service .t0 { grid-column: 3; }
  .services__list .service:hover { padding-inline: var(--s2); }
}

@media (min-width: 1200px) {
  .statement,
  .services,
  .counters,
  .process,
  .testimonials,
  .services-detail,
  .elements,
  .pricing-method,
  .gallery-section,
  .venues,
  .contact-layout,
  .faq { padding-block: var(--s7); }

  .contact-layout__grid { grid-template-columns: 7fr 3fr; gap: var(--s7); }
  .statement__cols { grid-template-columns: repeat(2, minmax(0, 36ch)); gap: var(--s5); }
}

@media (min-width: 1440px) {
  .hero__title { max-width: 13ch; }
}

/* Very short viewports: the pinned film and hero must not clip. */
@media (max-height: 560px) {
  .scrollfilm { height: auto; min-height: 0; }
  .scrollfilm__pin { height: auto; }
  .scrollfilm__stage { position: relative; aspect-ratio: 16 / 9; }
  .scrollfilm__caption,
  .scrollfilm__progress { position: static; padding-block: var(--s3) 0; }
  .hscroll.is-pinned { height: auto; padding-block: var(--s4); }
}


/* -------------------------------------------------------------------------
   25.16  REDUCED MOTION — neutralises every rule added in §25
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {

  /* No custom cursor, and the native one is never hidden. */
  html.has-cursor,
  html.has-cursor a,
  html.has-cursor button,
  html.has-cursor [data-magnetic] { cursor: auto !important; }

  .cursor { display: none !important; }

  /* Hero cue holds still. */
  .hero__scroll-line { animation: none !important; transform: none !important; }

  /* Marquee stops but stays readable. */
  .marquee__item { transform: none !important; }

  /* Scrollfilm: unpinned, first frame only, captions stacked as a list. */
  .scrollfilm { height: auto !important; min-height: 0 !important; }
  .scrollfilm__pin { height: auto !important; overflow: visible !important; }
  .scrollfilm__stage {
    position: relative !important;
    inset: auto !important;
    height: auto !important;
    aspect-ratio: 16 / 9;
  }
  .scrollfilm__caption,
  .scrollfilm__progress {
    position: static !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
  }
  .scrollfilm__caption {
    display: flex !important;
    flex-direction: column;
    gap: var(--s2);
    padding-block: var(--s4) var(--s2);
  }
  .scrollfilm__line,
  .scrollfilm__line.is-on {
    opacity: 1 !important;
    transform: none !important;
    grid-area: auto !important;
  }
  .scrollfilm__progress { margin-bottom: var(--s5); }
  .scrollfilm__progress-fill { transform: scaleX(1) !important; }

  /* Horizontal track: never pinned, always a native swipe track. */
  .hscroll.is-pinned {
    height: auto !important;
    display: block !important;
    padding-block: var(--s5) !important;
  }
  .hscroll.is-pinned .hscroll__track,
  .hscroll .hscroll__track {
    overflow-x: auto !important;
    scroll-snap-type: x mandatory !important;
    transform: none !important;
    width: auto !important;
  }

  /* Hover-driven layout shifts are motion too. */
  .services__list .service,
  .services__list .service:hover {
    padding-inline: 0 !important;
    transition: none !important;
  }

  .menu__list a:hover,
  .menu__list a:focus-visible { transform: none !important; }

  .nav-desktop > a::after,
  .nav-inline > a::after { transform: scaleX(1) !important; }

  .faq__q::before { transform: none !important; }
  .faq__q[aria-expanded="true"]::before { transform: scaleY(0) !important; }

  .btn::before { transition: none !important; }
}


/* -------------------------------------------------------------------------
   25.17  PRINT addendum — the sections §24 didn't know about
   ------------------------------------------------------------------------- */

@media print {
  .statement,
  .services,
  .counters,
  .process,
  .testimonials,
  .services-detail,
  .elements,
  .pricing-method,
  .gallery-section,
  .venues,
  .contact-layout,
  .faq,
  .page-banner,
  .hero,
  .hscroll {
    background: #fff !important;
    color: #000 !important;
    height: auto !important;
    min-height: 0 !important;
    padding-block: 12pt !important;
  }

  .hero__scrim,
  .hero__media,
  .hero__scroll,
  .scrollfilm__progress,
  .nav-desktop,
  .nav-inline,
  .filter-btn { display: none !important; }

  .hero__title,
  .banner__title,
  .page-banner .d1,
  .counter__num,
  .scrollfilm__line { color: #000 !important; }

  .scrollfilm,
  .scrollfilm__pin { height: auto !important; min-height: 0 !important; }

  .scrollfilm__stage { position: relative !important; aspect-ratio: 16 / 9; }

  .scrollfilm__caption,
  .scrollfilm__progress { position: static !important; }

  .t0, .t1, .mono, .service__num, .process__num,
  .contact-card__label { color: #333 !important; }

  .gallery-empty, .gallery__empty { display: none !important; }

  .service-block, .element-card, .testimonial,
  .pricing-method__item, .venues__group { break-inside: avoid; }
}
