/* ==========================================================================
   MD Focus Studio — style.css
   Dark cinematic foundation · off-white · charcoal · champagne metal accent
   ========================================================================== */

/* ---------- Figures ----------
   Archivo's 6 and 9 close up at the small label sizes (9–12px) on standard-resolution screens:
   "2026" reads as "2028". Digits alone come from Archivo's wide cut (125%), whose open 6 and 9
   stay legible; every letter is still regular Archivo. A 7 KB subset, self-hosted. */
@font-face {
  font-family: "Archivo Figures";
  src: url("../fonts/archivo-figures-wide.woff2") format("woff2");
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0030-0039;
}

/* ---------- Cyrillic serif ----------
   Bodoni Moda has no Cyrillic. Macedonian is set in one family made of two Didones: upright from
   Playfair (Bodoni's proportions, with optical sizes) and italic from Old Standard TT, because
   Playfair's italic capitals are swashes that misread in Macedonian (Ј like a "7", Т like "Ћ").
   Cyrillic subsets only (U+0400–045F holds every Macedonian letter), self-hosted. */
@font-face {
  font-family: "MDF Serif Cyrillic";
  src: url("../fonts/playfair-cyrillic.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "MDF Serif Cyrillic";
  src: url("../fonts/old-standard-italic-cyrillic.woff2") format("woff2");
  font-weight: 400; font-style: italic; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* ---------- Tokens ---------- */
:root {
  --black: #0b0b0a;
  --charcoal: #141412;
  --charcoal-2: #1d1c1a;
  --bone: #ece7dd;
  --stone: #a39d92;
  --metal: #b89a62;
  --metal-hi: #d6bd8a;

  /* Theme-aware (flipped by html.theme-light on the "paper" chapter) */
  --bg: var(--black);
  --fg: var(--bone);
  --fg-muted: var(--stone);
  --hair: rgba(236, 231, 221, .14);

  /* Bodoni Moda and Archivo have no Cyrillic: the Macedonian text is set in their closest Cyrillic
     companions ("MDF Serif Cyrillic" above, and Golos Text). The browser picks per letter, so
     Latin words ("MD Focus Studio", "Instagram") stay in Bodoni and Archivo. */
  --serif: "Bodoni Moda", "MDF Serif Cyrillic", "Bodoni 72", Didot, "Times New Roman", serif;
  --sans: "Archivo Figures", "Archivo", "Golos Text", "Helvetica Neue", Helvetica, Arial, sans-serif;

  --gutter: clamp(18px, 4vw, 64px);
  /* Outer edges also clear the notch / rounded corners (viewport-fit=cover, phones in
     landscape). Inner column gaps keep plain --gutter. */
  --gutter-l: max(var(--gutter), env(safe-area-inset-left, 0px));
  --gutter-r: max(var(--gutter), env(safe-area-inset-right, 0px));
  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --nav-h: 76px;
  --nav-h-scrolled: 58px; /* settled bar height once the page has scrolled */
  --section: clamp(110px, 18vh, 220px);

  /* Accent text and focus ring, theme-aware: champagne on dark, bronze / ink on paper */
  --metal-ink: var(--metal);
  --focus: var(--metal-hi);

  --ease: cubic-bezier(.22, 1, .36, 1);
  --ease-io: cubic-bezier(.76, 0, .24, 1);

  /* The site is dark by design: dark UA widgets and scrollbars, and no algorithmic
     "darken websites" repaint of the paper chapter. Stays dark on html.theme-light. */
  color-scheme: dark;
}

html.theme-light {
  --bg: var(--bone);
  --fg: #11110f;
  --fg-muted: #5d5850;
  --hair: rgba(17, 17, 15, .16);
  --metal-ink: #6f5a32; /* 5.4:1 on bone (champagne would be 2.2:1) */
  --focus: #11110f;     /* ~15:1 on bone */
}

/* Always-dark surfaces keep their own palette regardless of theme */
.hero, .feature__sticky, .wide__stage, .services, .contact, .footer, .viewer, .menu {
  --fg: var(--bone);
  --fg-muted: var(--stone);
  --hair: rgba(236, 231, 221, .14);
  --metal-ink: var(--metal);
  --focus: var(--metal-hi);
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent; /* inherited: no grey/blue tap flash; components give their own :active feedback */
  background: var(--black);
  /* Native anchor and focus scrolling clear the fixed nav */
  scroll-padding-top: calc(var(--nav-h-scrolled) + 16px);
}
/* While scrolling is locked (intro loader, viewer, menu) the classic scrollbar
   disappears; keep its gutter so the page and the fixed nav never jump sideways.
   When unlocked the scrollbar itself fills the same 15px, so nothing moves. */
html.is-loading, html.is-locked { scrollbar-gutter: stable; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
html.is-locked { overflow: hidden; }

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip; /* clip (not hidden) so position: sticky keeps working */
  transition: background-color .9s var(--ease), color .9s var(--ease);
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
/* <picture> wrappers are layout-transparent, so img rules apply as before (contract §2) */
picture { display: contents; }
a { color: inherit; text-decoration: none; }
button {
  font: inherit; color: inherit; background: none; border: 0; padding: 0; margin: 0;
  /* UA styles reset these on buttons; inherit them so a button label matches its context */
  letter-spacing: inherit; text-transform: inherit; word-spacing: inherit;
  cursor: pointer; text-align: inherit;
}
h1, h2, h3, p, figure, blockquote, dl, dd, ol, ul { margin: 0; }
p, blockquote { text-wrap: pretty; } /* no single-word last lines where supported */
ol, ul { padding: 0; list-style: none; }
em { font-style: italic; }
::selection { background: var(--metal); color: var(--black); }
/* 2px ring in a theme-aware colour: champagne on dark surfaces, ink on the paper chapter */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.skip {
  position: fixed; top: calc(12px + var(--safe-t)); left: max(12px, env(safe-area-inset-left, 0px)); z-index: 400; padding: 12px 18px;
  background: var(--bone); color: var(--black); font-size: 13px;
  transform: translateY(-200%); transition: transform .3s var(--ease);
}
.skip:focus { transform: none; }
.skip:focus-visible { outline: 2px solid var(--black); outline-offset: -6px; } /* inside the bone box: visible on any page colour */

.icon { width: 18px; height: 18px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.4; }
.mark { width: 26px; height: 26px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; color: var(--metal-hi); }

/* ---------- Layout helpers & type primitives ---------- */
.wrap { width: 100%; max-width: 1920px; margin-inline: auto; padding-left: var(--gutter-l); padding-right: var(--gutter-r); }

.label {
  display: flex; align-items: center; gap: .9em;
  font: 500 11px/1.4 var(--sans); letter-spacing: .24em; text-transform: uppercase;
  color: var(--fg-muted); transition: color .9s var(--ease);
}
.label__num { color: var(--metal-ink); font-variant-numeric: tabular-nums; }

/* Masked lines for split-text reveals. The mask clips vertically only (the letters
   rise from below the line); sideways, italic overhangs and extra letter-spacing
   (WCAG 1.4.12) stay visible. `hidden` is the fallback where `clip` is unknown. */
.line { display: block; overflow: hidden; overflow: visible clip; padding: 0 .08em .1em 0; margin-bottom: -.1em; }
.line__in { display: inline-block; }
.word { display: inline-block; white-space: nowrap; }
.char { display: inline-block; }
.w { display: inline-block; }
/* Titles that can wrap on phones: every word masks its own letters, so a wrapped
   word never shows (or slides up) outside its row before the reveal */
.project__title .word, .contact__title .word {
  overflow: hidden; overflow: visible clip; vertical-align: top;
  padding: 0 .08em .1em 0; margin: 0 -.08em -.1em 0; /* room for italic overhang and descenders */
}

/* One-shot reveal start states (main.js plays them in when they enter the
   viewport). Only while motion will run: no JS, no GSAP, reduced motion and
   print all show the content as authored. */
@media screen and (prefers-reduced-motion: no-preference) {
  .js:not(.no-motion) [data-reveal]:not(.is-in) { opacity: 0; transform: translate3d(0, 34px, 0); }
  .js:not(.no-motion) [data-reveal-mask]:not(.is-in) { clip-path: inset(100% 0 0 0); }
  .js:not(.no-motion) [data-reveal-mask][data-dir="down"]:not(.is-in) { clip-path: inset(0 0 100% 0); }
  .js:not(.no-motion) [data-reveal-mask][data-dir="left"]:not(.is-in) { clip-path: inset(0 100% 0 0); }
  .js:not(.no-motion) [data-reveal-mask][data-dir="right"]:not(.is-in) { clip-path: inset(0 0 0 100%); }
  .js:not(.no-motion) [data-reveal-lines]:not(.is-split) { visibility: hidden; }
  .js:not(.no-motion) .is-split:not(.is-in) .char { transform: translate3d(0, 118%, 0); }
  .js:not(.no-motion) .footer__word.is-split:not(.is-in) .char { transform: translate3d(0, 110%, 0); }
}

.cap {
  display: flex; gap: 14px; margin-top: 14px;
  font: 500 10.5px/1.4 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted);
  transition: color .9s var(--ease);
}
.cap span { color: var(--metal-ink); transition: color .9s var(--ease); }
/* Caption responds to its image: a hairline draws out from the frame number
   (the number only — other spans in a caption, such as a gallery rating, are left alone) */
.cap > span:first-child { display: inline-flex; align-items: center; }
.cap > span:first-child::after { content: ""; width: 0; height: 1px; margin-left: 0; background: currentColor; transition: width .6s var(--ease), margin .6s var(--ease); }
@media (hover: hover) { figure:hover > .cap > span:first-child::after { width: 22px; margin-left: 10px; } }
figure:focus-within > .cap > span:first-child::after { width: 22px; margin-left: 10px; }

/* Champagne is too light on the paper chapter (2.2:1): --metal-ink turns bronze there (5.4:1)
   and these accents fade with the page */
.label__num, .chapter__num { transition: color .9s var(--ease); }

/* Rolling text micro-interaction (contract §5). The label and its clone share one grid
   cell; the clone is a real, aria-hidden element, so the accessible name is said once. */
.roll { display: inline-grid; overflow: hidden; vertical-align: top; }
.roll__in { grid-area: 1 / 1; transition: transform .7s var(--ease); }
.roll__clone { transform: translateY(105%); }
@media (hover: hover) {
  a:hover .roll__in, button:hover .roll__in { transform: translateY(-105%); }
  a:hover .roll__clone, button:hover .roll__clone { transform: none; }
}
a:focus-visible .roll__in, button:focus-visible .roll__in { transform: translateY(-105%); }
a:focus-visible .roll__clone, button:focus-visible .roll__clone { transform: none; }

/* ---------- Grain ---------- */
.grain { position: fixed; inset: 0; z-index: 140; pointer-events: none; overflow: hidden; opacity: .055; }
/* Overscan only as far as the keyframes travel (6% of 130% < 15%): a 1.7x-viewport layer, not 4x */
.grain::before {
  content: ""; position: absolute; inset: -15%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 220px 220px;
}
/* The grain is deliberately static: a film texture, not an animation loop that would keep
   a full-viewport layer compositing every frame for the life of the page */

/* ---------- Loader ---------- */
.loader {
  position: fixed; inset: 0; z-index: 300; display: none; place-items: center;
  background: var(--black); color: var(--bone);
  --r: 0px;
  -webkit-mask-image: radial-gradient(circle at 50% 50%, transparent var(--r), #000 calc(var(--r) + 1px));
  mask-image: radial-gradient(circle at 50% 50%, transparent var(--r), #000 calc(var(--r) + 1px));
}
.is-loading .loader { display: grid; }
.is-loading body { overflow: hidden; }
.loader__center { display: flex; flex-direction: column; align-items: center; gap: 28px; }
.loader__mark { width: clamp(84px, 9vw, 118px); height: auto; overflow: visible; color: var(--metal-hi); }
.loader__ring, .loader__blade { fill: none; stroke: currentColor; stroke-width: 1.1; stroke-linecap: round; }
.loader__word { font: 500 11px/1 var(--sans); letter-spacing: .52em; padding-left: .52em; text-transform: uppercase; }
.loader__meta, .loader__count { position: absolute; bottom: max(clamp(20px, 4vh, 40px), var(--safe-b)); }
.loader__meta { left: var(--gutter-l); font: 500 10px/1.4 var(--sans); letter-spacing: .24em; text-transform: uppercase; color: var(--stone); }
.loader__count { right: var(--gutter-r); font: 400 clamp(40px, 6vw, 88px)/1 var(--serif); letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
/* The draw-on and the text fade run in CSS from the very first paint (the paths carry
   pathLength="1"), so nothing shows fully drawn and then vanishes when scripts arrive.
   A dash shorter than its gap, offset just past the end, leaves no round-cap dots.
   main.js adds .is-drawn when the aperture opens (snaps the draw complete, hands the
   texts to GSAP). Without JS or with reduced motion the mark is simply static. */
@media (prefers-reduced-motion: no-preference) {
  .js .loader__ring, .js .loader__blade { stroke-dasharray: 1 2; stroke-dashoffset: 1.001; animation: loaderDraw 1.1s cubic-bezier(.65, 0, .35, 1) .05s both; }
  .js .loader__blade { animation-duration: .8s; animation-timing-function: cubic-bezier(.33, 1, .68, 1); }
  .js .loader__blade:nth-of-type(1) { animation-delay: .4s; }
  .js .loader__blade:nth-of-type(2) { animation-delay: .47s; }
  .js .loader__blade:nth-of-type(3) { animation-delay: .54s; }
  .js .loader__blade:nth-of-type(4) { animation-delay: .61s; }
  .js .loader__blade:nth-of-type(5) { animation-delay: .68s; }
  .js .loader__blade:nth-of-type(6) { animation-delay: .75s; }
  .js .loader__word, .js .loader__meta, .js .loader__count { opacity: 0; animation: loaderFade .9s cubic-bezier(.22, 1, .36, 1) .1s both; }
  .js .loader__meta { animation-delay: .18s; }
  .js .loader__count { animation-delay: .26s; }
  /* Repeat visit (set by the head script): the short intro */
  .is-seen .loader__ring { animation-duration: .45s; }
  .is-seen .loader__blade { animation-duration: .35s; }
  .is-seen .loader__blade:nth-of-type(n) { animation-delay: calc(.12s + var(--b, 0) * .03s); }
  .is-seen .loader__blade:nth-of-type(2) { --b: 1; } .is-seen .loader__blade:nth-of-type(3) { --b: 2; }
  .is-seen .loader__blade:nth-of-type(4) { --b: 3; } .is-seen .loader__blade:nth-of-type(5) { --b: 4; }
  .is-seen .loader__blade:nth-of-type(6) { --b: 5; }
  .is-seen :is(.loader__word, .loader__meta, .loader__count) { animation-duration: .6s; }
  .loader.is-drawn :is(.loader__ring, .loader__blade) { animation: none; stroke-dashoffset: 0; }
  .loader.is-drawn :is(.loader__word, .loader__meta, .loader__count) { animation: none; opacity: 1; transform: none; }
}
@keyframes loaderDraw { from { stroke-dashoffset: 1.001; } to { stroke-dashoffset: 0; } }
@keyframes loaderFade { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

/* ---------- Cursor ---------- */
/* The blend sits on the fixed wrapper (its own stacking context), so the white
   dot and ring invert against the page itself: dark on the paper chapter. */
.cursor { position: fixed; top: 0; left: 0; z-index: 260; pointer-events: none; opacity: 0; transition: opacity .4s; mix-blend-mode: difference; }
.cursor.is-view { mix-blend-mode: normal; } /* the bone "View project" disc keeps its colours */
.has-cursor .cursor.is-visible { opacity: 1; }
/* main.js adds .has-cursor only after the intro loader, so the native pointer stays visible while it plays.
   High-contrast users keep their OS pointer even if they switch it on after the page has loaded. */
@media not all and (forced-colors: active) {
  .has-cursor, .has-cursor * { cursor: none !important; }
}
.cursor__dot, .cursor__ring { position: fixed; top: 0; left: 0; will-change: transform; }
.cursor__dot {
  width: 6px; height: 6px; margin: -3px 0 0 -3px; border-radius: 50%;
  background: #fff; transition: opacity .3s;
}
.cursor__ring { width: 0; height: 0; }
.cursor__circle {
  position: absolute; left: 0; top: 0; width: 38px; height: 38px; transform: translate(-50%, -50%);
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .55);
  transition: width .55s var(--ease), height .55s var(--ease), background-color .45s var(--ease), border-color .45s var(--ease);
}
@supports not (mix-blend-mode: difference) {
  html.theme-light .cursor__dot { background: var(--black); }
  html.theme-light .cursor__circle, html.theme-light .cursor__c { border-color: rgba(17, 17, 15, .6); }
}
.cursor__label {
  font: 600 9.5px/1 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--black);
  white-space: nowrap; opacity: 0; transform: scale(.6); transition: opacity .3s, transform .5s var(--ease);
}
.cursor__c {
  position: absolute; width: 14px; height: 14px; border: 0 solid #fff; opacity: 0;
  transition: opacity .4s var(--ease), transform .6s var(--ease);
}
.cursor__c:nth-of-type(1) { left: -36px; top: -28px; border-left-width: 1px; border-top-width: 1px; transform: translate(-10px, -10px); }
.cursor__c:nth-of-type(2) { right: -36px; top: -28px; border-right-width: 1px; border-top-width: 1px; transform: translate(10px, -10px); }
.cursor__c:nth-of-type(3) { left: -36px; bottom: -28px; border-left-width: 1px; border-bottom-width: 1px; transform: translate(-10px, 10px); }
.cursor__c:nth-of-type(4) { right: -36px; bottom: -28px; border-right-width: 1px; border-bottom-width: 1px; transform: translate(10px, 10px); }

.cursor.is-link .cursor__circle { width: 60px; height: 60px; border-color: #fff; }
.cursor.is-link .cursor__dot { opacity: 0; }
.cursor.is-view .cursor__circle { width: 118px; height: 118px; background: var(--bone); border-color: var(--bone); }
.cursor.is-view .cursor__label { opacity: 1; transform: none; }
.cursor.is-view .cursor__dot { opacity: 0; }
.cursor.is-focus .cursor__circle { width: 6px; height: 6px; border-color: transparent; }
.cursor.is-focus .cursor__c { opacity: 1; transform: none; }
/* Over a magnetic call to action the ring opens up and leans onto the button (main.js) */
.cursor.is-magnet .cursor__circle { width: 84px; height: 84px; border-color: rgba(255, 255, 255, .9); }

/* ---------- Navigation ---------- */
.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 60; pointer-events: none; color: var(--fg); transition: color .9s var(--ease); }
.nav__bar {
  position: relative; pointer-events: auto;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  /* the top inset is 0 in the Safari tab bar and grows the bar only in standalone / notched layouts */
  height: calc(var(--nav-h) + var(--safe-t)); padding: var(--safe-t) var(--gutter-r) 0 var(--gutter-l);
  transition: height .7s var(--ease), transform .6s var(--ease);
}
/* Reading downwards the bar steps aside; any upward movement, focus or the menu brings it back (main.js) */
.nav.is-hidden .nav__bar { transform: translate3d(0, -101%, 0); }
/* Opaque bar: at 92% the giant serif lines scrolling underneath read as ghost letters */
.nav__bar::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--bg);
  border-bottom: 1px solid var(--hair);
  opacity: 0; transform: translateY(-100%);
  transition: opacity .6s var(--ease), transform .8s var(--ease), background-color .9s var(--ease);
}
.nav.is-scrolled .nav__bar { height: calc(var(--nav-h-scrolled) + var(--safe-t)); }
.nav.is-scrolled .nav__bar::before,
html:not(.js) .nav__bar::before { opacity: 1; transform: none; } /* no JS: the bar never learns it scrolled */

.nav__brand { display: inline-flex; align-items: center; gap: 12px; min-width: 0; min-height: 44px; font: 600 12px/1 var(--sans); letter-spacing: .3em; text-transform: uppercase; white-space: nowrap; }
.nav__brand .mark { transition: transform 1.1s var(--ease), color .9s var(--ease); }
.nav.is-scrolled .nav__brand .mark { transform: rotate(60deg); }
@media (hover: hover) { .nav__brand:hover .mark { transform: rotate(120deg); } }
.nav__brand:focus-visible .mark { transform: rotate(120deg); }
.nav__word { display: inline-flex; align-items: center; }
.nav__rest { display: inline-block; overflow: hidden; max-width: 13em; white-space: nowrap; transition: max-width .8s var(--ease), opacity .5s var(--ease); }
.nav.is-scrolled .nav__rest { max-width: 0; opacity: 0; }
.theme-light .nav .mark { color: var(--metal-ink); }

.nav__links { display: flex; gap: clamp(22px, 2.8vw, 46px); margin-left: auto; }
.nav__link { position: relative; padding: 8px 0; font: 500 11px/1.3 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.nav__link::before {
  content: ""; position: absolute; left: -13px; top: 50%; width: 4px; height: 4px; margin-top: -2px;
  border-radius: 50%; background: var(--metal-ink); transform: scale(0); transition: transform .5s var(--ease), background-color .9s var(--ease);
}
.nav__link.is-active::before { transform: scale(1); }

/* "Book a session": a square, hairline-outlined call to action (desktop bar; the mobile menu has it below 900px) */
.nav__cta {
  display: inline-flex; align-items: center; height: 40px; padding: 0 18px; margin-left: clamp(4px, 1vw, 18px);
  font: 500 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; white-space: nowrap;
  border: 1px solid rgba(236, 231, 221, .45);
  border-color: color-mix(in srgb, currentColor 45%, transparent);
  transition: height .7s var(--ease), color .5s var(--ease), background-color .5s var(--ease), border-color .5s var(--ease);
}
.nav.is-scrolled .nav__cta { height: 36px; }
@media (hover: hover) {
  .nav__cta:hover { background-color: var(--fg); color: var(--bg); border-color: var(--fg); }
}
.nav__cta:focus-visible { background-color: var(--fg); color: var(--bg); border-color: var(--fg); }
/* booking.html: "you are here" — a full-strength outline instead of the 45% hairline */
.nav__cta[aria-current="page"] { border-color: currentColor; }

.nav__menu { display: none; flex-shrink: 0; align-items: center; gap: 12px; height: 44px; font: 500 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.nav__menu-label { min-width: 4.4em; text-align: right; } /* "Menu" ↔ "Close" without the button shifting */
.nav__burger { position: relative; width: 26px; height: 10px; }
.nav__burger i { position: absolute; left: 0; right: 0; height: 1px; background: currentColor; transition: transform .6s var(--ease), top .6s var(--ease); }
.nav__burger i:first-child { top: 0; }
.nav__burger i:last-child { top: 9px; }
/* Open menu: the bar dissolves into the charcoal overlay, whatever the page theme
   (the scrolled-bar rule is outranked here, so no bone band shows over the dark menu) */
.menu-open .nav { color: var(--bone); --bg: var(--charcoal); --hair: rgba(236, 231, 221, .14); --focus: var(--metal-hi); --metal-ink: var(--metal); }
.menu-open .nav .nav__bar::before,
.menu-open .nav.is-scrolled .nav__bar::before { opacity: 0; transform: translateY(-100%); }
html.menu-open .nav .mark { color: var(--metal-hi); }
.menu-open .nav__burger i:first-child { top: 4.5px; transform: rotate(45deg); }
.menu-open .nav__burger i:last-child { top: 4.5px; transform: rotate(-45deg); }

/* ---------- Mobile menu ---------- */
/* Scrolls on its own when it can't fit (short landscape phones, zoom): the page underneath
   is locked, and data-lenis-prevent keeps the smooth-scroll handler out of it */
.menu {
  position: fixed; inset: 0; z-index: 55;
  display: flex; flex-direction: column; justify-content: space-between; gap: 40px;
  padding: calc(var(--nav-h) + var(--safe-t) + 8svh) var(--gutter-r) max(28px, var(--safe-b)) var(--gutter-l);
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--charcoal); color: var(--bone);
  clip-path: inset(0 0 100% 0); visibility: hidden;
  transition: clip-path .7s var(--ease-io), visibility 0s linear .7s;
}
.menu > * { flex-shrink: 0; }
.menu.is-open { clip-path: inset(0 0 0 0); visibility: visible; transition: clip-path .7s var(--ease-io), visibility 0s; }
.menu__list { display: flex; flex-direction: column; gap: 4px; }
.menu__link { display: block; overflow: hidden; font: 400 clamp(34px, min(14vw, 11svh), 96px)/1.02 var(--serif); letter-spacing: -.02em; text-transform: uppercase; }
.menu__link span { display: inline-flex; align-items: baseline; gap: 18px; transform: translateY(105%); transition: transform .9s var(--ease), opacity .4s var(--ease); }
.menu.is-open .menu__link span { transform: none; transition-delay: calc(.2s + var(--i) * .06s), 0s; }
/* Pointer over the list: the other links step back, the one under the pointer stays full strength */
@media (hover: hover) {
  .menu__list:hover .menu__link span { opacity: .55; }
  .menu__list .menu__link:hover span { opacity: 1; }
}
.menu__link small { font: 500 11px var(--sans); letter-spacing: .2em; color: var(--metal); }
.menu__foot {
  display: flex; justify-content: space-between; gap: 16px;
  font: 500 11px/1.6 var(--sans); letter-spacing: .2em; text-transform: uppercase; color: var(--stone);
  opacity: 0; transition: opacity .5s;
}
.menu.is-open .menu__foot { opacity: 1; transition: opacity .6s .6s; }

/* ---------- Buttons & links ---------- */
.btn {
  position: relative; isolation: isolate; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; gap: 14px;
  height: 64px; padding: 0 34px;
  font: 500 12px/1 var(--sans); letter-spacing: .22em; text-transform: uppercase;
  border: 1px solid var(--bone);
  transition: color .6s var(--ease), border-color .6s var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  transform: translateY(101%); transition: transform .7s var(--ease);
}
.btn--solid { background: var(--bone); color: var(--black); }
.btn--solid::before { background: var(--black); }
.btn--ghost { color: var(--bone); border-color: rgba(236, 231, 221, .4); }
.btn--ghost::before { background: var(--bone); }
.btn:focus-visible::before { transform: none; }
.btn--solid:focus-visible { color: var(--bone); }
.btn--ghost:focus-visible { color: var(--black); border-color: var(--bone); }
.btn__label { display: inline-block; text-align: center; }

/* 44px tall hit area (15px padding), pulled back by a negative margin so the layout is unchanged */
.btn-text {
  display: inline-flex; align-items: center; gap: 16px; padding: 15px 0; margin-block: -3px;
  font: 500 11px/1.3 var(--sans); letter-spacing: .24em; text-transform: uppercase;
}
.btn-text__line { width: 40px; height: 1px; background: currentColor; transition: width .7s var(--ease); }
.btn-text:focus-visible .btn-text__line { width: 76px; }

.link-cta {
  display: inline-flex; align-items: center; gap: 16px; padding: 16px 0; margin-block: -2px;
  font: 500 11.5px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase;
}
.link-cta__line { width: 48px; height: 1px; background: currentColor; transition: width .8s var(--ease); }
.link-cta .icon { transition: transform .8s var(--ease); }
.link-cta:focus-visible .link-cta__line { width: 84px; }
.link-cta:focus-visible .icon { transform: translateX(6px); }

/* Hover states only where hover is real: on touch screens :hover sticks after a tap
   (e.g. a button left inverted when the user comes back from Instagram) */
@media (hover: hover) {
  .btn:hover::before { transform: none; }
  .btn--solid:hover { color: var(--bone); }
  .btn--ghost:hover { color: var(--black); border-color: var(--bone); }
  .btn-text:hover .btn-text__line { width: 76px; }
  .link-cta:hover .link-cta__line { width: 84px; }
  .link-cta:hover .icon { transform: translateX(6px); }
}
/* Touch: a short, deliberate pressed state instead of the browser's tap flash */
@media (hover: none) {
  :is(.btn, .btn-text, .link-cta, .menu__link, .wi, .big-link, .nav__brand, .nav__menu, .footer__v, .contact__details a.v, .quotes__btn, .viewer__btn, .viewer__close, .hscroll__btn):active { opacity: .62; transition: opacity 0s; }
}

/* ---------- Shots (interactive images) ---------- */
.shot {
  position: relative; display: block; width: 100%; overflow: hidden; isolation: isolate;
  aspect-ratio: var(--ar, 3 / 2); background: var(--charcoal-2);
}
.shot__plx, .shot__hover { position: absolute; inset: 0; display: block; }
.shot__hover { inset: -2%; }
.shot--plx .shot__plx { inset: -8% 0; }
.shot img {
  width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%);
  transition: transform 1.6s var(--ease);
}
/* Hover / focus caption: the scrim rises well above the text, so title and meta always
   sit on at least ~68% black, even over white kit */
.shot__info {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0;
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding: clamp(56px, 7vw, 110px) clamp(14px, 1.6vw, 24px) clamp(14px, 1.6vw, 24px); color: var(--bone);
  background: linear-gradient(to top, rgba(11, 11, 10, .86) 0%, rgba(11, 11, 10, .68) 50%, rgba(11, 11, 10, 0) 100%);
  opacity: 0; transform: translateY(14px); pointer-events: none;
  transition: opacity .6s var(--ease), transform .8s var(--ease);
}
.shot__title { font: 400 clamp(18px, 1.6vw, 26px)/1.1 var(--serif); text-shadow: 0 1px 14px rgba(11, 11, 10, .5); }
.shot__meta { font: 500 11px/1.4 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--bone); white-space: nowrap; text-shadow: 0 1px 12px rgba(11, 11, 10, .6); }
@media (hover: hover) {
  .shot:hover img { transform: scale(1.06); }
  .shot:hover .shot__info { opacity: 1; transform: none; }
}
.shot:focus-visible .shot__info { opacity: 1; transform: none; }
/* Keyboard focus ring drawn inside the frame, above the photo: the reveal's clip-path and
   the overflow-hidden stages can't clip it. Two-tone, so it holds on bright and dark images. */
.shot::before {
  content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none;
  box-shadow: inset 0 0 0 2px var(--metal-hi), inset 0 0 0 6px rgba(11, 11, 10, .5);
  opacity: 0; transition: opacity .3s var(--ease);
}
.shot:focus-visible { outline: none; }
.shot:focus-visible::before { opacity: 1; }
/* Full-bleed stages: keep the ring clear of the fixed nav and inside the side gutters */
.feature__media::before, .wide__hero::before { inset: calc(var(--nav-h-scrolled) + var(--safe-t) + 14px) var(--gutter-r) 14px var(--gutter-l); }
html:not(.js) .shot { cursor: default; } /* the viewer needs main.js */

/* ---------- Hero ---------- */
.hero { position: relative; height: 100vh; height: 100svh; min-height: 600px; overflow: hidden; background: var(--black); color: var(--fg); }
.hero__media { position: absolute; inset: 0; }
/* Landscape framing: the leaping #11's head sits ~2% from the top of the frame, so the photo is
   anchored near its top edge and the lens grows downwards. The bleed only covers the pointer
   parallax (±14px across, ±5px down). Portrait screens use the 9:16 crop (rule further down). */
.hero__shift { position: absolute; inset: -8px -16px -12px; will-change: transform; }
/* The lens carries the scale (intro + drift); the image layers inside never animate a filter */
.hero__lens { position: absolute; inset: 0; transform: scale(1.02); transform-origin: 46% 0; will-change: transform; } /* 1.02: keep main.js restScale() in step */
.hero__img, .hero__soft { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 46% 6%; }
/* Soft-focus copy (640w, blurred once, then cross-faded away by opacity only) */
.hero__soft { filter: blur(6px); will-change: opacity; pointer-events: none; }
.hero__veil { position: absolute; inset: 0; background: var(--black); opacity: 0; pointer-events: none; }
/* Shade: a px-based top band for the nav, and a scrim measured from the bottom edge to just
   above the copy (--scrim, set per layout), so the eyebrow and title keep their contrast on
   any screen height instead of depending on a percentage of the photo */
.hero {
  --hero-bottom: clamp(70px, 11vh, 130px);
  --scrim: calc(var(--hero-bottom) + 1.68 * clamp(64px, 11.4vw, 232px) + 230px);
}
.hero__shade {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(11, 11, 10, .66) 0, rgba(11, 11, 10, .4) 96px, rgba(11, 11, 10, 0) 220px),
    radial-gradient(75% 62% at 14% 100%, rgba(11, 11, 10, .5) 0%, rgba(11, 11, 10, .32) 55%, rgba(11, 11, 10, 0) 100%),
    linear-gradient(0deg, rgba(11, 11, 10, .9) 0, rgba(11, 11, 10, .66) calc(var(--scrim) * .45), rgba(11, 11, 10, .4) calc(var(--scrim) * .74), rgba(11, 11, 10, 0) var(--scrim)),
    radial-gradient(120% 90% at 35% 45%, rgba(11, 11, 10, 0) 45%, rgba(11, 11, 10, .4) 100%);
}
/* The bar has no backdrop over the hero (it fades in once the page scrolls): a soft halo
   keeps the brand and links legible over the bright top of the photo */
