/* =============================================================================
   DB ARCHITECTURE — Design system & styles
   Warm, gallery-like, image-forward. Light theme only (by design).
   Sections: 1 Fonts · 2 Tokens · 3 Reset/base · 4 Typography · 5 Layout
   6 Buttons · 7 Header/nav · 8 Footer · 9 Hero · 10 Reveal · 11 Home
   12 Services · 13 Process · 14 About · 15 Projects module · 16 Forms
   17 Utilities · 18 Responsive · 19 Reduced motion
   ============================================================================= */

/* ---- 1. Fonts (self-hosted, GDPR-clean — no external requests) ------------ */
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin-300-normal.woff2")
    format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin-400-normal.woff2")
    format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin-500-normal.woff2")
    format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/cormorant-garamond-latin-600-normal.woff2")
    format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/inter-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/inter-latin-500-normal.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/inter-latin-600-normal.woff2") format("woff2");
}

/* ---- 2. Tokens ------------------------------------------------------------ */
:root {
  /* Warm neutral palette, drawn from the practice's own work */
  --bone: #f4f1ea; /* page background — warm off-white */
  --paper: #ffffff;
  --cream: #efeae1;
  --cream-deep: #e7e0d4;
  --ink: #1c1a17;
  --ink-soft: #3a352f;
  --muted: #6f665b;
  --muted-light: #9a9084;
  --line: #e6dfd4;
  --line-strong: #d8cdbd;
  --brass: #9a7b4e;
  --brass-deep: #7d6136;
  --brass-tint: #b7975f;
  --scrim: rgba(24, 20, 16, 0.42);

  --font-display:
    "Cormorant Garamond", "Iowan Old Style", "Times New Roman", Georgia, serif;
  --font-sans:
    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
    Arial, sans-serif;

  /* Fluid type scale */
  /* Hero size respects viewport HEIGHT too, so the title never climbs under
     the fixed header on short/landscape windows. */
  --fs-hero: clamp(2.6rem, min(7vw, 8.5vh), 6rem);
  --fs-display: clamp(2.4rem, 5.2vw, 4.2rem);
  --fs-h1: clamp(2.1rem, 4.4vw, 3.4rem);
  --fs-h2: clamp(1.7rem, 3vw, 2.5rem);
  --fs-h3: clamp(1.3rem, 2vw, 1.65rem);
  --fs-lead: clamp(1.08rem, 1.5vw, 1.32rem);
  --fs-body: 1.02rem;
  --fs-small: 0.875rem;
  --fs-eyebrow: 0.74rem;

  /* Spacing */
  --space-2xs: 0.375rem;
  --space-xs: 0.625rem;
  --space-sm: 1rem;
  --space-md: 1.75rem;
  --space-lg: 3rem;
  --space-xl: 5rem;
  --space-2xl: 8rem;

  --maxw: 1280px;
  --maxw-wide: 1500px;
  --maxw-narrow: 760px;
  --gutter: clamp(1.25rem, 5vw, 4rem);

  --radius: 2px;
  --radius-lg: 4px;
  --shadow-sm: 0 1px 2px rgba(28, 24, 18, 0.05);
  --shadow-md: 0 18px 40px -24px rgba(28, 24, 18, 0.35);
  --shadow-lg: 0 40px 80px -40px rgba(28, 24, 18, 0.45);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 0.5s;

  --header-h: 76px;
}

/* ---- 3. Reset / base ------------------------------------------------------ */
*,
*::before,
*::after {
  box-sizing: border-box;
}
* {
  margin: 0;
}
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
body {
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.7;
  color: var(--ink-soft);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}
img {
  height: auto;
}
a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: none;
  border: none;
}
input,
textarea,
select {
  font: inherit;
  color: inherit;
}
ul,
ol {
  list-style: none;
  padding: 0;
}
:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 3px;
}
::selection {
  background: var(--brass);
  color: #fff;
}
hr {
  border: none;
  border-top: 1px solid var(--line);
}

/* ---- 4. Typography -------------------------------------------------------- */
h1,
h2,
h3,
h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.08;
  color: var(--ink);
  letter-spacing: -0.01em;
}
p {
  max-width: 68ch;
}
strong {
  font-weight: 600;
  color: var(--ink);
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--brass-deep);
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 1px;
  background: var(--brass);
  opacity: 0.65;
}
.eyebrow--center {
  display: flex;
  justify-content: center;
  text-align: center;
}
.eyebrow--center::before {
  display: none;
}

.display {
  font-size: var(--fs-display);
}
.section-title {
  font-size: var(--fs-h2);
}
.lead {
  font-size: var(--fs-lead);
  line-height: 1.6;
  color: var(--muted);
  font-weight: 400;
}
.font-display {
  font-family: var(--font-display);
}

/* ---- 5. Layout ------------------------------------------------------------ */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--wide {
  max-width: var(--maxw-wide);
}
.container--narrow {
  max-width: var(--maxw-narrow);
}
.container--flush {
  max-width: 1800px;
  padding-inline: clamp(1rem, 2vw, 2.5rem);
}
.section {
  padding-block: clamp(3.5rem, 8vw, var(--space-2xl));
}
.section--tight {
  padding-block: clamp(2.5rem, 5vw, var(--space-xl));
}
.section--cream {
  background: var(--cream);
}
.section--ink {
  background: var(--ink);
  color: #d9d2c7;
}
.section--ink h1,
.section--ink h2,
.section--ink h3 {
  color: #f6f1e8;
}

.section-head {
  max-width: 60ch;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}
.section-head--center {
  margin-inline: auto;
  text-align: center;
}
.section-head .eyebrow {
  margin-bottom: 1.1rem;
}
.section-head .lead {
  margin-top: 1.1rem;
}

