@import url('fonts.css');

/* ══════════════════════════════════════════════════════════════════════
   GALIP KAYA — design system
   Palette: warm near-black, bone white, bej.
   Type: the platform grotesque — SF Pro on Apple, Montserrat elsewhere.
   ══════════════════════════════════════════════════════════════════ */

:root {
  /* ink & paper */
  --ink: #100e0c;
  --ink-2: #26221e;
  --ink-3: #4a443c;
  --paper: #fbf9f6;
  --paper-2: #f4efe8;
  --bej: #e6dccd;
  --bej-2: #d5c7b1;
  --bronze: #9c866a;

  /* semantic — flipped inside .invert */
  --bg: var(--paper);
  --fg: var(--ink);
  --fg-mute: #6f675d;
  --rule: rgb(16 14 12 / 13%);
  --rule-strong: rgb(16 14 12 / 26%);
  --accent: var(--bronze);

  /*
   * One family for the whole site — no serif anywhere.
   * `-apple-system` / `BlinkMacSystemFont` are what actually resolve to SF Pro
   * in a browser; the SF names after them are for the rare engine that matches
   * by family name. Montserrat sits further down as the self-hosted fallback so
   * Windows and Android get a consistent face instead of dropping to Arial —
   * and because it is never matched on Apple devices, it is never downloaded
   * there either.
   */
  --f-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text',
    'Helvetica Neue', 'Montserrat', Helvetica, Arial, sans-serif;
  --f-display: var(--f-sans);

  /* Sans sets visually larger than the serif did at the same size, so the
     display steps come down and take negative tracking. */
  --t-hero: clamp(2.25rem, 6.4vw, 5.75rem);
  --t-h1: clamp(2rem, 5vw, 4.25rem);
  --t-h2: clamp(1.65rem, 3.4vw, 3rem);
  --t-h3: clamp(1.15rem, 1.9vw, 1.6rem);
  --t-lead: clamp(1.15rem, 2vw, 1.6rem);
  --t-body: clamp(0.9rem, 1vw, 1rem);
  --t-small: 0.78125rem;
  --t-micro: 0.65625rem;

  /* layout */
  --gutter: clamp(1.25rem, 5vw, 5.5rem);
  --max: 1680px;
  --measure: 34em;
  --section: clamp(4.5rem, 11vw, 11rem);
  --header-h: clamp(64px, 8vw, 92px);

  /* motion */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io: cubic-bezier(0.65, 0.05, 0.36, 1);
  /* --ease front-loads almost all of its travel into the first quarter, which
     on a slow image zoom reads as a snap. This one moves evenly. */
  --ease-zoom: cubic-bezier(0.38, 0.12, 0.24, 1);
  --dur: 0.7s;
}

.invert {
  --bg: var(--ink);
  --fg: var(--paper);
  --fg-mute: #a49b8e;
  --rule: rgb(251 249 246 / 16%);
  --rule-strong: rgb(251 249 246 / 34%);
  --accent: #c2ab89;
  color-scheme: dark;
}

/* ─────────────────────────────────────────────────────────── reset ── */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scrollbar-color: var(--bej-2) var(--paper-2);
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 300;
  line-height: 1.72;
  letter-spacing: 0.004em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  text-rendering: optimizeLegibility;
}

body.is-locked { overflow: hidden; }

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

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

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

button { background: none; border: 0; cursor: pointer; padding: 0; }

h1, h2, h3, h4 { font-weight: 300; line-height: 1.06; }

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

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 1px;
}

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

.skip-link {
  position: fixed;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  z-index: 200;
  padding: 0.75rem 1.25rem;
  background: var(--ink);
  color: var(--paper);
  transform: translateY(-160%);
  transition: transform 0.25s var(--ease);
  font-size: var(--t-small);
}
.skip-link:focus-visible { transform: none; }

/* ─────────────────────────────────────────────────── typography ── */

/* Display sizes in a grotesque need weight to hold the page and tight tracking
   so large settings do not read as loose. */
.display { font-family: var(--f-display); font-weight: 500; letter-spacing: -0.028em; }
.display em { font-style: italic; }

.t-hero  { font-family: var(--f-display); font-weight: 500; font-size: var(--t-hero); line-height: 1.04; letter-spacing: -0.035em; }
.t-h1    { font-family: var(--f-display); font-weight: 500; font-size: var(--t-h1);   line-height: 1.06; letter-spacing: -0.03em; }
.t-h2    { font-family: var(--f-display); font-weight: 500; font-size: var(--t-h2);   line-height: 1.09; letter-spacing: -0.028em; }
.t-h3    { font-family: var(--f-display); font-weight: 500; font-size: var(--t-h3);   line-height: 1.22; letter-spacing: -0.02em; }

/* Reading-size intro copy: lighter and looser than the display steps. */
.t-lead {
  font-family: var(--f-sans);
  font-size: clamp(1rem, 1.35vw, 1.1875rem);
  font-weight: 300;
  line-height: 1.66;
  letter-spacing: 0.004em;
}

.t-quote {
  font-family: var(--f-display);
  font-weight: 400;
  font-size: var(--t-lead);
  line-height: 1.42;
  letter-spacing: -0.022em;
}

.eyebrow {
  font-size: var(--t-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--fg-mute);
  /* Deliberately not flex: the rule is an inline-block so a long kicker wraps
     as ordinary text instead of overflowing (or pushing the rule onto its own
     line, which is what flex-wrap did). */
  display: block;
  line-height: 1.55;
}
.eyebrow::before {
  content: '';
  display: inline-block;
  vertical-align: middle;
  width: clamp(20px, 4vw, 56px);
  height: 1px;
  margin-inline-end: 0.9em;
  margin-block-end: 0.15em;
  background: currentColor;
  opacity: 0.55;
}
.eyebrow--plain::before { display: none; }

.prose > * + * { margin-block-start: 1.15em; }
.prose p { max-width: var(--measure); color: var(--fg); }
.prose--mute p { color: var(--fg-mute); }

.text-mute { color: var(--fg-mute); }

/* ─────────────────────────────────────────────────────── layout ── */

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

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