.nav:not(.is-scrolled) :is(.nav__brand, .nav__link, .nav__menu) { text-shadow: 0 1px 10px rgba(11, 11, 10, .6); }
.theme-light .nav:not(.is-scrolled) :is(.nav__brand, .nav__link, .nav__menu) { text-shadow: none; }
.hero__dim { position: absolute; inset: 0; background: var(--black); opacity: 0; }

.hero__content {
  position: absolute; left: 0; right: 0; bottom: var(--hero-bottom); z-index: 2;
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; column-gap: 4vw; row-gap: 22px;
}
.hero__eyebrow { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px 36px; font: 500 11px/1.4 var(--sans); letter-spacing: .26em; text-transform: uppercase; color: var(--bone); text-shadow: 0 1px 12px rgba(11, 11, 10, .7), 0 0 2px rgba(11, 11, 10, .5); }
.hero__title { font: 400 clamp(64px, 11.4vw, 232px)/.84 var(--serif); letter-spacing: -.03em; text-transform: uppercase; text-shadow: 0 2px 30px rgba(11, 11, 10, .3); }
.hero__title .l1, .hero__title .l2 { display: inline-block; vertical-align: top; }
.hero__title .l1 { margin-right: .22em; }
.hero__title .l3 { padding-left: 1.08em; }
.hero__side { width: min(300px, 26vw); padding-bottom: .9vw; }
.hero__statement { font: 400 clamp(22px, 1.9vw, 32px)/1.16 var(--serif); margin-bottom: 26px; }
.hero__statement em { display: block; }
.hero__foot {
  position: absolute; left: 0; right: 0; bottom: max(26px, var(--safe-b)); z-index: 2;
  display: flex; justify-content: space-between; align-items: center; gap: 20px;
  font: 500 10px/1.4 var(--sans); letter-spacing: .24em; text-transform: uppercase; color: rgba(236, 231, 221, .72);
}
.hero__scroll { display: inline-flex; align-items: center; gap: 14px; }
.hero__scroll i { position: relative; width: 1px; height: 30px; overflow: hidden; background: rgba(236, 231, 221, .22); }
.hero__scroll i::after {
  content: ""; position: absolute; left: 0; top: 0; width: 1px; height: 100%; background: var(--bone);
  transform: translateY(-100%); animation: scrollcue 2.4s var(--ease-io) infinite;
}
@keyframes scrollcue { 0% { transform: translateY(-100%); } 55% { transform: translateY(0); } 100% { transform: translateY(100%); } }
/* The cue has done its job once the visitor scrolls: it settles into a still line */
.has-scrolled .hero__scroll i::after { animation: none; transform: none; opacity: .5; }