/* ---- 6. Buttons ----------------------------------------------------------- */
.btn {
  --btn-bg: var(--ink);
  --btn-fg: #f7f2ea;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6em;
  padding: 0.95em 1.9em;
  font-family: var(--font-sans);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-bg);
  border-radius: var(--radius);
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    transform var(--dur) var(--ease);
  will-change: transform;
}
.btn:hover {
  background: var(--brass-deep);
  border-color: var(--brass-deep);
  color: #fff;
  transform: translateY(-2px);
}
.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  border-color: var(--line-strong);
}
.btn--ghost:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: #f7f2ea;
}
.btn--light {
  --btn-bg: rgba(255, 255, 255, 0.1);
  --btn-fg: #fff;
  border-color: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(4px);
}
.btn--light:hover {
  background: #fff;
  border-color: #fff;
  color: var(--ink);
}
.btn--block {
  width: 100%;
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 3px;
  border-bottom: 1px solid var(--line-strong);
  transition:
    color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    gap var(--dur) var(--ease);
}
.link-arrow svg {
  transition: transform var(--dur) var(--ease);
}
.link-arrow:hover {
  color: var(--brass-deep);
  border-color: var(--brass);
  gap: 0.85em;
}
.link-arrow:hover svg {
  transform: translateX(4px);
}

/* ---- 7. Header / navigation ---------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition:
    background var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    color var(--dur) var(--ease);
  background: rgba(244, 241, 234, 0.85);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-header__inner {
  width: 100%;
  max-width: var(--maxw-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
}

/* Transparent variant used over the homepage hero */
.site-header--overlay {
  background: transparent;
  border-bottom-color: transparent;
  color: #fff;
}
.site-header--overlay .nav__link,
.site-header--overlay .brand {
  color: #fff;
}
.site-header--overlay .brand__mark {
  color: #fff;
}
.site-header--overlay .nav__link::after {
  background: #fff;
}
.site-header--overlay .nav-toggle span {
  background: #fff;
}
.site-header--overlay.is-scrolled {
  background: rgba(244, 241, 234, 0.92);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom-color: var(--line);
  color: var(--ink);
}
.site-header--overlay.is-scrolled .nav__link,
.site-header--overlay.is-scrolled .brand,
.site-header--overlay.is-scrolled .brand__mark {
  color: var(--ink);
}
.site-header--overlay.is-scrolled .nav__link::after {
  background: var(--brass);
}
.site-header--overlay.is-scrolled .nav-toggle span {
  background: var(--ink);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  color: var(--ink);
  flex-shrink: 0;
}
.brand__mark {
  height: 34px;
  width: auto;
  color: var(--ink);
  transition: color var(--dur) var(--ease);
}
/* Real logo image (black ink on transparency): inverted to white over the dark
   hero and in the footer, back to black once the header turns light. */
.brand__logo {
  display: block;
  height: 44px;
  width: auto;
  transition: filter var(--dur) var(--ease);
}
.site-header--overlay .brand__logo {
  filter: invert(1);
}
.site-header--overlay.is-scrolled .brand__logo {
  filter: none;
}
.footer-brand__mark.brand__logo {
  height: 52px;
  filter: invert(1);
  opacity: 0.95;
}

/* First-visit logo splash. Shown only while <html> has `splash-on` (set by an
   inline <head> script before first paint); scroll is locked meanwhile. */
.splash {
  display: none;
}
html.splash-on,
html.splash-on body {
  overflow: hidden;
}
html.splash-on .splash,
.splash.is-leaving {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.95);
  cursor: pointer;
  transition: opacity 0.6s var(--ease);
}
.splash.is-leaving {
  opacity: 0;
}
/* The logo is black ink on transparency, so it's inverted to white here. */
.splash__logo {
  display: block;
  height: clamp(96px, 16vw, 140px);
  width: auto;
  max-width: 80vw;
  object-fit: contain;
  filter: invert(1);
}
/* Full logo, in two layers that line up exactly (same canvas): "DB" slides in
   from the left, then — once it has settled and a pause has passed —
   "Architecture" slides in beside it. Timings are the variables below.
   Both are black ink, inverted to white like the single logo. */
.splash__mark {
  --splash-h: clamp(96px, 16vw, 140px);  /* height of the "DB" letters */
  --db-in: 0.9s;                         /* DB slide duration */
  --arch-pause: 1.05s;                   /* wait after DB has landed */
  --arch-in: 0.9s;                       /* Architecture slide duration */
  position: relative;
  width: min(86vw, calc(var(--splash-h) * var(--ratio, 2.76)));
  aspect-ratio: var(--ratio, 2.76);
}
.splash__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: invert(1);
  opacity: 0; /* hidden until the images have loaded (.is-ready) */
}
.splash.is-ready .splash__layer--db {
  animation: splashDbIn var(--db-in) var(--ease-out) both;
}
.splash.is-ready .splash__layer--arch {
  animation: splashArchIn var(--arch-in) var(--ease-out) calc(var(--db-in) + var(--arch-pause)) both;
}
@keyframes splashDbIn {
  from { opacity: 0; transform: translateX(-32vw); }
  45%  { opacity: 1; }
  to   { opacity: 1; transform: none; }
}
@keyframes splashArchIn {
  from { opacity: 0; transform: translateX(-9%); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  /* No sliding: the whole logo simply appears. */
  .splash.is-ready .splash__layer--db,
  .splash.is-ready .splash__layer--arch {
    animation: none;
    opacity: 1;
  }
}

/* The homepage slideshow waits underneath: first slide's zoom + progress dot
   hold their first frame until the splash goes (hero.js holds the timer). */
html.splash-on .hero__slide.is-active .hero__img,
html.splash-on .hero__dot.is-active::after {
  animation-play-state: paused;
}
@media (prefers-reduced-motion: reduce) {
  .splash.is-leaving {
    transition: none;
  }
}
.nav {
  display: flex;
  align-items: center;
  gap: clamp(1.4rem, 2.4vw, 2.6rem);
}
.nav__link {
  position: relative;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-block: 0.4rem;
  transition: color var(--dur) var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 100%;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--dur) var(--ease);
}
.nav__link:hover::after,
.nav__link.is-active::after {
  transform: scaleX(1);
  transform-origin: left;
}
.nav__link.is-active {
  color: var(--ink);
}
.nav__cta {
  margin-left: 0.4rem;
}

/* Whole-pixel lines on whole-pixel rows, or phones draw the three lines at
   different thicknesses. The header leaves an odd 65px (66 minus its border)
   to centre in, hence 45px tall with 1px of padding under the lines. */
.nav-toggle {
  display: none;
  width: 44px;
  height: 45px;
  padding: 0 0 1px;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  margin-right: -10px;
}
.nav-toggle span {
  display: block;
  height: 2px;
  width: 24px;
  margin-inline: auto;
  background: var(--ink);
  transition:
    transform 0.2s var(--ease),
    opacity 0.15s var(--ease);
}
body.nav-open .nav-toggle span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
body.nav-open .nav-toggle span:nth-child(2) {
  opacity: 0;
}
body.nav-open .nav-toggle span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}
/* Mobile page swipe (main.js): the page slides away in the swipe direction
   and fades while the next one loads. */