.section { padding-block: var(--section); }
.section--tight { padding-block: clamp(3rem, 7vw, 6.5rem); }
.section--flush-top { padding-block-start: 0; }

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

.grid { display: grid; gap: clamp(1.5rem, 3vw, 3rem); }

/* ─────────────────────────────────────────────────────── header ── */

.header {
  position: fixed;
  inset: 0 0 auto;
  /* above the overlay menu (95) — the Close control lives in the header, so
     it has to stay reachable while the menu is open */
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  isolation: isolate;
  transition: background 0.5s var(--ease), color 0.5s var(--ease), box-shadow 0.5s var(--ease);
}

.header__inner {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(0.75rem, 2vw, 1.5rem);
  min-width: 0;
}

/* Over the hero the header is transparent and light, so it needs its own
   wash — several of the hero images are bright interiors and a plain white
   logo simply disappears into them. */
.header[data-mode='over'] {
  color: var(--paper);
  text-shadow: 0 1px 14px rgb(16 14 12 / 55%);
}
.header[data-mode='over']::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: calc(var(--header-h) * 2.1);
  background: linear-gradient(rgb(16 14 12 / 48%), rgb(16 14 12 / 0%));
  pointer-events: none;
  z-index: -1;
}
.header[data-mode='over'] .brand__mark,
.header[data-mode='over'] .brand__type {
  filter: drop-shadow(0 1px 10px rgb(16 14 12 / 55%));
}
.header[data-mode='solid'] {
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  color: var(--ink);
  box-shadow: 0 1px 0 rgb(16 14 12 / 9%);
}
/* while the overlay is open the header sits on the ink panel, so it drops its
   solid paper background whatever mode it was in */
body.is-menu .header {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  color: var(--paper);
  text-shadow: none;
}
body.is-menu .header::before { opacity: 0; }
body.is-menu .header .brand__mark,
body.is-menu .header .brand__type { filter: none; }

.header.is-hidden { transform: translateY(-102%); transition: transform 0.45s var(--ease-io), background 0.5s var(--ease); }
.header { transform: translateY(0); transition: transform 0.45s var(--ease-io), background 0.5s var(--ease), color 0.5s var(--ease), box-shadow 0.5s var(--ease); }

.brand {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.4vw, 1rem);
  min-width: 0;
  flex: 0 1 auto;
}
.brand__mark { width: clamp(17px, 2.2vw, 23px); flex: none; color: currentColor; }
.brand__type { width: clamp(104px, 13vw, 152px); flex: 0 1 auto; color: currentColor; }

.nav-toggle,
.nav { flex: none; }
.brand:hover .brand__mark { animation: markNudge 0.6s var(--ease); }

@keyframes markNudge {
  50% { transform: translateX(3px) rotate(-4deg); }
}

.nav {
  display: flex;
  align-items: center;
  gap: clamp(1.5rem, 2.6vw, 2.75rem);
}

.nav__link {
  font-size: var(--t-small);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 300;
  position: relative;
  padding-block: 0.35rem;
  white-space: nowrap;
}
.nav__link::after {
  content: '';
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: 100% 50%;
  transition: transform 0.5s var(--ease);
}
.nav__link:hover::after,
.nav__link[aria-current]::after { transform: scaleX(1); transform-origin: 0 50%; }

.nav-toggle {
  display: none;
  align-items: center;
  gap: 0.7rem;
  font-size: var(--t-micro);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 0.5rem 0;
}
.nav-toggle__bars { width: 24px; display: grid; gap: 5px; }
.nav-toggle__bars span {
  height: 1px;
  background: currentColor;
  transition: transform 0.45s var(--ease), opacity 0.3s;
}
body.is-menu .nav-toggle__bars span:first-child { transform: translateY(3px) rotate(45deg); }
body.is-menu .nav-toggle__bars span:last-child { transform: translateY(-3px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav { display: none; }
  .nav-toggle { display: flex; }
}

/* ───────────────────────────────────────────────── menu overlay ── */

.menu {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: var(--ink);
  color: var(--paper);
  display: grid;
  grid-template-rows: var(--header-h) 1fr auto;
  padding-inline: var(--gutter);
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.8s var(--ease);
  pointer-events: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}
body.is-menu .menu { clip-path: inset(0 0 0 0); pointer-events: auto; }

.menu__nav {
  align-self: center;
  display: grid;
  gap: clamp(0.1rem, 1vw, 0.4rem);
  padding-block: 2rem;
}
.menu__link {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(2rem, 8.5vw, 4.25rem);
  line-height: 1.16;
  letter-spacing: -0.035em;
  display: flex;
  align-items: baseline;
  gap: 0.7em;
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s var(--ease), transform 0.7s var(--ease), color 0.4s;
}
body.is-menu .menu__link { opacity: 1; transform: none; }
body.is-menu .menu__link:nth-child(1) { transition-delay: 0.16s; }
body.is-menu .menu__link:nth-child(2) { transition-delay: 0.22s; }
body.is-menu .menu__link:nth-child(3) { transition-delay: 0.28s; }
body.is-menu .menu__link:nth-child(4) { transition-delay: 0.34s; }
body.is-menu .menu__link:nth-child(5) { transition-delay: 0.40s; }
.menu__link:hover { color: var(--bej-2); }
.menu__link span {
  font-family: var(--f-sans);
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  color: var(--fg-mute);
  opacity: 0.6;
}

/* One line, always. Three items will not fit across a phone at a readable
   size, so the city — which is repeated in every page footer — steps out
   below 600px rather than letting the row wrap. */
.menu__foot {
  padding-block: clamp(1.25rem, 4vw, 3rem);
  border-block-start: 1px solid rgb(251 249 246 / 16%);
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: clamp(0.75rem, 3vw, 3rem);
  white-space: nowrap;
  font-size: clamp(0.6875rem, 3.2vw, var(--t-small));
  color: #a49b8e;
  /* Fades only — it is the last row of a scrollable overlay, so translating it
     downwards adds its own travel to the menu's scroll height. */
  opacity: 0;
  transition: opacity 0.5s var(--ease) 0.42s;
}
body.is-menu .menu__foot { opacity: 1; }
.menu__foot a:hover { color: var(--paper); }
@media (max-width: 600px) { .menu__foot-place { display: none; } }

/* ───────────────────────────────────────────────────────── hero ── */

.hero {
  position: relative;
  /* svh, deliberately not dvh: dvh tracks the mobile browser's collapsing
     toolbar, so the hero grows by ~70px the moment you start scrolling and the
     cover image visibly rescales with it. svh holds one size. */
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  color: var(--paper);
  overflow: clip;
  background: var(--ink);
}

/* Explicit layers so the headline can never be covered by a slide. */
.hero__stage { position: absolute; inset: 0; z-index: 0; }

/* A true dissolve: the outgoing frame stays fully opaque underneath while the
   incoming one fades in above it. Fading both at once would let the dark hero
   background show through the middle of every transition, which reads as the
   picture going soft and grey for a second. */
.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  z-index: 0;
  transition: opacity 1.4s var(--ease-io);
}
.hero__slide.is-prev { opacity: 1; z-index: 0; transition: none; }
.hero__slide.is-active { opacity: 1; z-index: 1; }
.hero__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.06);
  --img-zoom: 9s;
  --img-zoom-ease: linear;
}
.hero__slide.is-active img,
.hero__slide.is-prev img { transform: scale(1); }