/* Hide the hero copy until the intro animation takes over (JS only) */
.js:not(.is-ready) .hero__content, .js:not(.is-ready) .hero__foot { opacity: 0; }

/* ---------- Introduction ---------- */
.intro { position: relative; overflow: hidden; padding: clamp(130px, 22vh, 260px) 0 var(--section); }
.intro__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: clamp(48px, 7vw, 110px); }
.intro__label { grid-column: 1 / -1; }
.intro__title { grid-column: 1 / -1; font: 400 clamp(40px, 7vw, 134px)/.94 var(--serif); letter-spacing: -.025em; text-transform: uppercase; }
.intro__line { display: block; }
.intro__line--b { padding-left: 14%; }
.intro__line--c { padding-left: 4%; }
.intro__line--d { padding-left: 22%; }
.intro__body { grid-column: 6 / 13; display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1fr); column-gap: var(--gutter); align-items: end; }
.intro__copy { display: grid; gap: 26px; justify-items: start; }
.intro__text { font-size: clamp(15px, 1.1vw, 18px); line-height: 1.75; color: var(--fg-muted); max-width: 42ch; transition: color .9s var(--ease); }

/* ---------- Work ---------- */
.work { position: relative; padding-top: clamp(40px, 8vh, 100px); }
.work__head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: 28px; align-items: end; }
.work__head .label { grid-column: 1 / -1; }
.work__title { grid-column: 1 / -1; font: 400 clamp(60px, 11vw, 214px)/.86 var(--serif); letter-spacing: -.03em; text-transform: uppercase; }
.line--indent { padding-left: 1.4em; }
.line--indent-2 { padding-left: 2.2em; }
/* The count hangs from the cap line of "WORK" (top-aligned to the line box), at every size */
.work__title sup { position: relative; vertical-align: top; top: .9em; margin-left: .5em; font: 500 12px var(--sans); letter-spacing: .2em; color: var(--metal-ink); transition: color .9s var(--ease); }
.work__intro { grid-column: 8 / 13; max-width: 36ch; color: var(--fg-muted); transition: color .9s var(--ease); }