body.page-leave main,
body.page-leave .site-footer {
  opacity: 0;
  transition:
    opacity 0.2s var(--ease),
    transform 0.2s var(--ease);
}
body.page-leave--next main,
body.page-leave--next .site-footer {
  transform: translateX(-8vw);
}
body.page-leave--prev main,
body.page-leave--prev .site-footer {
  transform: translateX(8vw);
}
/* The open menu is light, so the logo and the close icon are always dark —
   including over the homepage, where the header is otherwise white. */
body.nav-open .site-header .brand__logo {
  filter: none;
}
body.nav-open .site-header .brand,
body.nav-open .site-header .brand__mark {
  color: var(--ink);
}
body.nav-open .site-header .nav-toggle span {
  background: var(--ink);
}

/* Mobile drawer */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--bone);
  padding: calc(var(--header-h) + 2rem) var(--gutter) 3rem;
  display: flex;
  flex-direction: column;
  overflow-y: auto; /* drawer scrolls its own content while the body is locked */
  -webkit-overflow-scrolling: touch;
  transform: translateY(-100%);
  visibility: hidden;
  transition:
    transform 0.26s var(--ease-out),
    visibility 0.26s;
}
@media (max-height: 640px) {
  .mobile-nav__list {
    margin-top: 0;
    margin-bottom: 0;
  }
}
body.nav-open .mobile-nav {
  transform: translateY(0);
  visibility: visible;
}
.mobile-nav__list {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  margin-top: auto;
  margin-bottom: auto;
}
.mobile-nav__link {
  font-family: var(--font-display);
  font-size: clamp(2rem, 9vw, 3rem);
  color: var(--ink);
  padding-block: 0.35rem;
  display: flex;
  align-items: baseline;
  gap: 1rem;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.22s var(--ease),
    transform 0.22s var(--ease),
    color 0.2s;
}
.mobile-nav__link .num {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  color: var(--brass-deep);
}
.mobile-nav__link.is-active {
  color: var(--brass-deep);
}
body.nav-open .mobile-nav__link {
  opacity: 1;
  transform: none;
  transition-delay: calc(0.025s * var(--i, 0) + 0.04s);
}
.mobile-nav__footer {
  border-top: 1px solid var(--line);
  padding-top: 1.5rem;
  color: var(--muted);
  font-size: var(--fs-small);
}
.mobile-nav__footer a {
  color: var(--ink);
}

/* ---- 8. Footer ------------------------------------------------------------ */
.site-footer {
  background: var(--ink);
  color: #b9b1a4;
  padding-block: clamp(3.5rem, 7vw, 6rem) 2rem;
}
.site-footer h2 {
  color: #f4efe6;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 600;
  margin-bottom: 1.3rem;
}
.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: clamp(2rem, 5vw, 4rem);
}
.footer-brand__mark {
  color: #f4efe6;
  height: 40px;
  width: auto;
  margin-bottom: 1.4rem;
}
.footer-brand p {
  color: #9a9184;
  max-width: 34ch;
  font-size: var(--fs-small);
}
.footer-col a {
  color: #b9b1a4;
  transition: color var(--dur) var(--ease);
  display: inline-block;
  padding-block: 0.3rem;
}
.footer-col a:hover {
  color: #fff;
}
.footer-contact li {
  padding-block: 0.3rem;
  color: #b9b1a4;
  font-size: var(--fs-small);
  overflow-wrap: anywhere;
}
.footer-contact a:hover {
  color: #fff;
}
.social {
  display: flex;
  gap: 1rem;
  margin-top: 1.5rem;
}
.social a {
  width: 68px;
  height: 68px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #cfc7ba;
  transition: all var(--dur) var(--ease);
}
.social a:hover {
  background: var(--brass-deep);
  border-color: var(--brass-deep);
  color: #fff;
  transform: translateY(-3px);
}
.social svg {
  width: 29px;
  height: 29px;
}
.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.75rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.78rem;
  color: #8a8175;
}
.footer-bottom a {
  color: #a9a093;
}
.footer-bottom a:hover {
  color: #fff;
}

/* ---- 9. Hero (Ken Burns) -------------------------------------------------- */
.hero {
  position: relative;
  height: 100svh;
  min-height: 600px;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  background: var(--ink);
  color: #fff;
}
.hero__slides {
  position: absolute;
  inset: 0;
}
.hero__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.7s var(--ease);
  z-index: 1;
}
.hero__slide.is-active {
  opacity: 1;
  z-index: 2;
}
/* Blur-up placeholder of the server-rendered first slide (set by build.mjs). */
.hero__lqip {
  background: var(--lqip) center / cover;
}
@media (orientation: portrait) {
  .hero__lqip {
    background-image: var(--lqip-phone, var(--lqip));
  }
}
/* Ken Burns, gentle: each photo starts slightly zoomed in and eases out to the
   full frame over exactly one slide's time, so it lands on the whole photo
   just as the next one fades in. The resting state is that full frame too, so
   nothing jumps when a slide hands over. */
.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  will-change: transform;
}
.hero__slide.is-active .hero__img {
  animation: kb1 var(--hero-interval, 6s) var(--ease) forwards;
}
.hero__slide.is-active:nth-child(2n) .hero__img {
  animation-name: kb2;
}
.hero__slide.is-active:nth-child(3n) .hero__img {
  animation-name: kb3;
}
.hero__slide.is-active:nth-child(4n) .hero__img {
  animation-name: kb4;
}
/* Four drift directions so consecutive slides don't move alike. Keep each
   start pan under (zoom − 1) ÷ 2, or the photo's edge shows. */