.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Bottom wash for the headline, top wash for the header, left wash because
     all hero copy is set flush left. Tuned against the brightest image in the
     rotation, not the darkest. */
  background:
    linear-gradient(to top, rgb(16 14 12 / 84%) 0%, rgb(16 14 12 / 46%) 30%, rgb(16 14 12 / 12%) 60%, rgb(16 14 12 / 40%) 100%),
    linear-gradient(to right, rgb(16 14 12 / 42%) 0%, rgb(16 14 12 / 0%) 58%);
}

.hero__body {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(3rem, 7vw, 5.5rem);
  display: grid;
  gap: clamp(1.5rem, 4vw, 2.75rem);
}

.hero__kicker { color: rgb(251 249 246 / 92%); }

/* Hero copy has to survive whichever project is on screen, including the very
   bright interiors. A soft shadow costs nothing on the dark ones. */
.hero__body,
.phero__body { text-shadow: 0 1px 18px rgb(16 14 12 / 45%); }
.hero__title { max-width: 22ch; }
.hero__title em { font-style: italic; }

.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.25rem 2rem;
  border-block-start: 1px solid rgb(251 249 246 / 26%);
  padding-block-start: clamp(1rem, 2vw, 1.5rem);
}

.hero__now {
  font-size: var(--t-small);
  letter-spacing: 0.1em;
  color: rgb(251 249 246 / 78%);
  display: grid;
  gap: 0.2rem;
}
.hero__now strong { font-weight: 400; color: var(--paper); }

.hero__dots { display: flex; gap: 0.6rem; align-items: center; }
.hero__dot {
  width: 34px; height: 2px;
  background: rgb(251 249 246 / 28%);
  position: relative;
  overflow: hidden;
}
.hero__dot::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--paper);
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.hero__dot.is-active::after { animation: dotFill 6s linear forwards; }
@keyframes dotFill { to { transform: scaleX(1); } }

.scroll-cue {
  position: absolute;
  z-index: 2;
  /* physical properties: `inset-inline-*` would resolve against this element's
     own vertical writing mode, not the page's */
  right: var(--gutter);
  bottom: clamp(3rem, 7vw, 5.5rem);
  writing-mode: vertical-rl;
  font-size: var(--t-micro);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgb(251 249 246 / 72%);
  display: flex;
  align-items: center;
  gap: 1rem;
}
.scroll-cue::after {
  content: '';
  width: 1px; height: 54px;
  background: linear-gradient(rgb(251 249 246 / 80%), rgb(251 249 246 / 0%));
  animation: cueDrop 2.4s var(--ease-io) infinite;
}
@keyframes cueDrop {
  0% { transform: scaleY(0); transform-origin: 0 0; }
  45% { transform: scaleY(1); transform-origin: 0 0; }
  46% { transform: scaleY(1); transform-origin: 0 100%; }
  100% { transform: scaleY(0); transform-origin: 0 100%; }
}
@media (max-width: 900px) { .scroll-cue { display: none; } }

/* page header (interior pages) */

.pagehead {
  padding-block: calc(var(--header-h) + clamp(2.75rem, 6.5vw, 6rem)) clamp(2.5rem, 6vw, 4.5rem);
  display: grid;
  gap: clamp(1rem, 2.4vw, 1.6rem);
}
/* Page titles and project names are set in the plain sans, not the display
   serif. Sans carries far more weight at the same size, so the scale is pulled
   back and the tracking tightened to keep it from shouting. */
.pagehead__title {
  max-width: 20ch;
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: clamp(2rem, 5vw, 4.25rem);
  line-height: 1.04;
  letter-spacing: -0.03em;
}
.pagehead__lead { max-width: 52ch; color: var(--fg-mute); }

/* ──────────────────────────────────────────────────────── media ── */

.media {
  position: relative;
  overflow: hidden;
  background: var(--paper-2);
  /* `isolation` keeps the placeholder/photo z-indexes below inside their own
     stacking context. Without it a fully-opaque hero slide does not create one,
     the photo's z-index escapes to the root, and it paints over the hero
     headline — which then only reappears mid-cross-fade. */
  isolation: isolate;
}
/* When .media carries an aspect-ratio (or --fill), the image fills it and
   crops. When it doesn't, the image's own ratio sets the height. */
.media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.media--fill { block-size: 100%; }
.media:not([style*='aspect-ratio']):not(.media--fill) img { height: auto; }

/* Progressive image: the tiny blurred placeholder and the real photograph
   cross-fade over the same long curve, so the picture appears to come into
   focus in one continuous movement rather than snapping from blur to sharp.
   Nothing is filtered at full resolution, so it stays cheap on mobile. */
.media__ph {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-size: cover;
  background-position: 50% 50%;
  filter: blur(16px) saturate(1.1);
  transform: scale(1.1);
  transition:
    opacity 1.25s var(--ease),
    transform 1.6s var(--ease),
    filter 1.25s var(--ease),
    clip-path var(--img-wipe, 1.25s) var(--ease);
}
.media.is-loaded .media__ph {
  opacity: 0;
  transform: scale(1.02);
  filter: blur(6px) saturate(1);
}