.work__index { margin-top: clamp(64px, 9vw, 130px); }
.work__index li { border-top: 1px solid var(--hair); transition: border-color .9s var(--ease); }
.work__index li:last-child { border-bottom: 1px solid var(--hair); }
.wi {
  display: grid; grid-template-columns: 70px minmax(0, 1.4fr) 144px minmax(0, 1fr) 70px; align-items: center; gap: 24px;
  /* only the horizontal hover offset animates: vertical padding is vw-based and
     must not keep changing the page height after a resize */
  padding: clamp(18px, 2vw, 28px) 0; transition: padding-left .7s var(--ease);
}
/* Row preview: anchored in its own column, unmasked in place (never follows the pointer) */
.wi__thumb {
  position: relative; display: block; width: 144px; aspect-ratio: 3 / 2; overflow: hidden;
  background: var(--charcoal-2); clip-path: inset(0 100% 0 0);
  transition: clip-path .8s var(--ease-io);
}
.wi__thumb img { width: 100%; height: 100%; object-fit: cover; transform: scale(1.16); transition: transform 1.2s var(--ease); }
.wi:focus-visible .wi__thumb { clip-path: inset(0 0 0 0); }
.wi:focus-visible .wi__thumb img { transform: none; }
.wi__num { font: 500 11px var(--sans); letter-spacing: .2em; color: var(--metal-ink); }
.wi__title { font: 400 clamp(26px, 3vw, 50px)/1.05 var(--serif); transition: opacity .5s var(--ease); }
.wi__cat, .wi__year { font: 500 11px var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted); }
.wi__num, .wi__cat, .wi__year { transition: opacity .5s var(--ease), color .9s var(--ease); }
.wi__year { text-align: right; }
@media (hover: hover) {
  /* Dim the other rows without dropping below readable contrast */
  .work__index:hover .wi:not(:hover) .wi__title { opacity: .5; }
  .work__index:hover .wi:not(:hover) :is(.wi__num, .wi__cat, .wi__year) { opacity: .8; }
  .work__index .wi:hover { padding-left: 1.6vw; }
  .wi:hover .wi__thumb { clip-path: inset(0 0 0 0); }
  .wi:hover .wi__thumb img { transform: none; }
}

/* Project common */
.project { position: relative; }
.project__num { font: 500 11px/1 var(--sans); letter-spacing: .24em; color: var(--metal-ink); transition: color .9s var(--ease); }
.project__title { font: 400 clamp(48px, 8vw, 152px)/.88 var(--serif); letter-spacing: -.025em; text-transform: uppercase; }
.project__meta { display: flex; flex-wrap: wrap; gap: 6px 22px; font: 500 11px/1.5 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted); transition: color .9s var(--ease); }
.project__desc { max-width: 36ch; color: var(--fg-muted); transition: color .9s var(--ease); }

/* Project 01 — feature */
.feature { margin-top: clamp(100px, 16vh, 200px); }
.feature__pin { position: relative; height: 210vh; }
.feature__sticky { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; color: var(--fg); background: var(--black); }
.feature__media.shot { position: absolute; inset: 0; aspect-ratio: auto; width: 100%; height: 100%; }
/* Viewfinder: four hairline corners sit just outside the opening frame and travel with
   its edges (main.js scrubs their transforms), dissolving as the photo reaches full bleed */
.feature__frame { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.feature__frame i { position: absolute; width: 26px; height: 26px; border: 0 solid rgba(236, 231, 221, .78); will-change: transform; }
.feature__frame i:nth-child(1) { left: 0; top: 0; margin: -12px 0 0 -12px; border-left-width: 1px; border-top-width: 1px; }
.feature__frame i:nth-child(2) { right: 0; top: 0; margin: -12px -12px 0 0; border-right-width: 1px; border-top-width: 1px; }
.feature__frame i:nth-child(3) { left: 0; bottom: 0; margin: 0 0 -12px -12px; border-left-width: 1px; border-bottom-width: 1px; }
.feature__frame i:nth-child(4) { right: 0; bottom: 0; margin: 0 -12px -12px 0; border-right-width: 1px; border-bottom-width: 1px; }
html:not(.js) .feature__frame, .no-motion .feature__frame { display: none; }
.feature__media::after, .wide__hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top, rgba(11, 11, 10, .9) 0%, rgba(11, 11, 10, .68) 30%, rgba(11, 11, 10, .3) 52%, rgba(11, 11, 10, 0) 72%);
}
.feature__text {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; pointer-events: none; isolation: isolate;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: end;
  padding-bottom: clamp(32px, 8vh, 90px);
}
.feature__text .project__num { grid-column: 1 / -1; margin-bottom: 20px; }
.feature__text .project__title { grid-column: 1 / 9; }
.feature__side { grid-column: 10 / 13; display: grid; gap: 18px; justify-items: start; padding-bottom: .6vw; pointer-events: auto; }
/* Overlay copy on the two full-bleed photos: lighter accents, a soft halo, and a local
   scrim behind the small side copy where it crosses white kit */
:is(.feature__text, .wide__overlay) .project__num { color: #ead9b4; } /* a lighter champagne: 4.5:1 over sunlit grass */
:is(.feature__text, .wide__overlay) .project__meta { color: rgba(236, 231, 221, .88); }
:is(.feature__text, .wide__overlay) :is(.project__num, .project__meta, .btn-text) { text-shadow: 0 1px 14px rgba(11, 11, 10, .6); }
:is(.feature__text, .wide__overlay) .project__title { text-shadow: 0 2px 28px rgba(11, 11, 10, .35); }
:is(.feature__side, .wide__side) { position: relative; }
:is(.feature__side, .wide__side)::before {
  content: ""; position: absolute; inset: -28px -32px -20px; z-index: -1; pointer-events: none;
  background: radial-gradient(closest-side, rgba(11, 11, 10, .5), rgba(11, 11, 10, 0));
}
:is(.feature__side, .wide__side) .project__meta span { white-space: nowrap; }

.spread { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: clamp(48px, 7vw, 110px); padding-top: clamp(90px, 12vw, 190px); align-items: start; }
.spread__a { grid-column: 1 / 8; grid-row: 1; }
.spread__b { grid-column: 9 / 13; grid-row: 1; margin-top: 18vw; }
.spread__note { grid-column: 2 / 6; grid-row: 2; align-self: center; display: grid; gap: 22px; }
.spread__quote { font: italic 400 clamp(24px, 2.4vw, 40px)/1.22 var(--serif); }
.spread__c { grid-column: 7 / 13; grid-row: 2; }

/* Project 02 — horizontal gallery (mobile-first: native swipe) */
.hscroll { padding-top: clamp(120px, 18vh, 230px); }
.hscroll__intro { display: grid; gap: 20px; justify-items: start; margin-bottom: 36px; }
.hscroll__count { margin-top: 6px; }
.hint-desk, .hint-mouse { display: none; }
.has-hpin .hint-desk { display: inline; }
.has-hpin .hint-touch { display: none; }
.hscroll__viewport {
  /* relative: absolutely positioned descendants (the .sr-only button suffixes) stay inside
     the scroller; otherwise they widen the page and phones zoom the whole site out */
  position: relative;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.hscroll__viewport::-webkit-scrollbar { display: none; }
.hscroll__viewport:focus-visible { outline-offset: -2px; }
.hscroll__track { display: flex; align-items: flex-start; gap: 14px; width: max-content; padding-left: var(--gutter-l); padding-right: var(--gutter-r); }
.hscroll__num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.hs-item { flex: 0 0 auto; width: 80vw; scroll-snap-align: center; }
/* The end card snaps to the true scroll end, so it is reachable and the bar fills */
.hs-end { flex: 0 0 auto; display: flex; align-items: center; padding: 0 14vw 0 6vw; align-self: center; scroll-snap-align: end; scroll-margin-inline-end: var(--gutter); }
.hscroll__progress { position: relative; height: 1px; margin: 26px var(--gutter-r) 0 var(--gutter-l); background: var(--hair); overflow: hidden; }
.hscroll__progress i { position: absolute; inset: 0; background: var(--fg); transform-origin: left; transform: scaleX(0); }

/* Arrow buttons: mouse users on the native (non-pinned) gallery */
.hscroll__nav { display: none; gap: 26px; font: 500 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.hscroll__btn { position: relative; min-height: 44px; padding: 10px 0; transition: opacity .4s var(--ease); }
.hscroll__btn:disabled { opacity: .35; cursor: default; }
@media (hover: hover) and (pointer: fine) {
  .js:not(.has-hpin) .hscroll__nav { display: flex; }
  .js:not(.has-hpin) .hint-touch { display: none; }
  .js:not(.has-hpin) .hint-mouse { display: inline; }
}
/* Pinned (desktop): the arrows glide the page to the neighbouring frame (main.js) */
.has-hpin .hscroll__nav { display: flex; margin-top: -6px; }

/* Desktop without the pin (reduced motion, scripts blocked, no JS): a calm
   row of images at their natural proportions with a slim scrollbar */
@media (min-width: 900px) {
  html:not(.has-hpin) .hscroll__track { align-items: center; gap: 3vw; }
  html:not(.has-hpin) .hs-item { width: auto; }
  html:not(.has-hpin) .hs-item .shot { width: auto; height: min(var(--h, 60vh), 70vh); }
  html:not(.has-hpin) .hscroll__viewport { scrollbar-width: thin; scrollbar-color: var(--hair) transparent; padding-bottom: 10px; }
  html:not(.has-hpin) .hscroll__viewport::-webkit-scrollbar { display: block; height: 6px; }
  html:not(.has-hpin) .hscroll__viewport::-webkit-scrollbar-thumb { background: var(--hair); }
}

/* Desktop: pinned, scroll-driven. overflow: clip (not a scroll container),
   so Tab can never scroll the pin sideways */
.has-hpin .hscroll__pin {
  height: 100vh; height: 100svh; overflow: hidden; overflow: clip;
  display: grid; grid-template-columns: minmax(320px, 30vw) minmax(0, 1fr); grid-template-rows: minmax(0, 1fr) auto;
}
.has-hpin .hscroll__intro {
  grid-column: 1; grid-row: 1 / 3; position: relative; z-index: 2; margin: 0;
  align-content: center; height: 100%; padding-right: 3vw; background: var(--bg); transition: background-color .9s var(--ease);
}
/* The track centres in the space below the fixed nav, and is capped by it, so the tallest
   frames never butt against or slide under the bar on 700–768px-tall screens */
.has-hpin .hscroll__viewport { grid-column: 2; grid-row: 1; overflow: visible; scroll-snap-type: none; display: flex; align-items: center; padding-top: calc(var(--nav-h-scrolled) + 2vh); }
.has-hpin .hscroll__track { height: min(78vh, calc(100svh - var(--nav-h-scrolled) - 14vh)); align-items: stretch; gap: 4.5vw; padding-left: max(4vw, env(safe-area-inset-left, 0px)); padding-right: 0; will-change: transform; }
.has-hpin .hs-item { width: auto; display: flex; flex-direction: column; align-items: flex-start; }
.has-hpin .hs-item .shot { width: auto; height: min(var(--h, 66vh), calc(100svh - var(--nav-h-scrolled) - 14vh - 40px)); }
/* "ЦРВЕНО И" keeps the panel's 3vw right margin (the photos slide under that edge) */
.has-hpin .hscroll__intro .project__title { font-size: clamp(48px, 5.8vw, 116px); max-width: 100%; }
.has-hpin .hscroll__intro > * { min-width: 0; }
.has-hpin .hs-item--top { align-self: flex-start; }
.has-hpin .hs-item--bottom { align-self: flex-end; }
.has-hpin .hs-item--center { align-self: center; }
.has-hpin .hs-item .shot__plx { inset: 0 -8%; }
.has-hpin .hscroll__progress { grid-column: 2; grid-row: 2; margin: 0 max(6vw, env(safe-area-inset-right, 0px)) 6vh 4vw; }

/* Project 03 — asymmetric masonry */
.masonry { padding-top: clamp(130px, 20vh, 250px); }
.masonry__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: clamp(60px, 9vw, 150px); align-items: start; }
.masonry__head { grid-column: 1 / 6; grid-row: 1; align-self: end; display: grid; gap: 20px; justify-items: start; padding-bottom: 2vw; }
.m1 { grid-column: 6 / 13; grid-row: 1; }
.m2 { grid-column: 1 / 6; grid-row: 2; }
.m3 { grid-column: 8 / 13; grid-row: 2; align-self: center; }
.m4 { grid-column: 3 / 8; grid-row: 3; }
.m-note { grid-column: 9 / 13; grid-row: 3; align-self: end; font: italic 400 clamp(20px, 1.8vw, 30px)/1.3 var(--serif); }
.m5 { grid-column: 1 / 5; grid-row: 4; }
.m6 { grid-column: 6 / 13; grid-row: 4; align-self: end; }
.m7 { grid-column: 7 / 12; grid-row: 5; }

/* Project 04 — wide stage + triptych */
.wide { padding-top: clamp(130px, 20vh, 250px); }
.wide__stage { position: relative; height: 100vh; height: 100svh; min-height: 560px; overflow: hidden; background: var(--black); color: var(--fg); }
.wide__hero.shot { position: absolute; inset: 0; aspect-ratio: auto; width: 100%; height: 100%; }
.wide__overlay {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3; pointer-events: none; isolation: isolate;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: end;
  padding-bottom: clamp(32px, 8vh, 90px);
}
.wide__overlay .project__num { grid-column: 1 / -1; margin-bottom: 20px; }
.wide__overlay .project__title { grid-column: 1 / 9; }
.wide__side { grid-column: 10 / 13; display: grid; gap: 18px; justify-items: start; padding-bottom: .6vw; pointer-events: auto; }
.wide__strip { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); padding-top: clamp(48px, 7vw, 110px); align-items: start; }
.ws1 { grid-column: 1 / 5; }
.ws2 { grid-column: 6 / 10; margin-top: 14vw; }
.ws3 { grid-column: 10 / 13; margin-top: 5vw; }

.work__outro { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-end; gap: 24px; padding-top: var(--section); }
.big-link { display: inline-flex; align-items: center; gap: .3em; max-width: 100%; padding-block: 6px; margin-block: -6px; font: 400 clamp(36px, 6.4vw, 120px)/1 var(--serif); letter-spacing: -.02em; }
.big-link .icon { width: .62em; height: .62em; stroke-width: 1; transition: transform .8s var(--ease); }
.big-link:focus-visible .icon { transform: translate(.08em, -.08em); }
@media (hover: hover) { .big-link:hover .icon { transform: translate(.08em, -.08em); } }

/* ---------- Services ---------- */
.services {
  position: relative; isolation: isolate;
  overflow: hidden; overflow: clip; /* clip (not hidden): the sticky background layer below needs the viewport as its scroller */
  margin-top: var(--section); padding: var(--section) 0;
  background: var(--charcoal); color: var(--fg);
}
.services__bg { position: absolute; inset: 0; z-index: -1; }
@media not all and (min-width: 1200px) and (hover: hover) { .services__bg { display: none; } } /* only used by hover rows */
/* A viewport-sized layer that travels with the list, so the whole frame (faces included)
   shows while a row is hovered, at no more than 1:1 scale */
.services__bg-in { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }
.services__bg img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transform: scale(1.08); transition: opacity 1.1s var(--ease), transform 2s var(--ease);
}
.services__bg img.is-active { opacity: .3; transform: scale(1); }
/* Keeps the photo cinematic on the left and puts the description column (right) and the
   intro (top) on near-solid charcoal, whatever the frame behind them */