@keyframes kb1 {
  from {
    transform: scale(1.08) translate(-1.5%, -1%);
  }
  to {
    transform: none;
  }
}
@keyframes kb2 {
  from {
    transform: scale(1.08) translate(1.5%, 1%);
  }
  to {
    transform: none;
  }
}
@keyframes kb3 {
  from {
    transform: scale(1.07) translate(1%, -1.5%);
  }
  to {
    transform: none;
  }
}
@keyframes kb4 {
  from {
    transform: scale(1.07) translate(-1%, 1.5%);
  }
  to {
    transform: none;
  }
}
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(20, 17, 13, 0.42) 0%,
    rgba(20, 17, 13, 0.1) 28%,
    rgba(20, 17, 13, 0.34) 62%,
    rgba(20, 17, 13, 0.82) 100%
  );
}
.hero__content {
  position: relative;
  z-index: 4;
  width: 100%;
  max-width: var(--maxw-wide);
  margin-inline: auto;
  padding: 0 var(--gutter) clamp(3.5rem, 9vh, 7rem);
}
.hero__eyebrow {
  color: rgba(255, 255, 255, 0.85);
}
.hero__eyebrow::before {
  background: rgba(255, 255, 255, 0.7);
}
.hero__title {
  font-size: var(--fs-hero);
  font-weight: 400;
  color: #fff;
  letter-spacing: -0.015em;
  margin: 1.1rem 0 0;
  max-width: 16ch;
  text-wrap: balance;
}
.hero__tagline {
  font-size: var(--fs-lead);
  color: rgba(255, 255, 255, 0.9);
  margin-top: 1.4rem;
  max-width: 46ch;
  font-weight: 300;
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 2.2rem;
}
.hero__meta {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(3.5rem, 9vh, 7rem);
  z-index: 4;
  writing-mode: vertical-rl;
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
  display: flex;
  align-items: center;
  gap: 1rem;
}
.hero__meta::after {
  content: "";
  height: 60px;
  width: 1px;
  background: rgba(255, 255, 255, 0.5);
}
.hero__dots {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: 1.6rem;
  z-index: 5;
  display: flex;
  gap: 0.5rem;
}
.hero__dot {
  /* 30px each, shrinking to fit when there are many slides on a phone. */
  flex: 0 1 30px;
  min-width: 0;
  height: 2px;
  background: rgba(255, 255, 255, 0.35);
  overflow: hidden;
}
.hero__dot::after {
  content: "";
  display: block;
  height: 100%;
  width: 100%;
  background: #fff;
  transform: translateX(-101%);
}
.hero__dot.is-active::after {
  animation: heroDot var(--hero-interval, 6s) linear forwards;
}
@keyframes heroDot {
  to {
    transform: translateX(0);
  }
}

/* ---- 10. Reveal on scroll ------------------------------------------------- */
/* Only hide when JS is running, so content is always visible without JS. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity 0.9s var(--ease-out),
    transform 0.9s var(--ease-out);
}
.js [data-reveal="fade"] {
  transform: none;
}
.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
}
[data-reveal-delay="1"] {
  transition-delay: 0.1s;
}
[data-reveal-delay="2"] {
  transition-delay: 0.2s;
}
[data-reveal-delay="3"] {
  transition-delay: 0.3s;
}
[data-reveal-delay="4"] {
  transition-delay: 0.4s;
}

/* ---- 11. Home: intro + featured ------------------------------------------ */
.intro-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 6rem);
  align-items: center;
}
.intro-split__figure {
  position: relative;
  aspect-ratio: 4 / 5;
  overflow: hidden;
}
.intro-split__figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.intro-split__figure .tag {
  position: absolute;
  left: 1.25rem;
  bottom: 1.25rem;
  background: rgba(247, 244, 239, 0.92);
  color: var(--ink);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.6em 1em;
}
/* No figure beside it, so the block spans the container — cap the heading to a
   readable measure (paragraphs already cap at 68ch). */
.studio-intro .section-title {
  max-width: 24ch;
}
.stat-row {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 5vw, 3.5rem);
  margin-top: 2.5rem;
}
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4vw, 3rem);
  color: var(--ink);
  line-height: 1;
}
.stat__label {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.5rem;
}

/* Disciplines list (homepage services preview) */
.disc-list {
  border-top: 1px solid var(--line);
}
.disc-list li {
  padding: 1.1rem 0;
  border-bottom: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: baseline;
}
.disc-list__name {
  font-family: var(--font-display);
  font-size: 1.35rem;
  color: var(--ink);
  font-variant-numeric: lining-nums;
}
.disc-list__num {
  color: var(--brass-deep);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
}

.feature-card {
  position: relative;
  overflow: hidden;
  display: block;
  background: var(--cream);
}
.feature-card__media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--cream-deep);
}
.feature-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease-out);
}
.feature-card:hover .feature-card__img {
  transform: scale(1.05);
}
.feature-card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(1.25rem, 2.5vw, 2rem);
  color: #fff;
  background: linear-gradient(
    180deg,
    transparent 40%,
    rgba(20, 17, 13, 0.72) 100%
  );
  opacity: 0.96;
  transition: opacity var(--dur) var(--ease);
}
.feature-card__cat {
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.85);
  margin-bottom: 0.5rem;
}
.feature-card__title {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.4vw, 2rem);
  color: #fff;
  font-weight: 500;
}
.feature-card__loc {
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, 0.8);
  margin-top: 0.2rem;
}
.feature-card__plus {
  position: absolute;
  top: clamp(1rem, 2vw, 1.5rem);
  right: clamp(1rem, 2vw, 1.5rem);
  width: 42px;
  height: 42px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  opacity: 0;
  transform: scale(0.85);
  transition: all var(--dur) var(--ease);
}
.feature-card:hover .feature-card__plus {
  opacity: 1;
  transform: scale(1);
}

/* Card slider (homepage "Recent projects") — native horizontal scrolling with
   snap points, so touch, trackpad, arrow buttons and keyboard all work.
   The track bleeds to the window edges but its first card lines up with the
   page gutter, which is what --edge computes. */
.section-head--split {
  max-width: none;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 1rem 2rem;
}
.slider-tools {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 1.75rem);
  flex-wrap: wrap;
}
.slider-btns {
  display: flex;
  gap: 0.5rem;
}
.slider-btns[hidden] {
  display: none;
} /* author display: flex would beat [hidden] */
.slider-btn {
  width: 46px;
  height: 46px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--ink);
  transition:
    background var(--dur) var(--ease),
    color var(--dur) var(--ease),
    border-color var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}
.slider-btn:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: #f7f2ea;
}
.slider-btn[disabled] {
  opacity: 0.3;
  cursor: default;
}
.slider-btn[disabled]:hover {
  background: none;
  border-color: var(--line-strong);
  color: var(--ink);
}