/* One transition declaration for every image on the site, tuned per component
   through custom properties rather than by re-declaring `transition`.
   Re-declaring it is how the sector tiles and the hero lost their zoom: a
   higher-specificity rule elsewhere replaced the whole shorthand and left
   `transform` with no transition at all, so it snapped. */
.media img {
  transition:
    opacity var(--img-fade, 1.05s) var(--ease),
    transform var(--img-zoom, 1.2s) var(--img-zoom-ease, var(--ease-zoom)),
    clip-path var(--img-wipe, 1.25s) var(--ease);
}

/* Scoped to .js so the page still shows every photograph if scripting fails. */
.js .media img {
  position: relative;
  z-index: 1;
  opacity: 0;
}
.js .media.is-loaded img { opacity: 1; }

/* Reveal: the frame wipes open while the picture settles back to scale 1 and
   cross-fades out of its placeholder — one movement, three properties, one
   curve. All reveal states are scoped to .js so a no-script page shows
   everything immediately. */
/* The wipe is applied to .media's CHILDREN, never to .media itself. A
   clip-path on the observed element collapses its intersection rectangle to
   nothing, so IntersectionObserver never reports it as visible and the image
   stays hidden forever. .media keeps overflow:hidden, so the result is
   identical. */
/* No `transition` shorthand here — it would replace the image's own, which is
   exactly how the zoom kept getting lost. Both children already animate
   clip-path through their base transitions. */
.js .media[data-reveal='media'] > * { clip-path: inset(0 0 100% 0); }
/* Scoped to :not(.is-in) so that once a picture has landed it hands the zoom
   back to whatever component it lives in, at that component's own pace. */
.js .media[data-reveal='media']:not(.is-in) img {
  --img-zoom: 1.6s;
  --img-zoom-ease: var(--ease);
  transform: scale(1.1);
}
.js .media[data-reveal='media'] .media__ph { transform: scale(1.16); }
.js .media[data-reveal='media'].is-in > * { clip-path: inset(0 0 0 0); }

.js [data-reveal='up'] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 1s var(--ease), transform 1.1s var(--ease);
}
.js [data-reveal='up'].is-in { opacity: 1; transform: none; }

.js [data-reveal='fade'] { opacity: 0; transition: opacity 1.2s var(--ease); }
.js [data-reveal='fade'].is-in { opacity: 1; }

.js [data-reveal-delay='1'] { transition-delay: 0.09s; }
.js [data-reveal-delay='2'] { transition-delay: 0.18s; }
.js [data-reveal-delay='3'] { transition-delay: 0.27s; }
.js [data-reveal-delay='4'] { transition-delay: 0.36s; }


/* ──────────────────────────────────────────────── project cards ── */

.work {
  display: grid;
  gap: clamp(2.75rem, 7vw, 7rem) clamp(1.5rem, 3.4vw, 3.5rem);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 780px) {
  .work { grid-template-columns: minmax(0, 1fr); gap: clamp(2.25rem, 8vw, 3rem); }
}

/* Editorial rhythm comes from offsetting the right-hand column, not from
   mixing aspect ratios: a 3:4 card next to a 4:3 one forces the grid row to
   the taller of the two and leaves a screen-high hole under the shorter. */
.work--editorial > *:nth-child(even) { margin-block-start: clamp(0rem, 9vw, 8rem); }

/* One column: the stagger only makes every second gap half again as big as the
   one before it, which reads as an accident rather than a rhythm. Must come
   after the rule above — same specificity, so source order decides. */
@media (max-width: 780px) {
  .work--editorial > *:nth-child(even) { margin-block-start: 0; }
}

/* `align-content: start` on both: the work grid stretches rows to equal
   height, and without it the leftover space is dealt out between the title
   and its meta line instead of falling below the card. */
.card {
  position: relative;
  display: grid;
  align-content: start;
  gap: clamp(0.7rem, 1.6vw, 1.35rem);
}
.card__media { aspect-ratio: 4 / 3; }
@media (max-width: 780px) { .card__media { aspect-ratio: 5 / 4; } }

.card__media img { --img-zoom: 2.4s; }
.card:hover .card__media img { transform: scale(1.055); }

/* The index used to sit on the photograph in `difference` blend mode, which
   vanished on any light interior. It belongs with the caption. */
.card__index {
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  color: var(--fg-mute);
  font-variant-numeric: tabular-nums;
}

/* Title and meta are stacked, not spread across the card: on a two-column
   editorial grid a `space-between` foot puts one card's meta right against the
   next card's title and the two read as a single line. */
.card__foot {
  display: grid;
  align-content: start;
  gap: 0.3rem;
  justify-items: start;
  border-block-start: 1px solid var(--rule);
  padding-block-start: clamp(0.65rem, 1.4vw, 1rem);
}
.card__title {
  font-family: var(--f-sans);
  font-weight: 400;
  font-size: clamp(1.0625rem, 1.7vw, 1.4rem);
  line-height: 1.25;
  letter-spacing: -0.02em;
}
.card__title .u { display: inline-block; position: relative; }
.card__title .u::after {
  content: '';
  position: absolute; inset-block-end: 0.06em; inset-inline: 0;
  height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform 0.6s var(--ease);
}
.card:hover .card__title .u::after { transform: scaleX(1); transform-origin: 0 50%; }

.card__tags {
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-mute);
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.6rem;
  align-items: center;
  line-height: 1.5;
}
.card__tags span + span::before { content: '·'; margin-inline-end: 0.6rem; }

.card__link { position: absolute; inset: 0; z-index: 3; }

/* filter */

.filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem clamp(0.5rem, 1.4vw, 1rem);
  border-block: 1px solid var(--rule);
  padding-block: clamp(0.85rem, 1.8vw, 1.15rem);
  margin-block-end: clamp(2.25rem, 5vw, 4rem);
}
.filter {
  font-size: var(--t-small);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.45rem 1rem;
  border: 1px solid transparent;
  border-radius: 100px;
  color: var(--fg-mute);
  transition: color 0.35s, border-color 0.35s, background 0.35s;
  white-space: nowrap;
}
.filter:hover { color: var(--fg); border-color: var(--rule-strong); }
.filter[aria-pressed='true'] {
  color: var(--paper);
  background: var(--ink);
  border-color: var(--ink);
}