.services__bg-in::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(20, 20, 18, .5) 0%, rgba(20, 20, 18, .3) 22%, rgba(20, 20, 18, .45) 52%, rgba(20, 20, 18, .9) 74%),
    linear-gradient(180deg, rgba(20, 20, 18, .6) 0, rgba(20, 20, 18, 0) 32%);
}
.services__head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: 28px; align-items: end; margin-bottom: clamp(56px, 8vw, 120px); }
.services__head .label { grid-column: 1 / -1; }
.services__title { grid-column: 1 / 8; font: 400 clamp(52px, 8vw, 150px)/.88 var(--serif); letter-spacing: -.025em; text-transform: uppercase; }
.services__intro { grid-column: 9 / 13; color: var(--fg-muted); max-width: 34ch; }

.svc-list { border-top: 1px solid var(--hair); }
.svc { border-bottom: 1px solid var(--hair); transition: opacity .6s var(--ease); }
.svc__row { display: grid; grid-template-columns: clamp(64px, 7vw, 120px) minmax(0, 1fr) 24px; align-items: center; width: 100%; padding: clamp(22px, 2.6vw, 40px) 0; }
.svc__num { display: inline-flex; gap: .8em; font: 500 12px/1 var(--sans); letter-spacing: .2em; color: var(--metal); transition: transform .8s var(--ease), opacity .6s var(--ease); }
.svc__num i { font-style: normal; color: var(--fg-muted); }
.svc__name { font: 400 clamp(32px, 4.3vw, 86px)/.98 var(--serif); letter-spacing: -.02em; text-transform: uppercase; transition: transform .9s var(--ease), opacity .6s var(--ease); }
.svc__icon { position: relative; width: 18px; height: 18px; justify-self: end; transition: transform .7s var(--ease); }
.svc__icon::before, .svc__icon::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: currentColor; }
.svc__icon::after { transform: rotate(90deg); transition: transform .7s var(--ease); }
/* Details are open by default: they only collapse once main.js can open them again
   (no JS, or a failed services script (.is-static), leaves every description visible) */
.svc__detail { display: grid; grid-template-rows: 1fr; transition: grid-template-rows .7s var(--ease); }
.svc__detail-in { overflow: hidden; min-height: 0; }
@media not all and (min-width: 1200px) and (hover: hover) {
  .js .svc-list:not(.is-static) .svc:not(.is-open) .svc__detail { grid-template-rows: 0fr; }
  /* collapsed content leaves the tab order and the accessibility tree once the height has closed */
  .js .svc-list:not(.is-static) .svc:not(.is-open) .svc__detail-in { visibility: hidden; transition: visibility 0s linear .7s; }
  /* A clipped zero-height box still counts as "near the viewport" for lazy loading, so a
     collapsed row's photo is taken out of layout (after the close animation where supported):
     it is only fetched when its row opens (main.js starts it on touch) */
  .js .svc-list:not(.is-static) .svc:not(.is-open) .svc__img { display: none; transition: display 0s .7s allow-discrete; }
}
html:not(.js) .svc__icon, .svc-list.is-static .svc__icon { display: none; }
.svc-list.is-switching :is(.svc__detail, .svc__detail-in, .svc__desc, .svc__tags, .svc__book) { transition: none !important; } /* breakpoint change: switch instantly */
.svc__img { display: block; width: 100%; aspect-ratio: 16 / 10; max-height: min(46vh, 440px); object-fit: cover; margin-bottom: 18px; }
.svc__desc { color: var(--fg-muted); max-width: 40ch; }
.svc__tags { margin-top: 12px; font: 500 10.5px/1.6 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--metal); text-wrap: balance; }
.svc__tags span { white-space: nowrap; } /* "Shot lists", "On location" never split */
.svc__book { margin: 8px 0 18px; }
.svc.is-open .svc__icon::after { transform: rotate(0deg); }
/* Accordion on tablets and small desktops: photo beside the text, so an open row stays
   about half a screen tall and the next rows remain in view */
@media (min-width: 700px) {
  @media not all and (min-width: 1200px) and (hover: hover) {
    .svc__detail-in { display: grid; grid-template-columns: minmax(0, 46%) minmax(0, 1fr); grid-template-rows: auto auto 1fr; column-gap: var(--gutter); align-items: start; }
    .svc__img { grid-column: 1; grid-row: 1 / span 3; margin-bottom: 30px; }
    .svc__desc, .svc__tags, .svc__book { grid-column: 2; }
    .svc__desc { margin-top: -.3em; }
  }
}

/* Large screens: hover rows, description reveals inline on the right */
@media (min-width: 1200px) and (hover: hover) {
  .svc { display: grid; grid-template-columns: minmax(0, 1fr) minmax(26ch, 30ch); align-items: center; column-gap: 3vw; }
  .svc__row { grid-template-columns: clamp(64px, 6vw, 110px) minmax(0, 1fr); }
  .svc__icon { display: none; }
  .svc__img { display: none; }
  .svc__book { margin: 10px 0 0; }
  html:not(.js) .svc__detail-in, .svc-list.is-static .svc__detail-in { padding-block: 22px; } /* static: every description shows */
  /* Hidden until a row is hovered or focused (main.js marks it .is-active); static without JS */
  .js .svc-list:not(.is-static) :is(.svc__desc, .svc__tags, .svc__book) { opacity: 0; transform: translateY(14px); transition: opacity .6s var(--ease), transform .8s var(--ease); }
  .js .svc-list:not(.is-static) .svc__tags { transition-delay: .06s; }
  .js .svc-list:not(.is-static) .svc__book { transition-delay: .12s; }
  /* The other rows recede, but stay readable (they are still controls): names ≥3:1, numbers ≥4.5:1 */
  .svc-list.has-active .svc:not(.is-active) .svc__name { opacity: .46; }

  .svc.is-active .svc__num { transform: translateX(16px); }
  .svc.is-active .svc__name { transform: translateX(1.8vw); }
  .js .svc-list .svc.is-active :is(.svc__desc, .svc__tags, .svc__book) { opacity: 1; transform: none; }
  .svc.is-active .svc__desc { color: var(--bone); }
  .svc.is-active .svc__tags { color: var(--metal-hi); }
}

/* ---------- About (paper chapter) ---------- */
.paper { position: relative; }
.about { padding: var(--section) 0 clamp(70px, 10vh, 140px); }
/* Closing the paper chapter on its own: a full section of paper before the dark contact */
.about:last-child { padding-bottom: var(--section); }
.about__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); align-items: start; }
.about__visual { grid-column: 1 / 7; position: sticky; top: 12vh; height: 76vh; display: flex; flex-direction: column; }
.about__frame { position: relative; flex: 1; overflow: hidden; background: #d9d3c7; }
.about__img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%);
  clip-path: inset(100% 0 0 0); transform: scale(1.14);
  transition: clip-path 1.2s var(--ease-io), transform 1.8s var(--ease);
}
.about__img[data-dir="down"] { clip-path: inset(0 0 100% 0); }
.about__img.is-prev { clip-path: inset(0 0 0 0); transform: scale(1); z-index: 1; }
.about__img.is-active { clip-path: inset(0 0 0 0); transform: scale(1); z-index: 2; }
.about__caption { display: flex; justify-content: space-between; align-items: center; gap: 16px; margin-top: 14px; font: 500 10px/1.4 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted); transition: color .9s var(--ease); }
.about__story { grid-column: 8 / 13; padding-top: 4vh; }
.about__title { margin: 26px 0 30px; font: 400 clamp(46px, 5.6vw, 106px)/.9 var(--serif); letter-spacing: -.025em; text-transform: uppercase; }
.about__lede { font: 400 clamp(20px, 1.7vw, 28px)/1.35 var(--serif); max-width: 28ch; margin-bottom: 7vh; }
.chapter { min-height: 62vh; display: flex; flex-direction: column; justify-content: center; gap: 16px; padding: 7vh 0; border-top: 1px solid var(--hair); transition: border-color .9s var(--ease); }
.chapter__num { font: italic 400 24px/1 var(--serif); color: var(--metal-ink); }
.chapter__title { font: 500 12px/1.3 var(--sans); letter-spacing: .26em; text-transform: uppercase; }
.chapter p { max-width: 42ch; font-size: clamp(16px, 1.12vw, 19px); line-height: 1.75; color: var(--fg-muted); transition: color .9s var(--ease); }
.chapter__fig { display: none; }
.chapter .about__sign { margin-top: 14px; font: italic 400 20px/1.4 var(--serif); color: var(--fg); transition: color .9s var(--ease); }