.card-slider {
  position: relative;
}
.card-slider__track {
  --edge: max(
    var(--gutter),
    calc((100% - var(--maxw-wide)) / 2 + var(--gutter))
  );
  display: flex;
  gap: clamp(1rem, 2vw, 1.75rem);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--edge);
  scroll-behavior: smooth;
  padding-block: 3px; /* breathing room for the focus ring */
  scrollbar-width: none; /* our own progress bar stands in for it */
  -ms-overflow-style: none;
}
.card-slider__track::-webkit-scrollbar {
  display: none;
}
.card-slider__track > * {
  flex: 0 0 clamp(258px, 76vw, 560px);
  scroll-snap-align: start;
}
.card-slider__track > :first-child {
  margin-inline-start: var(--edge);
}
.card-slider__track > :last-child {
  margin-inline-end: var(--edge);
}
.card-slider__track.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
}
.card-slider__track.is-dragging .feature-card__img {
  transform: none;
}
/* Set while the wheel is turning: free scrolling, then it snaps back on idle. */
.card-slider__track.is-free {
  scroll-snap-type: none;
}
/* Mouse users get a grab cursor so it is obvious the row can be dragged. */
@media (hover: hover) and (pointer: fine) {
  .card-slider__track {
    cursor: grab;
  }
  .stage__viewport {
    cursor: grab;
  }
  .stage__track.is-dragging {
    cursor: grabbing;
  }
}

.card-slider__bar {
  position: relative;
  height: 2px;
  background: var(--line-strong);
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
  cursor: pointer;
  touch-action: pan-y; /* sideways drags move the bar; vertical still scrolls */
}
/* The bar is only 2px tall, so give it a comfortable invisible grab area. */
.card-slider__bar::before {
  content: "";
  position: absolute;
  inset: -12px 0;
}
.card-slider__fill {
  position: absolute;
  top: -1px;
  bottom: -1px;
  left: 0;
  width: 30%;
  background: var(--ink);
  cursor: grab;
  transition:
    left 0.25s var(--ease),
    width 0.25s var(--ease),
    top 0.2s var(--ease),
    bottom 0.2s var(--ease);
}
.card-slider__bar:hover .card-slider__fill,
.card-slider__bar.is-dragging .card-slider__fill {
  top: -2px;
  bottom: -2px;
}
/* Follow the pointer exactly while it's being dragged. */
.card-slider__bar.is-dragging .card-slider__fill {
  cursor: grabbing;
  transition: top 0.2s var(--ease), bottom 0.2s var(--ease);
}
.card-slider__bar.is-dragging {
  cursor: grabbing;
}
.card-slider__hint {
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.9rem;
}

/* ---- 12. Services --------------------------------------------------------- */
.services-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
  gap: 0;
  border-top: 1px solid var(--line);
}
.service-card {
  position: relative;
  padding: clamp(1.75rem, 3vw, 2.75rem);
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: transparent;
  overflow: hidden;
  transition: background var(--dur) var(--ease);
}
.service-card::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  height: 2px;
  width: 100%;
  background: var(--brass);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.6s var(--ease);
}
.service-card:hover {
  background: var(--paper);
}
.service-card:hover::before {
  transform: scaleX(1);
}
.service-card__num {
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  color: var(--brass-deep);
}
.service-card__icon {
  width: 34px;
  height: 34px;
  color: var(--ink);
  margin: 1.5rem 0 1.25rem;
  stroke-width: 1.2;
}
.service-card__title {
  font-size: var(--fs-h3);
  margin-bottom: 0.75rem;
}
.service-card__text {
  color: var(--muted);
  font-size: 0.96rem;
}
.service-card__list {
  margin-top: 1.1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.6rem;
}
.service-card__list li {
  font-size: 0.74rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--line-strong);
  border-radius: 100px;
  padding: 0.3em 0.85em;
}

/* ---- 13. Process ---------------------------------------------------------- */
.process {
  display: grid;
  gap: 0;
}
.process-step {
  display: grid;
  grid-template-columns: minmax(90px, 130px) 1fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(2rem, 4vw, 3.25rem);
  border-top: 1px solid var(--line);
  align-items: start;
  position: relative;
}
.process-step:last-child {
  border-bottom: 1px solid var(--line);
}
.process-step__num {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  color: var(--brass);
  line-height: 0.9;
  font-weight: 400;
}
.process-step__body {
  max-width: 60ch;
}
.process-step__title {
  font-size: var(--fs-h3);
  margin-bottom: 0.75rem;
}
.process-step__title .k {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.6rem;
  font-weight: 500;
}
.process-step__text {
  color: var(--muted);
}
.process-step:hover .process-step__num {
  color: var(--brass-deep);
}

/* ---- 14. About ------------------------------------------------------------ */
.about-hero {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: start;
}
.about-hero--single {
  grid-template-columns: 1fr;
  max-width: 74ch;
}

/* ---- About intro band (EXPERIMENTAL) --------------------------------------
   The intro copy sits on a wide project photo that runs the full width of the
   window, starting just above the text and ending just below it. The photo is
   sized with object-fit:cover and re-crops as the window resizes, so it fills
   the band at every width — no letterboxing, no background showing through.
   Deleting this block and the .about-band__media div in about.html reverts it. */
.about-band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(2.75rem, 6vw, 4.75rem);
}
.about-band > .container {
  position: relative;
  z-index: 1;
}
.about-band__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--cream-deep);
}
.about-band__media picture {
  display: block;
  width: 100%;
  height: 100%;
}
.about-band__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.07); /* covers the soft edge the blur leaves behind */
  filter: blur(0.8px) saturate(0.85); /* just enough softening to sit behind text */
}
/* Over a photo the site's grey body colours lose too much contrast, so the
   copy on this band only is darkened a step. */
.about-band p {
  color: var(--ink);
}
/* The wash: heaviest under the copy, lighter to the right so the photo reads.
   Raise the alphas to mute the photo further, lower them to show more of it. */
.about-band__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    100deg,
    rgba(244, 241, 234, 0.68) 0%,
    rgba(244, 241, 234, 0.6) 46%,
    rgba(244, 241, 234, 0.3) 100%
  );
}
/* TEST — "glass" version of the band: the photo at full strength, the copy in a
   frosted panel that blurs the photo behind it. Remove the about-band--glass
   class in about.html to go back to the washed-out photo above. */