.work__item {
  transition: opacity 0.5s var(--ease), transform 0.55s var(--ease);
}
.work__item.is-filtered {
  display: none;
}

/* ─────────────────────────────────────────────────── statement ── */

.statement {
  display: grid;
  gap: clamp(1.75rem, 4vw, 3rem);
  grid-template-columns: minmax(0, 1fr);
}
.statement__text {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.35rem, 3vw, 2.5rem);
  line-height: 1.26;
  letter-spacing: -0.03em;
  max-width: 26ch;
}
@media (min-width: 900px) {
  /* `start`, not `end`: when the right column is the taller of the two,
     bottom-aligning leaves a screen-high hole above the pull-quote. */
  .statement { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); align-items: start; gap: clamp(2rem, 5vw, 5rem); }
}

/* ─────────────────────────────────────────────── disciplines ── */

.disc { display: grid; }
.disc__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(1rem, 3vw, 3rem);
  align-items: start;
  padding-block: clamp(1.75rem, 3.4vw, 2.75rem);
  border-block-start: 1px solid var(--rule);
  position: relative;
}
.disc__row:last-child { border-block-end: 1px solid var(--rule); }
.disc__num {
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  color: var(--fg-mute);
  padding-block-start: 0.55em;
  font-variant-numeric: tabular-nums;
}
.disc__main { display: grid; gap: 0.7rem; }
.disc__title {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.35rem, 2.6vw, 2.25rem);
  line-height: 1.14;
  letter-spacing: -0.028em;
  transition: transform 0.6s var(--ease);
}
.disc__row:hover .disc__title { transform: translateX(clamp(4px, 1vw, 14px)); }
.disc__body { color: var(--fg-mute); max-width: 52ch; }

@media (min-width: 1000px) {
  .disc__row { grid-template-columns: 4rem minmax(0, 0.9fr) minmax(0, 1.1fr); align-items: baseline; }
  .disc__main { display: contents; }
  .disc__body { padding-block-start: 0.4em; }
}

/* ─────────────────────────────────────────────────── sectors ── */

.sectors {
  display: grid;
  gap: clamp(1.25rem, 2.5vw, 2rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
.sector {
  position: relative;
  display: grid;
  gap: 1rem;
  isolation: isolate;
  color: var(--paper);
  min-height: clamp(300px, 42vw, 460px);
  align-content: end;
  padding: clamp(1.25rem, 2.4vw, 2rem);
  overflow: hidden;
}
.sector__bg { position: absolute; inset: 0; z-index: -2; }
.sector__bg img { width: 100%; height: 100%; object-fit: cover; --img-zoom: 2.8s; }
.sector:hover .sector__bg img { transform: scale(1.07); }
.sector::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgb(16 14 12 / 78%), rgb(16 14 12 / 12%) 62%);
}
.sector__title { font-family: var(--f-display); font-weight: 500; font-size: clamp(1.3rem, 2.1vw, 1.85rem); letter-spacing: -0.028em; }
.sector__blurb { font-size: var(--t-small); color: rgb(251 249 246 / 80%); max-width: 34ch; }
.sector__count { font-size: var(--t-micro); letter-spacing: 0.2em; text-transform: uppercase; color: rgb(251 249 246 / 70%); }

/* ─────────────────────────────────────────────────────── facts ── */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.fact { display: grid; gap: 0.5rem; border-block-start: 1px solid var(--rule); padding-block-start: 1.1rem; }
.fact__value { font-family: var(--f-display); font-weight: 500; font-size: clamp(1.9rem, 3.6vw, 2.9rem); line-height: 1.05; letter-spacing: -0.035em; }
.fact__label { font-size: var(--t-small); color: var(--fg-mute); }

/* ───────────────────────────────────────────────────── marquee ── */

.marquee {
  overflow: hidden;
  border-block: 1px solid var(--rule);
  padding-block: clamp(0.9rem, 2vw, 1.4rem);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.marquee__track {
  display: flex;
  gap: clamp(2rem, 5vw, 4.5rem);
  width: max-content;
  animation: slide 46s linear infinite;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-size: var(--t-small);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fg-mute);
  white-space: nowrap;
}
@keyframes slide { to { transform: translateX(-50%); } }

/* ───────────────────────────────────────────────────── buttons ── */

.btn {
  --btn-fg: var(--fg);
  display: inline-flex;
  align-items: center;
  gap: 0.85em;
  font-size: var(--t-small);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--btn-fg);
  padding-block: 0.65em;
  position: relative;
  align-self: start;
  justify-self: start;
}
.btn__line {
  position: absolute;
  inset-block-end: 0; inset-inline: 0;
  height: 1px; background: currentColor; opacity: 0.4;
}
.btn__line::after {
  content: '';
  position: absolute; inset: 0;
  background: currentColor;
  transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform 0.6s var(--ease);
}
.btn:hover .btn__line::after { transform: scaleX(1); transform-origin: 0 50%; }
.btn svg { width: 1em; flex: none; transition: transform 0.5s var(--ease); }
.btn:hover svg { transform: translateX(4px); }

.btn--solid {
  background: var(--ink);
  color: var(--paper);
  padding: 1.05em 2.2em;
  transition: background 0.4s var(--ease), color 0.4s;
}
.btn--solid .btn__line { display: none; }
.btn--solid:hover { background: var(--ink-2); }
.invert .btn--solid,
.cta .btn--solid,
.footer .btn--solid { background: var(--paper); color: var(--ink); }
.invert .btn--solid:hover,
.cta .btn--solid:hover,
.footer .btn--solid:hover { background: var(--bej); }

/* ─────────────────────────────────────────────────────── CTA ── */