/* ---------- Testimonials ---------- */
.quotes { padding: var(--section) 0; }
.quotes__inner { position: relative; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: clamp(36px, 5vw, 64px); }
.quotes__head { grid-column: 1 / -1; display: flex; align-items: center; gap: 4px; }
.quotes__mark { grid-column: 1 / 2; grid-row: 2; font: italic 400 clamp(90px, 11vw, 200px)/.7 var(--serif); color: var(--metal-ink); transition: color .9s var(--ease); }
.quotes__stage { grid-column: 2 / 12; grid-row: 2; display: grid; }
/* One quote at a time once main.js runs the carousel; without it they simply stack */
.quote + .quote { margin-top: clamp(44px, 5vw, 80px); }
.js .quotes:not(.is-static) .quote { grid-area: 1 / 1; margin: 0; visibility: hidden; }
.js .quotes:not(.is-static) .quote.is-active, .js .quotes:not(.is-static) .quote.is-leaving { visibility: visible; }
html:not(.js) .quotes__nav, .quotes.is-static .quotes__nav, .quotes.is-single .quotes__nav { display: none; }
.quote blockquote p { font: 400 clamp(28px, 3.9vw, 68px)/1.1 var(--serif); letter-spacing: -.015em; max-width: 24ch; }
.quote figcaption { margin-top: clamp(28px, 3vw, 44px); font: 500 11px/1.5 var(--sans); letter-spacing: .24em; text-transform: uppercase; color: var(--fg-muted); transition: opacity .6s var(--ease); }
.quote figcaption span { color: var(--metal-ink); transition: color .9s var(--ease); }
.js .quotes:not(.is-static) .quote figcaption { opacity: 0; }
.js .quotes:not(.is-static) .quote.is-active figcaption { opacity: 1; transition: opacity .9s var(--ease) .45s; }
.quote .w { opacity: 0; transform: translateY(.35em); filter: blur(8px); transition: opacity .9s var(--ease), transform 1.1s var(--ease), filter .9s var(--ease); transition-delay: calc(var(--i, 0) * 22ms); }
.quote.is-active .w { opacity: 1; transform: none; filter: blur(0); }
.quote.is-leaving .w { opacity: 0; transform: translateY(-.25em); filter: blur(6px); transition-duration: .5s; transition-delay: calc(var(--i, 0) * 5ms); }
.quotes.is-static .quote .w { opacity: 1; transform: none; filter: none; }
.quotes__nav { grid-column: 2 / 12; display: flex; align-items: center; gap: 26px; font: 500 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.quotes__btn { position: relative; min-height: 44px; padding: 10px 0; } /* full-height hit area; no side padding, so the row stays aligned */
.quotes__btn::after, .viewer__btn::after, .hscroll__btn::after { content: ""; position: absolute; inset: 0 -10px; } /* ≥44px wide without moving the row */
.quotes__count { color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.quotes__bar { position: relative; flex: 0 1 260px; height: 1px; overflow: hidden; background: var(--hair); }
.quotes__bar i { position: absolute; inset: 0; background: var(--fg); transform-origin: left; transform: scaleX(0); }
.quotes__bar.is-running i { animation: qbar var(--qdur, 8s) linear forwards; }
.quotes__bar.is-paused i { animation-play-state: paused; }
@keyframes qbar { to { transform: scaleX(1); } }
.quote .quote__stars { margin-bottom: clamp(18px, 2vw, 28px); --star: 13px; }

/* ---------- Star ratings & reviews (published from the photo manager) ---------- */
.stars {
  --star: 11px; --star-gap: 3px;
  position: relative; display: inline-block; flex: none; vertical-align: middle;
  width: calc(var(--star) * 5 + var(--star-gap) * 4); height: var(--star);
}
.stars::before, .stars::after {
  content: ""; position: absolute; top: 0; left: 0; bottom: 0;
  -webkit-mask: var(--star-mask) 0 50% / calc(var(--star) + var(--star-gap)) var(--star) repeat-x;
  mask: var(--star-mask) 0 50% / calc(var(--star) + var(--star-gap)) var(--star) repeat-x;
}
.stars::before { right: 0; background: currentColor; opacity: .22; }
.stars::after {
  width: calc((var(--star) * 5 + var(--star-gap) * 4) * var(--rating, 0) / 5);
  background: var(--metal-hi);
}
:root { --star-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.8l3.1 6.6 7.2.9-5.3 5 1.4 7.1L12 17.9l-6.4 3.5 1.4-7.1-5.3-5 7.2-.9z'/%3E%3C/svg%3E"); }
.theme-light .stars::after { background: var(--metal-ink); }
@media (forced-colors: active) { .stars::before { background: CanvasText; } .stars::after { background: Highlight; } }

.review { display: grid; gap: 12px; padding: 22px 0; border-top: 1px solid var(--hair); }
.review:first-child { border-top: 0; padding-top: 0; }
.review__text { font: 400 clamp(17px, 1.25vw, 21px)/1.5 var(--serif); color: var(--fg); white-space: pre-line; }
.review__by { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; font: 500 10.5px/1.5 var(--sans); letter-spacing: .2em; text-transform: uppercase; color: var(--fg-muted); }
.review__author { color: var(--fg); }
.review__context { color: var(--metal-ink); }
.review__date { color: var(--fg-muted); }

/* ---------- Contact ---------- */
.contact {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 100vh; min-height: 100svh; display: flex; align-items: flex-end;
  background: var(--black); color: var(--fg);
}
.contact__media { position: absolute; inset: -12% 0; z-index: -2; }
.contact__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 45%; }
.contact__shade { position: absolute; inset: 0; z-index: -1; background: linear-gradient(to top, rgba(11, 11, 10, .95) 0%, rgba(11, 11, 10, .7) 48%, rgba(11, 11, 10, .8) 100%); }
.contact__inner { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gutter); row-gap: clamp(36px, 5vw, 70px); padding-block: clamp(140px, 22vh, 260px) clamp(36px, 6vh, 70px); }
.contact__inner > .label { grid-column: 1 / -1; }
.contact__title { grid-column: 1 / -1; font: 400 clamp(46px, 9vw, 172px)/.88 var(--serif); letter-spacing: -.03em; text-transform: uppercase; }
.contact__actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 14px; }
.contact__details { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; padding-top: 26px; border-top: 1px solid var(--hair); }
/* The column gap spaces an inline placeholder tag; a wrapped tag starts flush at the column edge */
.contact__details li { display: flex; flex-wrap: wrap; align-items: center; align-content: flex-start; gap: 8px 10px; min-width: 0; }
.contact__details .k { flex: 0 0 100%; font: 500 10px/1.4 var(--sans); letter-spacing: .24em; text-transform: uppercase; color: var(--fg-muted); }
.contact__details .v { min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
.contact__details a.v { position: relative; background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size .6s var(--ease); }
.contact__details a.v::after { content: ""; position: absolute; inset: -10px -4px; } /* 44px touch target, same look */
.contact__details a.v:focus-visible { background-size: 100% 1px; }
@media (hover: hover) { .contact__details a.v:hover { background-size: 100% 1px; } }

/* ---------- Footer ---------- */
.footer { overflow: hidden; padding: clamp(80px, 12vh, 140px) 0 26px; background: var(--black); color: var(--fg); }
.footer__top { display: grid; grid-template-columns: 2fr repeat(3, minmax(0, 1fr)); gap: 32px; padding-bottom: clamp(56px, 8vw, 120px); }
.footer__brand { display: flex; align-items: center; gap: 12px; font: 600 13px/1 var(--sans); letter-spacing: .32em; text-transform: uppercase; }
.footer__tag { margin-top: 14px; color: var(--fg-muted); }
.footer__k { margin-bottom: 10px; font: 500 10px/1.4 var(--sans); letter-spacing: .24em; text-transform: uppercase; color: var(--fg-muted); }
.footer__v { display: inline-block; font-size: 15px; }
a.footer__v, .footer__top-link, .menu__foot a { position: relative; display: inline-block; }
a.footer__v::after, .footer__top-link::after, .menu__foot a::after { content: ""; position: absolute; inset: -10px -4px; } /* 44px touch targets, same look */
.footer__top-link::after { inset: -15px -6px; }
.menu__foot a::after { inset: -13px -4px; }
.footer__links { display: grid; justify-items: start; gap: 10px; }
.footer__word { margin-bottom: clamp(18px, 3vw, 40px); text-align: center; white-space: nowrap; font: 400 16.4vw/.8 var(--serif); letter-spacing: -.04em; text-transform: uppercase; }
.footer__word .line { padding-bottom: .04em; }
.footer__bottom { display: flex; justify-content: space-between; gap: 16px; padding-top: 22px; border-top: 1px solid var(--hair); font: 500 10.5px/1.4 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted); }

/* ---------- Project viewer ---------- */
.viewer {
  position: fixed; inset: 0; z-index: 120;
  display: grid; grid-template-rows: auto minmax(0, 1fr) auto;
  background: var(--black); color: var(--fg);
  clip-path: inset(100% 0 0 0); visibility: hidden;
  transition: clip-path 1s var(--ease-io), visibility 0s linear 1s;
}
.viewer.is-open { clip-path: inset(0 0 0 0); visibility: visible; transition: clip-path 1s var(--ease-io), visibility 0s; }
.viewer__top { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: end; gap: 22px; padding-top: max(22px, var(--safe-t)); padding-bottom: 18px; border-bottom: 1px solid var(--hair); }
.viewer__num { font: 500 11px/1 var(--sans); letter-spacing: .24em; color: var(--metal); padding-bottom: 6px; }
.viewer__title { font: 400 clamp(26px, 3vw, 48px)/1 var(--serif); letter-spacing: -.01em; text-transform: uppercase; }
.viewer__meta { margin-top: 8px; font: 500 10px/1.4 var(--sans); letter-spacing: .22em; text-transform: uppercase; color: var(--fg-muted); }
.viewer__close { display: inline-flex; align-items: center; gap: 14px; min-height: 44px; padding: 10px 0; font: 500 11px/1.3 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.viewer__x { position: relative; width: 18px; height: 18px; }
.viewer__x::before, .viewer__x::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: currentColor; transform: rotate(45deg); transition: transform .6s var(--ease); }
.viewer__x::after { transform: rotate(-45deg); }
.viewer__close:focus-visible .viewer__x::before { transform: rotate(135deg); }
.viewer__close:focus-visible .viewer__x::after { transform: rotate(45deg); }
@media (hover: hover) {
  .viewer__close:hover .viewer__x::before { transform: rotate(135deg); }
  .viewer__close:hover .viewer__x::after { transform: rotate(45deg); }
}
.viewer--no-num .viewer__top { grid-template-columns: minmax(0, 1fr) auto; } /* gallery: no project number */
/* pinch-zoom stays available on photos; one-finger drags go to the swipe handler
   (and never chain to the locked page). While zoomed, one finger pans the photo. */
.viewer__stage { position: relative; margin: clamp(14px, 3vh, 34px) var(--gutter-r) clamp(14px, 3vh, 34px) var(--gutter-l); touch-action: pinch-zoom; }
.viewer.is-zoomed .viewer__stage { touch-action: auto; }
.viewer__slides { position: absolute; inset: 0; }
.vslide { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; clip-path: inset(0 0 0 100%); transition: clip-path 1.1s var(--ease-io); }
.viewer[data-dir="-1"] .vslide { clip-path: inset(0 100% 0 0); }
.vslide:not(.is-current):not(.is-prev) { transition: none; }
.viewer .vslide.is-prev { clip-path: inset(0 0 0 0); z-index: 1; }
.viewer .vslide.is-current { clip-path: inset(0 0 0 0); z-index: 2; }
/* The image box always fills the stage; contain keeps the whole frame visible,
   so the displayed size never depends on srcset descriptors */