.about-band--glass .about-band__media img {
  filter: none;
  transform: none;
}
.about-band--glass .about-band__media::after {
  display: none;
}
.about-band--glass {
  padding-block: clamp(3.5rem, 9vw, 7rem);
}
.about-band__panel {
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  background: rgba(244, 241, 234, 0.62);
  -webkit-backdrop-filter: blur(16px) saturate(1.15);
  backdrop-filter: blur(16px) saturate(1.15);
  border: 1px solid rgba(255, 255, 255, 0.45);
  box-shadow: 0 18px 50px -20px rgba(28, 26, 23, 0.35);
}
/* Browsers without backdrop blur get a more solid panel so text stays readable. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .about-band__panel {
    background: rgba(244, 241, 234, 0.9);
  }
}
.about-figure {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: var(--cream-deep);
}
.about-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.values-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.value h3 {
  font-size: var(--fs-h3);
  margin-bottom: 0.6rem;
}
.value h3 .idx {
  color: var(--brass-deep);
  font-family: var(--font-sans);
  font-size: 0.8rem;
  letter-spacing: 0.1em;
  margin-right: 0.6rem;
}
.value p {
  color: var(--muted);
  font-size: 0.96rem;
}
.section--ink .value p {
  color: #b3aa9c;
}
.section--ink .value h3 .idx {
  color: #c2a173;
}
.section--ink .eyebrow {
  color: #c2a173;
}
/* Pull quote */
.pull-quote {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.7rem, 4vw, 3.1rem);
  line-height: 1.22;
  color: var(--ink);
  max-width: 20ch;
}
.pull-quote--wide {
  max-width: 24ch;
  margin-inline: auto;
  text-align: center;
}

/* ---- 15. Projects module (self-contained, swappable) --------------------- */
.projects-app {
  --stage-ratio: 3 / 2;
}
.projects-app__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
}
.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.filter-chip {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0.55em 1.1em;
  border: 1px solid var(--line-strong);
  border-radius: 100px;
  transition: all var(--dur) var(--ease);
}
.filter-chip:hover {
  color: var(--ink);
  border-color: var(--ink);
}
.filter-chip.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: #f7f2ea;
}
.projects-picker {
  display: none;
}
.projects-count {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.projects-layout {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}

.projects-index {
  position: sticky;
  top: calc(var(--header-h) + 1.5rem);
  max-height: calc(100svh - var(--header-h) - 3rem);
  overflow-y: auto;
  padding-right: 0.5rem;
}
.projects-index__item {
  width: 100%;
  text-align: left;
  display: block;
  padding: 0.95rem 0.5rem;
  border-bottom: 1px solid var(--line);
  transition: padding var(--dur) var(--ease);
  position: relative;
}
/* Selected-project marker: a bold vertical bar beside the name and category.
   Hover previews it faintly; the selected project shows it in full. */
.projects-index__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.95rem;
  bottom: 0.95rem;
  width: 3px;
  border-radius: 2px;
  background: var(--brass-deep);
  opacity: 0;
  transform: scaleY(0.4);
  transition:
    transform var(--dur) var(--ease),
    opacity var(--dur) var(--ease);
}
.projects-index__item:hover {
  padding-left: 1.25rem;
}
.projects-index__item:hover::before {
  opacity: 0.35;
  transform: scaleY(1);
}
.projects-index__item.is-active {
  padding-left: 1.25rem;
}
.projects-index__item.is-active::before {
  opacity: 1;
  transform: scaleY(1);
}
.projects-index__title {
  display: block; /* own line, so the name never runs into the category */
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--muted);
  line-height: 1.2;
  transition: color var(--dur) var(--ease);
}
.projects-index__item:hover .projects-index__title,
.projects-index__item.is-active .projects-index__title {
  color: var(--ink);
}
.projects-index__meta {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 0.25rem;
}
.projects-index__item.is-active .projects-index__meta {
  color: var(--brass-deep);
}

.stage {
  position: relative;
}
/* Never taller than the window (under the header), so a whole image is in
   view at once: tall images shrink to fit (object-fit: contain) instead of
   running off the bottom of the screen. The explicit width keeps the frame
   full width when the cap kicks in (otherwise aspect-ratio narrows it and the
   arrows end up outside it). */
.stage__viewport {
  position: relative;
  overflow: hidden;
  width: 100%;
  aspect-ratio: var(--stage-ratio);
  max-height: calc(100svh - var(--header-h) - 3rem);
  background: var(--cream);
  border: 1px solid var(--line);
  touch-action: pan-y;
}
.stage__track {
  display: flex;
  height: 100%;
  transition: transform 0.42s var(--ease);
}
.stage__track.is-dragging {
  will-change: transform;
  transition: none;
}
.stage__slide {
  position: relative;
  flex: 0 0 100%;
  height: 100%;
}
.stage__slide picture {
  position: absolute;
  inset: 0;
}
.stage__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.stage__img--cover {
  object-fit: cover;
}
.stage.is-loading .stage__viewport {
  background: var(--cream-deep);
}

.stage__frame {
  position: relative;
}
.stage__navs {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: clamp(0.75rem, 2vw, 1.25rem);
  pointer-events: none;
  z-index: 3;
}
.stage__nav {
  pointer-events: auto;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgba(244, 241, 234, 0.9);
  color: var(--ink);
  display: grid;
  place-items: center;
  z-index: 3;
  box-shadow: var(--shadow-md);
  transition:
    background 0.18s var(--ease),
    transform 0.18s var(--ease),
    opacity 0.18s;
}
.stage__nav:hover {
  background: var(--ink);
  color: #f7f2ea;
}
.stage__nav--prev:hover {
  transform: translateX(-3px);
}
.stage__nav--next:hover {
  transform: translateX(3px);
}