.cta {
  position: relative;
  isolation: isolate;
  color: var(--paper);
  overflow: hidden;
  display: grid;
  place-items: center;
  text-align: center;
  padding-block: clamp(5rem, 14vw, 12rem);
}
.cta__bg { position: absolute; inset: 0; z-index: -2; }
.cta__bg img { width: 100%; height: 100%; object-fit: cover; }
.cta::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: rgb(16 14 12 / 62%);
}
.cta__inner { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); justify-items: center; max-width: 44rem; }
/* .btn defaults to justify-self:start, which would knock these off centre */
.cta__inner .btn { justify-self: center; }
.cta .eyebrow { text-align: center; color: rgb(251 249 246 / 76%); }

/* ─────────────────────────────────────────────── project detail ── */

.phero {
  position: relative;
  /* svh, deliberately not dvh: dvh tracks the mobile browser's collapsing
     toolbar, so the hero grows by ~70px the moment you start scrolling and the
     cover image visibly rescales with it. svh holds one size. */
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  color: var(--paper);
  background: var(--ink);
  overflow: clip;
}
.phero__bg { position: absolute; inset: 0; z-index: 0; }
.phero__bg img { width: 100%; height: 100%; object-fit: cover; }
.phero::after {
  content: '';
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(to top, rgb(16 14 12 / 86%) 0%, rgb(16 14 12 / 48%) 30%, rgb(16 14 12 / 10%) 60%, rgb(16 14 12 / 42%) 100%),
    linear-gradient(to right, rgb(16 14 12 / 44%) 0%, rgb(16 14 12 / 0%) 58%);
}
.phero__body {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(3rem, 7vw, 5.5rem);
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.75rem);
}
.phero__title { max-width: 16ch; }
.phero .eyebrow { color: rgb(251 249 246 / 80%); }

.pmeta {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 960px) {
  .pmeta { grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: clamp(3rem, 7vw, 7rem); }
  .pmeta__facts { position: sticky; top: calc(var(--header-h) + 2rem); }
}

.pmeta__facts { display: grid; gap: 0; }
.pfact {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) minmax(0, 1fr);
  gap: 1rem;
  padding-block: 0.85rem;
  border-block-start: 1px solid var(--rule);
  font-size: var(--t-small);
}
.pfact:last-child { border-block-end: 1px solid var(--rule); }
.pfact dt { color: var(--fg-mute); letter-spacing: 0.08em; text-transform: uppercase; font-size: var(--t-micro); padding-block-start: 0.3em; }
.pfact dd { margin: 0; }

.pbody { display: grid; gap: clamp(1.5rem, 3vw, 2.25rem); }
.pbody p { max-width: 68ch; color: var(--fg-mute); }
.pbody p:first-of-type {
  font-size: clamp(1.05rem, 1.5vw, 1.3125rem);
  line-height: 1.6;
  font-weight: 300;
  color: var(--fg);
  max-width: 46ch;
}

/* gallery: alternating editorial layouts */
.gal { display: grid; gap: clamp(1rem, 2.4vw, 2.25rem); }
.gal__row { display: grid; gap: clamp(1rem, 2.4vw, 2.25rem); }
.gal__row--full { grid-template-columns: minmax(0, 1fr); }
.gal__row--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gal__row--offset { grid-template-columns: repeat(12, minmax(0, 1fr)); }
.gal__row--offset > *:first-child { grid-column: 1 / span 7; }
.gal__row--offset > *:last-child { grid-column: 9 / span 4; align-self: end; }
.gal__row--offset-r > *:first-child { grid-column: 1 / span 4; }
.gal__row--offset-r > *:last-child { grid-column: 6 / span 7; align-self: start; }

@media (max-width: 780px) {
  .gal__row--two,
  .gal__row--offset { grid-template-columns: minmax(0, 1fr); }
  .gal__row--offset > *,
  .gal__row--offset-r > * { grid-column: 1 / -1 !important; }
}

.gal__fig { margin: 0; display: grid; gap: 0.6rem; }
.gal__fig .media { cursor: zoom-in; }
.gal__fig figcaption { font-size: var(--t-micro); letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-mute); }

.bleed {
  width: 100vw;
  max-width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/* next project */
.next {
  position: relative;
  isolation: isolate;
  color: var(--paper);
  min-height: clamp(340px, 58vw, 620px);
  display: grid;
  align-content: center;
  justify-items: center;
  text-align: center;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  overflow: hidden;
  padding: var(--section) var(--gutter);
}
.next__bg { position: absolute; inset: 0; z-index: -2; }
.next__bg img { width: 100%; height: 100%; object-fit: cover; --img-zoom: 3s; }
.next:hover .next__bg img { transform: scale(1.06); }
.next::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: rgb(16 14 12 / 58%);
  transition: background 0.6s;
}
.next:hover::after { background: rgb(16 14 12 / 48%); }
.next .eyebrow { color: rgb(251 249 246 / 78%); text-align: center; }

/* ─────────────────────────────────────────────────────── studio ── */

.studio-split {
  display: grid;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .studio-split { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: clamp(3rem, 7vw, 6.5rem); }
}
/* The portrait is a brush-edged plate rather than a rectangle: the mask is
   baked into the WebP's alpha channel, so it sits on the paper with no frame.
   The oversized mark behind it and the warm halo give the plate somewhere to
   land instead of floating. */
.portrait { margin: 0; display: grid; gap: clamp(1rem, 2vw, 1.5rem); }

.portrait__frame {
  position: relative;
  aspect-ratio: 3 / 4;
  isolation: isolate;
}
.portrait__frame::before {
  content: '';
  position: absolute;
  inset: 6% 2%;
  z-index: 0;
  background: radial-gradient(closest-side, rgb(156 134 106 / 22%), transparent 72%);
  filter: blur(34px);
}
.portrait img {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.portrait__cap {
  display: grid;
  gap: 0.15rem;
  border-block-start: 1px solid var(--rule);
  padding-block-start: clamp(0.7rem, 1.4vw, 1rem);
}
.portrait__name { font-family: var(--f-display); font-weight: 500; font-size: var(--t-h3); line-height: 1.2; letter-spacing: -0.02em; }
.portrait__role {
  font-size: var(--t-micro);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--fg-mute);
}

@media (max-width: 899px) { .portrait { max-width: 26rem; } }