.vslide img { width: 100%; height: 100%; max-width: none; object-fit: contain; transform: scale(1.08); transition: transform 1.6s var(--ease); }
.vslide.is-current img, .vslide.is-prev img { transform: none; }
.viewer__hit { position: absolute; top: 0; bottom: 0; z-index: 3; width: 50%; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.viewer__hit--prev { left: 0; }
.viewer__hit--next { right: 0; }
.viewer__bottom { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 14px 24px; padding-bottom: max(18px, env(safe-area-inset-bottom)); }
.viewer__cap { color: var(--fg-muted); font-size: 14px; }
.viewer__ctrl { display: flex; align-items: center; gap: 22px; font: 500 11px/1 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.viewer__btn { position: relative; min-height: 44px; padding: 10px 0; }
.viewer__count { color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.viewer__thumbs { grid-column: 1 / -1; display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.viewer__thumbs::-webkit-scrollbar { display: none; }
.vthumb { position: relative; flex: 0 0 auto; width: 76px; aspect-ratio: 3 / 2; overflow: hidden; opacity: .38; transition: opacity .4s var(--ease); }
.vthumb::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--bone); transform: scaleX(0); transition: transform .6s var(--ease); }
.vthumb img { width: 100%; height: 100%; object-fit: cover; }
@media (hover: hover) { .vthumb:hover { opacity: .75; } }
.vthumb.is-active { opacity: 1; }
.vthumb.is-active::after { transform: none; }
/* Focus ring drawn inside the thumbnail: the scrolling strip would clip an outer one */
.vthumb:focus-visible { opacity: 1; outline: 2px solid var(--metal-hi); outline-offset: -2px; }
.vthumb:focus-visible::after { transform: none; }

/* Reviews & comments drawer (only shown when the current photo has any) */
.viewer__reviews-toggle[aria-expanded="true"] { color: var(--metal-hi); }
.viewer__reviews {
  position: absolute; z-index: 5; top: 0; right: 0; bottom: 0; width: min(400px, 100%);
  display: grid; grid-template-rows: auto auto minmax(0, 1fr);
  padding: 22px 28px 0; background: rgba(20, 20, 18, .97); border-left: 1px solid var(--hair);
  transform: translate3d(104%, 0, 0); transition: transform .5s var(--ease-io);
}
.viewer.reviews-open .viewer__reviews { transform: none; }
.viewer__reviews[hidden] { display: none; }
.viewer__reviews-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--hair); }
.viewer__reviews-title { font: 500 11px/1.3 var(--sans); letter-spacing: .24em; text-transform: uppercase; }
.viewer__reviews-title:focus { outline: none; }
.viewer__reviews-title:focus-visible { outline: 2px solid var(--focus); outline-offset: 6px; }
.viewer__reviews-close { position: relative; display: grid; place-items: center; width: 44px; height: 44px; margin-right: -13px; }
@media (hover: hover) {
  .viewer__reviews-close:hover .viewer__x::before { transform: rotate(135deg); }
  .viewer__reviews-close:hover .viewer__x::after { transform: rotate(45deg); }
}
.viewer__reviews-summary { display: flex; align-items: center; gap: 12px; padding-top: 16px; font: 500 10.5px/1.4 var(--sans); letter-spacing: .2em; text-transform: uppercase; color: var(--fg-muted); }
.viewer__reviews-summary[hidden] { display: none; }
.viewer__reviews-summary .stars { --star: 13px; }
.viewer__reviews-list { overflow-y: auto; overscroll-behavior: contain; padding: 18px 0 28px; scrollbar-width: thin; scrollbar-color: var(--hair) transparent; }
/* Phones: a bottom sheet over the photo */
@media not all and (min-width: 600px) {
  .viewer__reviews { top: auto; left: 0; width: 100%; max-height: 74%; padding: 16px 20px 0; border-left: 0; border-top: 1px solid var(--hair); transform: translate3d(0, 104%, 0); }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

/* Tablet & small desktop. Breakpoints are written as exact complements of the
   min-width queries (also used by main.js) so fractional widths such as
   899.5px under browser zoom never fall between two layouts. */
@media not all and (min-width: 1100px) {
  .hero { --scrim: calc(var(--hero-bottom) + 1.68 * clamp(64px, 11.4vw, 232px) + 320px); } /* the side copy moves under the title */
  .hero__content { grid-template-columns: minmax(0, 1fr); }
  .hero__side { width: auto; display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 32px; padding: 0; }
  .hero__statement { margin: 0; }
}
/* Below 1200px the side copy of the full-bleed projects takes its own row under the title
   (three narrow columns would wrap the meta onto the subject) */
@media not all and (min-width: 1200px) {
  .feature__text .project__title, .wide__overlay .project__title { grid-column: 1 / -1; }
  .feature__side, .wide__side { grid-column: 1 / -1; margin-top: 22px; }
  :is(.feature__side, .wide__side)::before { display: none; }
}
/* Project 04 on landscape screens: the kicker, the ball and his planted foot fill the left
   half of the frame, the right half is open pitch — the copy moves there (a mirror of
   Project 01), so "KICK" no longer sits on the ball */
@media (min-width: 900px) {
  .wide__overlay .project__num { justify-self: end; }
  .wide__overlay .project__title { grid-column: 5 / -1; justify-self: end; text-align: right; }
  .wide__overlay .project__title .line--indent { padding-left: 0; }
  .wide__overlay .project__title .line:first-child { padding-right: 1.4em; }
  .wide__side { grid-column: 7 / -1; justify-items: end; text-align: right; margin-top: 24px; }
  .wide__side .project__meta { justify-content: flex-end; }
  .wide__side::before { display: block; inset: -30px -40px -24px; }
}


/* Below desktop: dedicated touch-first layout */
@media not all and (min-width: 900px) {
  :root { --nav-h: 64px; --nav-h-scrolled: 56px; }
  .nav__links, .nav__cta { display: none; }
  .nav__menu { display: inline-flex; }
  /* Without JS the menu can't open: show the links themselves, compactly */
  html:not(.js) .nav__links { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 16px; }
  html:not(.js) .nav__menu, html:not(.js) .nav__rest { display: none; }

  .intro__line--b { padding-left: 8%; }
  .intro__line--c { padding-left: 0; }
  .intro__line--d { padding-left: 10%; }
  .intro__body { grid-column: 1 / -1; grid-template-columns: minmax(0, .9fr) minmax(0, 1fr); }

  .work__intro { grid-column: 1 / -1; }
  .wi { grid-template-columns: 44px minmax(0, 1fr); row-gap: 6px; }
  .wi__thumb { display: none; }
  .wi__cat { grid-column: 2; }
  .wi__year { display: none; }

  .feature__pin { height: 170vh; }
  /* The overlay copy covers half the photo on phones: a scrim tied to the text block itself
     (not to a percentage of the photo), so the number, title and meta never sit on white kit */
  :is(.feature__text, .wide__overlay)::before {
    content: ""; position: absolute; left: 0; right: 0; top: -110px; bottom: 0; z-index: -1; pointer-events: none;
    background: linear-gradient(to top, rgba(11, 11, 10, .9) 0%, rgba(11, 11, 10, .8) 55%, rgba(11, 11, 10, .45) 80%, rgba(11, 11, 10, 0) 100%);
  }

  .spread { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .spread__a { grid-column: 1 / -1; }
  .spread__b { grid-column: 2 / -1; grid-row: 2; margin-top: 0; }
  .spread__note { grid-column: 1 / -1; grid-row: 3; }
  .spread__c { grid-column: 1 / -1; grid-row: 4; }

  .hs-item .shot { width: 100%; }

  .masonry__grid { grid-template-columns: repeat(6, minmax(0, 1fr)); row-gap: 56px; }
  .masonry__head, .m1, .m2, .m3, .m4, .m-note, .m5, .m6, .m7 { grid-row: auto; align-self: start; }
  .masonry__head { grid-column: 1 / -1; padding: 0; }
  .m1 { grid-column: 1 / -1; }
  .m2 { grid-column: 1 / 5; }
  .m3 { grid-column: 2 / -1; }
  .m4 { grid-column: 1 / -1; }
  .m-note { grid-column: 1 / -1; }
  .m5 { grid-column: 1 / 5; }
  .m6 { grid-column: 2 / -1; }
  .m7 { grid-column: 1 / -1; }

  /* The triptych keeps its reading order (03, 04, 06) in a staggered single column */
  .wide__strip { grid-template-columns: repeat(6, minmax(0, 1fr)); row-gap: 48px; }
  .ws1 { grid-column: 1 / 5; margin-top: 0; }
  .ws2 { grid-column: 1 / -1; margin-top: 0; }
  .ws3 { grid-column: 3 / -1; margin-top: 0; }

  .services__title, .services__intro { grid-column: 1 / -1; }

  .about__visual { display: none; }
  .about__story { grid-column: 1 / -1; padding-top: 0; }
  .about__lede { margin-bottom: 40px; }
  .chapter { min-height: 0; padding: 40px 0 48px; }
  .chapter__fig { display: block; aspect-ratio: 4 / 5; overflow: hidden; margin-bottom: 14px; background: #d9d3c7; }
  .chapter__fig img { width: 100%; height: 100%; object-fit: cover; }

  .quotes__mark { grid-column: 1 / -1; grid-row: 2; }
  .quotes__stage { grid-column: 1 / -1; grid-row: 3; }
  .quotes__nav { grid-column: 1 / -1; flex-wrap: wrap; }

  .contact__details { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 26px; }

  .footer__top { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 40px; }
  .footer__col--brand { grid-column: 1 / -1; }
}

/* Phones */
@media not all and (min-width: 600px) {
  .hero { min-height: 560px; --hero-bottom: 88px; --scrim: calc(88px + 51.6vw + 440px); }
  /* The 9:16 crop puts the leaping player's head in the top ~90px (the original has no
     headroom above it): a lighter, shorter top band keeps it readable under the nav */
  .hero__shade {
    background:
      linear-gradient(180deg, rgba(11, 11, 10, .5) 0, rgba(11, 11, 10, .2) 60px, rgba(11, 11, 10, 0) 130px),
      linear-gradient(0deg, rgba(11, 11, 10, .9) 0, rgba(11, 11, 10, .66) calc(var(--scrim) * .45), rgba(11, 11, 10, .4) calc(var(--scrim) * .74), rgba(11, 11, 10, 0) var(--scrim));
  }
  .hero__content { row-gap: 26px; }
  .hero__eyebrow { flex-direction: column; gap: 4px; font-size: 10px; }
  .hero__title { font-size: 20vw; line-height: .86; }
  .hero__title .l1, .hero__title .l2 { display: block; }
  .hero__title .l1 { margin-right: 0; }
  .hero__title .l2 { padding-left: .6em; }
  .hero__title .l3 { padding-left: 0; }
  .hero__statement { font-size: 22px; }
  .hero__caption { display: none; }
  .menu__foot { flex-direction: column; gap: 6px; }

  .intro__title { font-size: clamp(38px, 11.6vw, 70px); }
  .intro__body { grid-template-columns: minmax(0, 1fr); row-gap: 40px; }
  .intro__fig { width: 70%; }

  .work__title { font-size: 19vw; }
  /* "@mdfocusstudio ↗" fits a 320px screen on one line */
  .big-link { font-size: clamp(28px, 9.2vw, 56px); }
  .line--indent { padding-left: .9em; }
  .line--indent-2 { padding-left: 1.2em; }

  /* "ПРЕСУДНАТА", the longest title word, fits a 320px screen inside its reveal mask */
  .project__title { font-size: clamp(40px, 13.6vw, 90px); }
  /* …and the indented italic "ПРАВИМЕ" too */
  .services__title { font-size: clamp(40px, 13.2vw, 52px); }
  .hs-item { width: 82vw; }

  /* "PHOTOGRAPHY" clears the + icon down to 320px */
  .svc__name { font-size: clamp(24px, 8vw, 48px); overflow-wrap: anywhere; }
  .svc__row { grid-template-columns: 52px minmax(0, 1fr) 20px; column-gap: 8px; }

  .about__title { font-size: clamp(46px, 14vw, 80px); }

  .quote blockquote p { font-size: clamp(26px, 7.6vw, 40px); }
  .quotes__bar { flex-basis: 100%; order: 4; }

  .contact__title { font-size: clamp(32px, 11vw, 70px); } /* "remembering." fits its line down to 320px */
  .contact__title .line--indent { padding-left: .5em; }
  .contact__title .line--indent-2 { padding-left: .25em; }
  .contact__actions { flex-direction: column; align-items: stretch; }
  .btn { width: 100%; }
  .contact__details { grid-template-columns: minmax(0, 1fr); }

  .footer__word { font-size: 17vw; }
  .footer__bottom { flex-direction: column; }

  .viewer__top { grid-template-columns: minmax(0, 1fr) auto; }
  .viewer__num { display: none; }
  .viewer__bottom { grid-template-columns: minmax(0, 1fr); }
  .viewer__ctrl { justify-content: space-between; }
  .viewer__thumbs { display: none; }
  .viewer__btn { min-height: 44px; padding-inline: 4px; }
}

/* Tablets in portrait (600–899px): a designed middle tier rather than a stretched phone —
   chapters set image beside text, portrait frames step back from full width, the project
   index gets its year column back */
@media (min-width: 600px) and (orientation: portrait) {
  @media not all and (min-width: 900px) {
    .wi { grid-template-columns: 56px minmax(0, 1fr) auto 64px; column-gap: 24px; }
    .wi__thumb { display: none; }
    .wi__cat { grid-column: auto; }
    .wi__year { display: block; }
    .hs-item { width: 62vw; }
    .spread__b { grid-column: 3 / -1; }
    .m2, .m5 { grid-column: 1 / 4; }
    .ws1 { grid-column: 1 / 4; }
    .ws3 { grid-column: 3 / -1; }
    .chapter { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1fr); grid-auto-rows: min-content; column-gap: var(--gutter); row-gap: 16px; align-content: start; }
    .chapter__fig { grid-column: 1; grid-row: 1 / span 6; margin: 0; }
    .chapter > :not(.chapter__fig) { grid-column: 2; }
    .chapter > .chapter__num { margin-top: 4px; }
  }
}

/* Phones and small tablets on their side: media is sized from the screen height, so a
   whole frame (and its caption) is visible at once instead of overflowing a ~390px screen */
@media (orientation: landscape) {
  @media not all and (min-width: 900px) {
    .shot:not(.feature__media):not(.wide__hero) { width: min(100%, calc(78svh * (var(--ar, 3 / 2)))); }
    .hs-item { width: auto; }
    .hs-item .shot { width: auto; height: min(70svh, 110vw); }
    .chapter { display: grid; grid-template-columns: minmax(0, .7fr) minmax(0, 1fr); grid-auto-rows: min-content; column-gap: var(--gutter); row-gap: 14px; align-content: start; }
    .chapter__fig { grid-column: 1; grid-row: 1 / span 6; margin: 0; max-height: 80svh; }
    .chapter > :not(.chapter__fig) { grid-column: 2; }
    .svc__img { max-height: 60svh; }
  }
}

/* Narrow phones (320–359px): the wordmark folds to "MD" (as it does on scroll), so the
   Menu / Close button always fits inside the gutter; buttons tighten so labels stay on one line */
@media not all and (min-width: 360px) {
  .nav__rest { max-width: 0; opacity: 0; }
  .nav__bar { gap: 12px; }
  .work__title { font-size: 18.4vw; }
  .btn { padding-inline: 18px; letter-spacing: .16em; }
  .btn__label { white-space: nowrap; }
}

/* Short landscape screens (phones on their side): the hero and the Project 04 stage fit the
   screen instead of a 560–600px minimum, so the title and call to action start above the fold */
@media (orientation: landscape) and (max-height: 500px) {
  .hero, .wide__stage { min-height: 0; }
  .hero { --hero-bottom: 52px; --scrim: calc(52px + 1.68 * min(11.4vw, 21svh) + 220px); }
  .hero__title { font-size: min(11.4vw, 21svh); }
  .hero__content { row-gap: 12px; }
  .hero__eyebrow { gap: 4px 28px; }
  .hero__foot { bottom: max(14px, var(--safe-b)); }
  .hero__caption { display: none; }
  .feature__text, .wide__overlay { padding-bottom: 20px; }
  .feature__text .project__num, .wide__overlay .project__num { margin-bottom: 10px; }
  .feature__side, .wide__side { margin-top: 12px; gap: 10px; }
  /* the menu fits five links and its footer in ~390px; it scrolls if zoomed further */
  .menu { padding-top: calc(var(--nav-h) + var(--safe-t) + 12px); gap: 20px; }
  .menu__link { font-size: clamp(28px, 10svh, 64px); }
}

/* Portrait screens use the art-directed 9:16 hero crop (<source media="(max-aspect-ratio: 4/5)">):
   less overscan so more of the frame shows, and a focal point that keeps the
   leaping #11, the tackler's face and the ball in view */
@media (max-aspect-ratio: 4/5) {
  .hero__shift { inset: 0; }
  .hero__lens { transform: scale(1.04); transform-origin: 46% 24%; } /* 1.04: keep main.js restScale() in step */
  .hero__img, .hero__soft { object-position: 46% 20%; }
  /* The Project 01 feature and Project 04 stage switch to their own 9:16 crops too:
     --pos-p (inline, next to the markup) frames each crop */
  .feature__media img, .wide__hero img { object-position: var(--pos-p, var(--pos, 50% 50%)); }
}

/* Short screens (phones in landscape): give the photo the room */
@media (max-height: 500px) {
  .viewer__thumbs, .viewer__meta { display: none; }
  .viewer__top { padding-block: 8px; align-items: center; }
  .viewer__title { font-size: 20px; }
  .viewer__num { padding-bottom: 0; }
  .viewer__stage { margin-block: 6px; }
  .viewer__bottom { padding-bottom: max(8px, env(safe-area-inset-bottom)); gap: 4px 24px; }
  .viewer__btn, .viewer__close { padding-block: 6px; }
}

/* ---------- Display type optical size ----------
   Left to itself the browser picks opsz = font size (capped at 96), and Bodoni Moda's
   large masters have hairlines so fine that at 100–230px the thin M stem, the H bar and
   the N/K/W diagonals break up ("VID FOCUS", "SOMETHIIIG"). Giant lines use a low optical
   size (18: still a Didone, every stroke solid at DPR 1); mid sizes keep 24–36.
   Kept last so the `font` shorthands above don't override it. */
.hero__title, .intro__title, .work__title, .project__title, .services__title,
.about__title, .contact__title, .footer__word, .big-link, .quotes__mark,
.gallery .gallery__title {
  font-variation-settings: "opsz" 18;
}
.svc__name, .menu__link, .quote blockquote p { font-variation-settings: "opsz" 24; }
.loader__count, .wi__title, .viewer__title, .spread__quote, .m-note { font-variation-settings: "opsz" 36; }

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
  }
  .grain::before, .hero__scroll i::after { animation: none; }
  .hero__lens { transform: none; }
}