.stage__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1.25rem;
  flex-wrap: wrap;
}
.stage__caption {
  max-width: 60ch;
}
.stage__caption h2 {
  font-size: var(--fs-h3);
  margin-bottom: 0.35rem;
}
.stage__caption p {
  color: var(--muted);
  font-size: 0.95rem;
}
.stage__caption .stage__desc + .stage__desc {
  margin-top: 0.85em;
}
/* Project status, e.g. "Completed": a quiet label between title and text. */
.stage__caption .stage__status {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 0.9rem;
}
.stage__caption .stage__status::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brass);
}
/* Any status other than "Completed" (e.g. "Coming Soon"): an open ring. */
.stage__caption .stage__status.is-pending::before {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--brass);
}
.stage__caption .meta {
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass-deep);
  margin-bottom: 0.6rem;
}
.stage__controls {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  flex-shrink: 0;
}
.stage__counter {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--ink);
  letter-spacing: 0.05em;
}
.stage__counter .sep {
  color: var(--muted);
  margin-inline: 0.3rem;
}
.stage__dots {
  display: flex;
  gap: 0;
  flex-shrink: 0;
}
/* 8px visual dot inside a 24px touch target (WCAG 2.5.8) via transparent padding */
.stage__dot {
  width: 8px;
  height: 8px;
  padding: 8px;
  box-sizing: content-box;
  background-clip: content-box;
  border-radius: 50%;
  background-color: var(--line-strong);
  transition:
    background-color var(--dur) var(--ease),
    transform var(--dur) var(--ease);
}
.stage__dot.is-active {
  background-color: var(--brass-deep);
  transform: scale(1.25);
}
.stage__dot.is-edge {
  transform: scale(0.55);
}

.stage__thumbs {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.25rem;
  overflow-x: auto;
  padding-bottom: 0.4rem;
  scrollbar-width: thin;
}
.stage__thumb {
  flex: 0 0 auto;
  width: 84px;
  height: 60px;
  overflow: hidden;
  opacity: 0.55;
  border: 1px solid transparent;
  transition:
    opacity 0.18s var(--ease),
    border-color 0.18s var(--ease);
}
.stage__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.stage__thumb:hover {
  opacity: 0.85;
}
.stage__thumb.is-active {
  opacity: 1;
  border-color: var(--brass);
}

/* <picture> is a wrapper, not a box: without this it keeps its natural height and
   the img's height:100% resolves to auto, so object-fit never crops and a fixed
   aspect-ratio frame is left half empty. (The Projects stage is deliberately
   excluded — it letterboxes with object-fit: contain.) */
.intro-split__figure picture,
.about-figure picture,
.feature-card__media picture {
  display: block;
  height: 100%;
}

/* Blur-up image loading */
picture {
  display: block;
  width: 100%;
  height: 100%;
}
.blur-target {
  opacity: 0;
  background-size: cover;
  background-position: center;
  transition: opacity 0.7s var(--ease);
}
.blur-target.is-loaded {
  opacity: 1;
}
.imgwrap {
  position: relative;
  overflow: hidden;
  background-size: cover;
  background-position: center;
}

/* ---- 16. Forms ------------------------------------------------------------ */
.form {
  display: grid;
  gap: 1.4rem;
}
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.4rem;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.field--full {
  grid-column: 1 / -1;
}
.field label {
  font-size: 0.76rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}
.field label .req {
  color: var(--brass-deep);
}
.field input,
.field textarea,
.field select {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 0.85em 1em;
  color: var(--ink);
  transition:
    border-color var(--dur) var(--ease),
    box-shadow var(--dur) var(--ease);
  width: 100%;
  font-size: 0.98rem;
}
.field textarea {
  resize: vertical;
  min-height: 140px;
}
.field select {
  appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%236f665b' stroke-width='1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 1.1em center;
  padding-right: 2.6em;
}
.field input:focus,
.field textarea:focus,
.field select:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(154, 123, 78, 0.14);
}
.field.is-invalid input,
.field.is-invalid textarea,
.field.is-invalid select {
  border-color: #b4442f;
  box-shadow: 0 0 0 3px rgba(180, 68, 47, 0.12);
}
.field__error {
  font-size: 0.78rem;
  color: #b4442f;
  min-height: 1em;
  opacity: 0;
  transform: translateY(-3px);
  transition: all 0.3s var(--ease);
}
.field.is-invalid .field__error {
  opacity: 1;
  transform: none;
}
.form__status {
  padding: 1em 1.25em;
  border-radius: var(--radius);
  font-size: 0.95rem;
  display: none;
}
.form__status.is-success {
  display: block;
  background: #eef3ec;
  border: 1px solid #cde0c6;
  color: #3c5a34;
}
.form__status.is-error {
  display: block;
  background: #f9ece9;
  border: 1px solid #ecccc4;
  color: #90402f;
}
.form__consent {
  font-size: 0.82rem;
  color: var(--muted);
}
.form__consent a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.contact-split {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.contact-info__block {
  margin-bottom: 2rem;
}
.contact-info__block h2 {
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.6rem;
  font-weight: 600;
}
.contact-info__block a,
.contact-info__block p {
  color: var(--ink);
  font-size: 1.05rem;
}
.contact-info__block a:hover {
  color: var(--brass-deep);
}
.contact-info .hours li {
  display: flex;
  justify-content: space-between;
  gap: 2rem;
  max-width: 320px;
  padding-block: 0.2rem;
  color: var(--ink-soft);
  font-size: 0.95rem;
  border-bottom: 1px dotted var(--line-strong);
}

/* ---- 17. Utilities -------------------------------------------------------- */
.text-center {
  text-align: center;
}
.mx-auto {
  margin-inline: auto;
}
.mt-sm {
  margin-top: 1rem;
}
.mt-md {
  margin-top: 2rem;
}
.mt-lg {
  margin-top: 3rem;
}
.divider {
  height: 1px;
  background: var(--line);
  border: 0;
}
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.skip-link {
  position: absolute;
  left: 1rem;
  top: -60px;
  z-index: 200;
  background: var(--ink);
  color: #fff;
  padding: 0.7em 1.2em;
  border-radius: var(--radius);
  transition: top 0.3s var(--ease);
}
.skip-link:focus {
  top: 1rem;
}
.page-header {
  padding-top: calc(var(--header-h) + clamp(3rem, 8vw, 6rem));
  padding-bottom: clamp(2rem, 5vw, 4rem);
}
.page-header .eyebrow {
  margin-bottom: 1.2rem;
}
.page-header h1 {
  font-size: var(--fs-display);
  font-weight: 400;
}
.page-header .lead {
  margin-top: 1.4rem;
  max-width: 58ch;
}
.breadcrumb {
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 1.5rem;
}
.breadcrumb a {
  text-decoration: underline;
  text-underline-offset: 2px;
}
.breadcrumb a:hover {
  color: var(--ink);
}

/* The band is the last thing on every page, so it is sized to one fixed
   height rather than left to follow its copy — a short heading centres in
   the same box a two-line one fills, so all pages end identically. The
   min-height is the tallest natural content: 2 display lines + 2 lead lines
   + the margins and the button. */
.cta-band {
  background: var(--ink);
  color: #e9e2d6;
  text-align: center;
  padding-block: clamp(2.2rem, 4.2vw, 4.2rem);
}
.cta-band .container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(2.16 * var(--fs-display) + 3.2 * var(--fs-lead) + 6.6rem);
}
.cta-band h2 {
  color: #f6f1e8;
  font-size: var(--fs-display);
  font-weight: 400;
  margin-bottom: 1.2rem;
  max-width: 20ch;
}
.cta-band p {
  color: #b3aa9c;
  margin-bottom: 2.2rem;
  max-width: 46ch;
}
.cta-band .btn--ghost {
  --btn-fg: #fff;
  border-color: rgba(255, 255, 255, 0.5);
}
.cta-band .btn--ghost:hover {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
}