.taglist { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.taglist li {
  list-style: none;
  font-size: var(--t-small);
  letter-spacing: 0.06em;
  border: 1px solid var(--rule-strong);
  border-radius: 100px;
  padding: 0.4rem 1rem;
  color: var(--fg-mute);
}

/* ───────────────────────────────────────────────────── services ── */

.svc {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: center;
  padding-block: clamp(2.5rem, 6vw, 5rem);
  border-block-start: 1px solid var(--rule);
}
@media (min-width: 900px) {
  .svc { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(3rem, 7vw, 6rem); }
  .svc:nth-child(even) .svc__media { order: -1; }
}
.svc__media { aspect-ratio: 4 / 3; }
.svc__main { display: grid; gap: clamp(1rem, 2vw, 1.5rem); }
.svc__points { display: grid; gap: 0.55rem; padding: 0; margin: 0; }
.svc__points li {
  list-style: none;
  font-size: var(--t-small);
  color: var(--fg-mute);
  padding-inline-start: 1.4rem;
  position: relative;
}
.svc__points li::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  inset-block-start: 0.72em;
  width: 8px; height: 1px;
  background: var(--accent);
}

/* ────────────────────────────────────────────────────── contact ── */

.contact-grid {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: start;
}
@media (min-width: 900px) {
  .contact-grid { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: clamp(3rem, 8vw, 7rem); }
}

.info { display: grid; gap: clamp(1.75rem, 3.5vw, 2.75rem); }
.info__block { display: grid; gap: 0.5rem; border-block-start: 1px solid var(--rule); padding-block-start: 1.1rem; }
.info__label { font-size: var(--t-micro); letter-spacing: 0.2em; text-transform: uppercase; color: var(--fg-mute); }
.info__value { font-size: clamp(1rem, 1.5vw, 1.15rem); }
.info__value a { position: relative; }
.info__value a::after {
  content: ''; position: absolute; inset-block-end: -2px; inset-inline: 0;
  height: 1px; background: currentColor; transform: scaleX(0); transform-origin: 100% 50%;
  transition: transform 0.5s var(--ease);
}
.info__value a:hover::after { transform: scaleX(1); transform-origin: 0 50%; }

.form { display: grid; gap: clamp(1.25rem, 2.5vw, 1.75rem); }
.field { display: grid; gap: 0.5rem; }
.field label { font-size: var(--t-micro); letter-spacing: 0.18em; text-transform: uppercase; color: var(--fg-mute); }
.field input,
.field textarea,
.field select {
  width: 100%;
  background: transparent;
  border: 0;
  border-block-end: 1px solid var(--rule-strong);
  padding: 0.75rem 0;
  font-size: 1rem;
  transition: border-color 0.35s;
  border-radius: 0;
  appearance: none;
}
.field select { background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: right 6px center, right 1px center; background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; padding-inline-end: 1.5rem; }
.field textarea { min-height: 8rem; resize: vertical; }
.field input:focus,
.field textarea:focus,
.field select:focus { outline: 0; border-color: var(--fg); }
.field input::placeholder, .field textarea::placeholder { color: var(--fg-mute); opacity: 0.55; }
.form__row { display: grid; gap: inherit; }
@media (min-width: 620px) { .form__row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.form__note { font-size: var(--t-small); color: var(--fg-mute); }
/* full-width submit on phones so it is an easy target */
@media (max-width: 620px) {
  .form .btn--solid { justify-self: stretch; justify-content: center; }
}

/* ─────────────────────────────────────────────────────── footer ── */

/* The dark blocks must remap the tokens, not just set `color` — components
   like .btn read `--fg`, and on a plain `color: paper` footer that resolved to
   ink, i.e. a black link on a black background. */
.footer,
.cta {
  --bg: var(--ink);
  --fg: var(--paper);
  --fg-mute: #a49b8e;
  --rule: rgb(251 249 246 / 16%);
  --rule-strong: rgb(251 249 246 / 34%);
  --accent: #c2ab89;
  color-scheme: dark;
}

.footer { background: var(--ink); color: var(--paper); }
.footer__top {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  padding-block: clamp(3.5rem, 8vw, 7rem);
}
@media (min-width: 900px) {
  .footer__top { grid-template-columns: minmax(0, 1.3fr) repeat(2, minmax(0, 0.7fr)); gap: clamp(2rem, 5vw, 5rem); }
}
.footer__brand { display: grid; gap: clamp(1.25rem, 2.5vw, 2rem); align-content: start; }
.footer__logo { width: clamp(180px, 22vw, 260px); color: var(--paper); }
.footer__tag { font-size: var(--t-small); color: #a49b8e; max-width: 34ch; }

.footer__col { display: grid; gap: 0.65rem; align-content: start; }
.footer__head { font-size: var(--t-micro); letter-spacing: 0.22em; text-transform: uppercase; color: #a49b8e; margin-block-end: 0.4rem; }
.footer__col a, .footer__col p { font-size: var(--t-small); color: rgb(251 249 246 / 85%); }
.footer__col a:hover { color: var(--paper); }

.footer__bar {
  border-block-start: 1px solid rgb(251 249 246 / 14%);
  padding-block: clamp(1.25rem, 2.5vw, 1.75rem);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  color: #8d8478;
  text-transform: uppercase;
}
.footer__bar a:hover { color: var(--paper); }

/* ──────────────────────────────────────────────────── lightbox ── */

.lb {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgb(9 8 7 / 96%);
  display: grid;
  grid-template-rows: auto 1fr auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--ease), visibility 0.45s;
  color: var(--paper);
  touch-action: pan-y;
}
.lb.is-open { opacity: 1; visibility: visible; }

.lb__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.9rem, 2.5vw, 1.5rem) var(--gutter);
  font-size: var(--t-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgb(251 249 246 / 70%);
}
.lb__close { display: flex; align-items: center; gap: 0.6rem; }
.lb__close svg { width: 13px; }
.lb__close:hover { color: var(--paper); }

.lb__stage {
  position: relative;
  display: grid;
  place-items: center;
  padding: 0 clamp(0.5rem, 2vw, 2rem);
  min-height: 0;
}
.lb__img {
  max-width: min(100%, 1500px);
  max-height: 100%;
  object-fit: contain;
  opacity: 0;
  transform: scale(0.985);
  transition: opacity 0.45s var(--ease), transform 0.6s var(--ease);
}
.lb__img.is-ready { opacity: 1; transform: none; }

.lb__nav {
  position: absolute;
  inset-block: 0;
  width: clamp(60px, 14vw, 140px);
  display: grid;
  place-items: center;
  color: rgb(251 249 246 / 60%);
  transition: color 0.3s;
}
.lb__nav:hover { color: var(--paper); }
.lb__nav svg { width: clamp(20px, 3vw, 30px); }
.lb__nav--prev { inset-inline-start: 0; }
.lb__nav--next { inset-inline-end: 0; }
.lb__nav[disabled] { opacity: 0.2; pointer-events: none; }

.lb__foot {
  padding: clamp(0.9rem, 2.5vw, 1.5rem) var(--gutter);
  font-size: var(--t-small);
  color: rgb(251 249 246 / 72%);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ────────────────────────────────────────────────── preloader ── */

.loader {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--ink);
  display: grid;
  place-items: center;
  transition: opacity 0.7s var(--ease) 0.1s, visibility 0.8s;
}
.loader.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
.loader__mark { width: clamp(34px, 5vw, 48px); color: var(--paper); opacity: 0; animation: loaderIn 1.4s var(--ease) forwards; }
@keyframes loaderIn {
  0% { opacity: 0; transform: translateY(10px) scale(0.9); }
  40% { opacity: 1; transform: none; }
  100% { opacity: 1; transform: none; }
}
.loader__bar {
  position: absolute;
  inset-block-end: 0; inset-inline: 0;
  height: 1px;
  background: rgb(251 249 246 / 20%);
}
.loader__bar::after {
  content: '';
  position: absolute; inset: 0;
  background: var(--paper);
  transform: scaleX(var(--p, 0));
  transform-origin: 0 50%;
  transition: transform 0.4s var(--ease);
}

/* page fade */
.page { opacity: 1; transition: opacity 0.35s var(--ease); }
body.is-leaving .page { opacity: 0; }

/* ─────────────────────────────────────────────────────── cursor ── */

.cursor {
  position: fixed;
  top: 0; left: 0;
  z-index: 110;
  width: 84px; height: 84px;
  margin: -42px 0 0 -42px;
  border-radius: 50%;
  background: var(--paper);
  color: var(--ink);
  display: grid;
  place-items: center;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.3);
  transition: opacity 0.3s, transform 0.4s var(--ease);
  will-change: translate;
}
.cursor.is-on { opacity: 1; transform: scale(1); }
@media (hover: none), (max-width: 900px) { .cursor { display: none; } }