/* ---------- Forced colours (Windows High Contrast) ----------
   Strokes drawn with background-color are repainted as Canvas and vanish: give them
   system colours. Decorative layers go; focus rings use the system highlight. */
@media (forced-colors: active) {
  .nav__burger i, .svc__icon::before, .svc__icon::after, .viewer__x::before, .viewer__x::after,
  .btn-text__line, .link-cta__line, .hscroll__progress i, .quotes__bar i, .vthumb::after, .hero__scroll i::after {
    forced-color-adjust: none; background-color: CanvasText;
  }
  .hscroll__progress, .quotes__bar, .hero__scroll i { forced-color-adjust: none; background-color: GrayText; }
  .nav__link::before { forced-color-adjust: none; background-color: LinkText; }
  .vthumb.is-active::after { background-color: Highlight; }
  .nav__bar::before { forced-color-adjust: none; background: Canvas; }
  .cursor, .grain, .shot::before, .btn::before { display: none; }
  .shot:focus-visible, .vthumb:focus-visible { outline: 3px solid Highlight; outline-offset: -3px; }
  .btn, .nav__cta { border-color: ButtonText; }
  .vthumb, .svc-list.has-active .svc:not(.is-active) :is(.svc__name, .svc__num) { opacity: 1; }
}

/* ---------- Print ----------
   A clean, ink-friendly document: dark type on white, every image and line revealed,
   pinned and full-screen stages flattened into the flow, no chrome. Author !important
   rules outrank the inline styles GSAP leaves behind. */
@media print {
  @page { margin: 14mm 12mm; }
  html { -webkit-print-color-adjust: economy; print-color-adjust: economy; }
  :root, html.theme-light, .hero, .feature__sticky, .wide__stage, .services, .contact, .footer, .paper {
    --bg: #fff; --fg: #111; --fg-muted: #4a4741; --hair: rgba(0, 0, 0, .2);
    --bone: #111; --metal: #6f5a32; --metal-hi: #6f5a32; --metal-ink: #6f5a32;
    --section: 12mm; --gutter: 0px; --gutter-l: 0px; --gutter-r: 0px;
  }
  html, body { background: #fff !important; color: #111 !important; }
  body { font-size: 10.5pt; line-height: 1.5; }

  .grain, .cursor, .loader, .nav, .skip, .menu, .viewer, .sprite, .wi__thumb,
  .hero__foot, .hero__shade, .hero__veil, .hero__dim, .hero__soft, .contact__media, .contact__shade,
  .services__bg, .hscroll__progress, .hscroll__nav, .hscroll__hint, .hs-end, .quotes__nav, .quotes__mark,
  .shot__info, .shot::before, .svc__icon, .svc__img, .svc__book, .about__visual, .chapter__fig,
  .gallery__filters, .gallery__foot, .contact__actions, .footer__top-link, .feature__side .btn-text,
  .wide__side .btn-text, .hscroll__intro .btn-text, .masonry__head .btn-text, .roll__clone,
  :is(.feature__text, .wide__overlay, .feature__side, .wide__side)::before,
  .feature__media::after, .wide__hero::after { display: none !important; }

  [data-reveal], [data-reveal-mask], [data-reveal-lines], [data-float], .char, .w, .word, .line__in, .roll__in,
  .shot, .shot__plx, .shot__hover, .shot img, .hero__media, .hero__shift, .hero__lens, .hero__img,
  .hero__content, .hero__content *, .feature__media, .wide__hero, .feature__text *, .wide__overlay *,
  .hscroll__track, .hs-item, .cap, .quote, .quote *, .about__img, .svc__detail-in, .svc__desc, .svc__tags {
    opacity: 1 !important; visibility: visible !important; transform: none !important;
    clip-path: none !important; filter: none !important; text-shadow: none !important;
  }

  /* Flatten full-screen and pinned stages */
  .hero, .wide__stage, .feature__sticky, .contact { height: auto !important; min-height: 0 !important; overflow: visible !important; background: none !important; display: block !important; }
  .hero__media { position: relative !important; inset: auto !important; height: 95mm; overflow: hidden; }
  .hero__shift, .hero__lens { inset: 0 !important; }
  .hero__content, .feature__text, .wide__overlay { position: static !important; display: block !important; padding: 6mm 0 0 !important; }
  .hero__title { font-size: 54pt; }
  .hero__side { width: auto; padding: 4mm 0 0; }
  .feature__pin, .pin-spacer, .hscroll__pin, .has-hpin .hscroll__pin {
    position: static !important; display: block !important; height: auto !important; min-height: 0 !important;
    padding: 0 !important; top: auto !important; left: auto !important; width: auto !important; max-width: none !important; transform: none !important;
  }
  .feature__media.shot, .wide__hero.shot { position: relative !important; inset: auto !important; height: 105mm !important; }
  .hscroll__intro { height: auto !important; padding: 0 !important; margin-bottom: 5mm !important; }
  .hscroll__viewport { overflow: visible !important; padding: 0 !important; display: block !important; }
  .hscroll__track { display: grid !important; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 5mm; width: auto !important; height: auto !important; padding: 0 !important; }
  .hs-item, .has-hpin .hs-item { width: auto !important; display: block !important; }
  .hs-item .shot, .has-hpin .hs-item .shot { width: 100% !important; height: auto !important; }

  /* Every description and every testimonial, stacked */
  .services { margin: 0 !important; padding: var(--section) 0 !important; }
  .svc__detail { grid-template-rows: 1fr !important; }
  .svc__detail-in { padding-bottom: 4mm; }
  .svc__name { font-size: 22pt; }
  .quote { grid-area: auto !important; }
  .quote + .quote { margin-top: 8mm !important; }
  .chapter { min-height: 0 !important; padding: 4mm 0 !important; }
  .about__story { grid-column: 1 / -1 !important; }
  .contact__inner { padding: 8mm 0 0 !important; }
  .footer { padding: 8mm 0 0 !important; }
  .footer__word { font-size: 48pt; margin: 6mm 0; }
  .contact__details a.v[href^="http"]::after, a.footer__v[href^="http"]::after { content: " (" attr(href) ")"; position: static; font-size: 8pt; color: #4a4741; }

  .work__index { margin-top: 8mm; }
  .intro, .work, .feature, .hscroll, .masonry, .wide, .quotes, .about { padding-top: var(--section) !important; margin-top: 0 !important; }
  img { max-width: 100% !important; }
  figure, .chapter, .quote, .svc, .hs-item, .wi { break-inside: avoid; }
  h1, h2, h3, .label, .project__num { break-after: avoid; }
}