/* ---- 18. Responsive ------------------------------------------------------- */
@media (max-width: 1024px) {
  .footer-grid {
    grid-template-columns: 1fr 1fr;
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
  .projects-layout {
    grid-template-columns: 250px minmax(0, 1fr);
  }
}
@media (max-width: 860px) {
  :root {
    --header-h: 66px;
  }
  .nav {
    display: none;
  }
  .nav-toggle {
    display: flex;
  }
  .intro-split {
    grid-template-columns: 1fr;
  }
  .intro-split__figure {
    aspect-ratio: 4 / 3;
    order: -1;
  }
  .about-hero {
    grid-template-columns: 1fr;
  }
  .contact-split {
    grid-template-columns: 1fr;
  }

  /* Projects: side list becomes a horizontal strip above the slider */
  .projects-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  /* No transition here: aspect-ratio is not reliably interpolable, and a
     half-applied one leaves the frame stuck at the previous photo shape. */
  .stage__viewport {
    aspect-ratio: var(--stage-ratio-img, var(--stage-ratio));
  }
  .projects-index {
    display: none;
  }

  /* Categories stay on one swipeable line however many there are. */
  .filter-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 0.2rem;
  }
  .filter-chips::-webkit-scrollbar {
    display: none;
  }
  .filter-chip {
    flex: 0 0 auto;
  }

  .projects-picker {
    display: block;
    margin-bottom: 1.25rem;
  }
  .projects-picker__label {
    display: block;
    font-size: 0.68rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--brass-deep);
    margin-bottom: 0.5rem;
  }
  .projects-picker__field {
    position: relative;
  }
  .projects-picker select {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    font-family: var(--font-display);
    font-size: 1.15rem;
    color: var(--ink);
    background: transparent;
    border: 1px solid var(--line-strong);
    border-radius: 2px;
    padding: 0.8rem 2.75rem 0.8rem 1rem;
    line-height: 1.3;
    text-overflow: ellipsis;
  }
  .projects-picker select:focus-visible {
    outline: 2px solid var(--brass);
    outline-offset: 2px;
  }
  .projects-picker__chevron {
    position: absolute;
    right: 1rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    color: var(--muted);
  }
  .projects-index__item:hover,
  .projects-index__item.is-active {
    padding-left: 1.1rem;
  }
  .projects-index__item::before {
    display: none;
  }
  .projects-index__item.is-active {
    background: var(--ink);
    border-color: var(--ink);
  }
  .projects-index__title {
    font-family: var(--font-sans);
    font-size: 0.82rem;
    letter-spacing: 0.06em;
  }
  .projects-index__item.is-active .projects-index__title {
    color: #f7f2ea;
  }
  .projects-index__meta {
    display: none;
  }

  /* The drawer menu already lists these, so the column is dead weight here. */
  .footer-col--explore {
    display: none;
  }
  .social {
    gap: 1.05rem;
  }
  .social a {
    width: 72px;
    height: 72px;
  }
  .social svg {
    width: 31px;
    height: 31px;
  }

  /* Narrow screens: the copy spans the full width, so the wash does too. */
  .about-band__media::after {
    background: linear-gradient(
      rgba(244, 241, 234, 0.68),
      rgba(244, 241, 234, 0.64)
    );
  }
  /* Glass band on phones: plain copy like every other page, with the photo
     underneath it instead of behind it. */
  .about-band--glass {
    display: flex;
    flex-direction: column;
    gap: clamp(2rem, 7vw, 2.75rem);
    padding-block: clamp(3.5rem, 8vw, var(--space-2xl));
  }
  .about-band--glass .about-band__media {
    position: relative;
    order: 1;
    margin-inline: var(--gutter);
    aspect-ratio: 4 / 3;
  }
  .about-band--glass .about-band__panel {
    padding: 0;
    background: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border: 0;
    box-shadow: none;
  }
  .about-band--glass p {
    color: inherit;
  }
  .about-band--glass .lead {
    color: var(--muted);
  }
}
/* The hint names whichever gesture is actually available on the device. */
.card-slider__hint .hint--pointer {
  display: none;
}
@media (hover: hover) and (pointer: fine) {
  .card-slider__hint .hint--touch {
    display: none;
  }
  .card-slider__hint .hint--pointer {
    display: inline;
  }
}
@media (max-width: 560px) {
  .slider-btns {
    display: none;
  } /* swipe is the obvious gesture here */
  .form-grid {
    grid-template-columns: 1fr;
  }
  .footer-grid {
    grid-template-columns: 1fr;
  }
  .hero__meta {
    display: none;
  }
  .stage__nav {
    width: 44px;
    height: 44px;
  }
  .process-step {
    grid-template-columns: 1fr;
    gap: 0.75rem;
  }
  .process-step__num {
    font-size: 2.4rem;
  }
  .stat-row {
    gap: 1.5rem;
  }
  .btn {
    padding: 0.9em 1.5em;
  }
}

/* ---- 19. Reduced motion --------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .hero__slide {
    transition: opacity 0.6s ease !important;
  } /* keep the gentle cross-fade */
  .hero__slide.is-active .hero__img {
    animation: none;
  }
  .hero__dot::after {
    display: none;
  }
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  .feature-card:hover .feature-card__img {
    transform: none;
  }
}