/* ──────────────────────────────────────── phone held sideways ── */

/*
 * A landscape phone is wide but only ~390px tall, so type scaled against vw
 * becomes enormous relative to the space available: the hero headline alone
 * would be taller than the screen, and the five menu links would not fit at
 * all. Inside a short viewport the display sizes are driven by height instead,
 * and the vertical rhythm is compressed to match.
 */
@media (orientation: landscape) and (max-height: 620px) {
  :root {
    --t-hero: clamp(1.6rem, 8vh, 3.4rem);
    --t-h1: clamp(1.5rem, 7vh, 3rem);
    --t-h2: clamp(1.3rem, 5.5vh, 2.4rem);
    --t-h3: clamp(1.05rem, 3.6vh, 1.6rem);
    --header-h: 54px;
    --section: clamp(2.25rem, 9vh, 4.5rem);
  }

  .hero__title { max-width: 20ch; }
  .hero__body,
  .phero__body { padding-block-end: clamp(0.9rem, 5vh, 2.5rem); gap: clamp(0.6rem, 2.5vh, 1.5rem); }
  .scroll-cue { display: none; }

  /* Five links plus a footer inside ~390px, with no scrolling. */
  .menu { grid-template-rows: var(--header-h) 1fr auto; }
  .menu__nav { padding-block: 0.35rem; gap: 0; }
  .menu__link { font-size: clamp(1.05rem, 7.4vh, 2.4rem); line-height: 1.22; }
  .menu__link span { font-size: 0.5rem; }
  .menu__foot { padding-block: clamp(0.5rem, 2.2vh, 1rem); }

  .statement__text { font-size: clamp(1.25rem, 5vh, 2.4rem); }
  .pagehead { padding-block: calc(var(--header-h) + clamp(1.75rem, 9vh, 4rem)) clamp(2rem, 11vh, 3.5rem); }

  /* A sideways phone is ~840px wide — the same width that gets two columns on
     a desktop. Those layouts are keyed off min-width: 900px, so they would
     otherwise stack and waste all of it. */
  .studio-split { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
  .contact-grid { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); gap: clamp(1.5rem, 4vw, 3rem); }
  .svc { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3rem); }
  .svc:nth-child(even) .svc__media { order: -1; }
  .pmeta { grid-template-columns: minmax(0, 250px) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3rem); }
  .statement { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
  .form__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sector { min-height: clamp(220px, 62vh, 320px); }
  .next { min-height: clamp(240px, 70vh, 380px); }
  .cta { padding-block: clamp(3rem, 14vh, 7rem); }
  .portrait { max-width: 20rem; }

  /* three tiles across is the right call on a sideways phone */
  .sectors { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .work { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .card__media { aspect-ratio: 4 / 3; }

  .lb__foot { display: none; }
  .lb__bar { padding-block: 0.6rem; }
}

/* ─────────────────────────────────────────── motion preferences ── */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .js .media[data-reveal='media'] > * { clip-path: none !important; }
  .js .media[data-reveal='media'] img { transform: none !important; }
  .js .media img { opacity: 1 !important; }
  .js .media__ph { opacity: 0 !important; }
  .hero__slide img { transform: none !important; }
  .marquee__track { animation: none; }
  .cursor { display: none; }
}

/* ─────────────────────────────────────────────────────── print ── */

@media print {
  .header, .menu, .loader, .cursor, .lb, .scroll-cue, .next, .cta { display: none !important; }
  body { color: #000; background: #fff; }
  .hero, .phero { min-height: auto; }
}
