/* Laddha Constructions — page styles.
   Sits on top of ds/styles.css, which owns the Classical design tokens and
   component classes (.btn, .card, .plate, .tag). Nothing here redefines a token;
   this file only expresses page-level layout, chrome and motion. */

/* ── page ground ─────────────────────────────────────────────────────── */
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
a { color: var(--color-accent-700); text-decoration: none; }
a:hover { color: var(--color-accent-600); }

/* The prototypes expressed larger steps as calc() on --space-8 because the
   design system's scale skips 5, 7 and 9+. Named here once so pages read
   cleanly and the workaround lives in one place. */
:root {
  --gap-page: calc(var(--space-8) * 2);      /* section vertical rhythm, wide  */
  --gap-page-tight: calc(var(--space-8) * 1.6);
  --gap-col: calc(var(--space-8) * 1.25);    /* two-column spread gutter       */
  --gap-block: calc(var(--space-4) * 1.25);  /* paragraph / block separation   */
  --page-max: 1180px;
  /* Height of the fixed header: its vertical padding plus the brand's rendered
     line box, which measures 32px rather than the 25px a naive 1.3rem * 1.2
     suggests. Because the header is fixed it reserves no space in flow, so any
     content that must clear it has to pad by this itself. The extra --space-3
     keeps text off the header's bottom rule rather than flush against it. */
  --header-h: calc(var(--space-4) * 2 + 32px + var(--space-3));
}

.wrap { max-width: var(--page-max); margin: 0 auto; }

/* ── motion ──────────────────────────────────────────────────────────── */
@keyframes kb   { from { transform: scale(1.05); } to { transform: scale(1.20) translateY(-2%); } }
/* Three-slide crossfade. Each slide holds, fades out, stays hidden while the
   other two take their turn, then comes back. Percentages are thirds of the
   cycle with a ~7% overlap either side of each handover, which is what makes
   the change read as a dissolve rather than a cut. */
@keyframes heroFade {
   0%    { opacity: 1; }
  28%    { opacity: 1; }
  35%    { opacity: 0; }
  95%    { opacity: 0; }
 100%    { opacity: 1; }
}
@keyframes kbs  { from { transform: scale(1.04); } to { transform: scale(1.14); } }
@keyframes fadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes fadeUpSm { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@keyframes lineGrow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes drift { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

[data-reveal] { opacity: 0; }
[data-reveal].is-in { animation: drift 1.4s cubic-bezier(.22,.61,.36,1) forwards; }
/* No JavaScript, no IntersectionObserver: show everything rather than nothing. */
.no-js [data-reveal] { opacity: 1; animation: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; animation: none !important; }
  * { animation-duration: .01ms !important; }
  html { scroll-behavior: auto; }
  /* Collapsing the duration would freeze the rotator on whichever slide the
     cycle happened to land on, and stacked slides at opacity 1 would show only
     the last. Show the first and hide the rest: a still hero, not a broken one. */
  .hero--home .hero-frame img { animation: none !important; opacity: 0; }
  .hero--home .hero-frame img:nth-child(1) { opacity: 1; }
}

/* ── header ──────────────────────────────────────────────────────────── */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 40;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-6);
  padding: var(--space-4) var(--space-8);
  background: color-mix(in oklch, var(--color-bg) 84%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--color-divider);
}
/* Home only: the header arrives after the hero copy has settled. */
.site-header--home { animation: fadeIn 2s ease 2.4s both; }

.site-brand {
  /* The header aligns on the baseline, which a replaced element has no useful
     notion of. Give the brand its own flex context so the mark centres against
     the wordmark's cap height instead of hanging off the text baseline. */
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-family: var(--font-heading);
  font-size: 1.3rem; letter-spacing: .04em;
  color: var(--color-text);
  white-space: nowrap;
}
.site-brand span { color: var(--color-accent-700); }
.site-brand:hover { color: var(--color-text); }

/* The mark's artwork sits inside x=18..86 of a 100 viewBox, so it carries its
   own ~18% clear space - the README asks for 14%. No extra padding needed;
   the gap above is what separates it from the wordmark.

   This uses the simplified artwork, not the full mark: the README calls for it
   below 48px because the formation hairline fills in and muddies at small
   sizes. It is also vertically tighter (72 units against 80.8), so it reads
   larger in the same box. */
.site-mark {
  width: 32px; height: 32px;   /* README floor is 26px on screen */
  flex: none;
  display: block;
}

.site-nav {
  display: flex; align-items: baseline; gap: var(--space-6);
  font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
}
.site-nav a { color: var(--color-neutral-700); }
.site-nav a:hover { color: var(--color-accent-700); }
.site-nav a[aria-current="page"] {
  color: var(--color-accent-700);
  border-bottom: 1px solid var(--color-accent);
}

/* Mobile nav — a checkbox toggle so the menu works without JavaScript. */
.nav-toggle { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.nav-toggle-label { display: none; }

/* ── hero ────────────────────────────────────────────────────────────── */
.hero {
  position: relative; overflow: hidden;
  display: grid; align-items: end;
}
/* svh keeps the hero from jumping as mobile browser chrome hides and shows. */
/* min-height must not exceed what a short window can actually show, or the
   bottom-pinned copy is pushed up under the fixed header. 620px did exactly
   that below a ~620px viewport; 460px leaves the hero room to shrink. */
.hero--home { height: 100svh; min-height: 460px; }
.hero--sub  { height: 52svh;  min-height: 340px; }
.hero--contact { height: 46svh; min-height: 300px; }

.hero-frame { position: absolute; inset: 0; overflow: hidden; }
.hero-frame img { width: 100%; height: 100%; object-fit: cover; }

/* Home hero rotator: three slides stacked in the same box, crossfading.
   Stacking rather than sliding keeps the scrim and copy untouched - only the
   photograph changes underneath them. */
.hero--home .hero-frame img {
  position: absolute; inset: 0;
  animation: heroFade 27s ease-in-out infinite;
}
/* One third of the cycle apart. Negative delays start the sequence mid-way so
   slide 1 is already showing on load rather than fading up from nothing. */
.hero--home .hero-frame img:nth-child(1) { animation-delay:   0s; }
.hero--home .hero-frame img:nth-child(2) { animation-delay:  -18s; }
.hero--home .hero-frame img:nth-child(3) { animation-delay:   -9s; }

/* The slow Ken Burns drift is a client request. It rides on the frame, not the
   images, so the fade owns `animation` on each slide and the two effects
   compose instead of fighting for the same property. */
.hero--home .hero-frame {
  animation: kb 38s cubic-bezier(.4,0,.2,1) both;
}
/* No filter on these: the saturate(.82) that used to sit here was tuned for a
   night photograph and would mute a daylight sky.

   Framing differs per slide because the subjects sit in different places. The
   cement plant is 2.53:1 against a 100svh hero, so cover() crops its sides hard
   - at 390px wide only 18% of the width survives - and biasing left keeps the
   silos in frame. The other two are 16:9 and read well centred. */
.hero--home .hero-frame img:nth-child(1) { object-position: 38% center; }
.hero--home .hero-frame img:nth-child(2) { object-position: 50% 60%; }
.hero--home .hero-frame img:nth-child(3) { object-position: 50% center; }
.hero--sub .hero-frame img,
.hero--contact .hero-frame img { animation: kbs 30s ease-out both; }

.hero-scrim { position: absolute; inset: 0; }
/* The hero photograph carries its own gradient - sky about 203, foreground
   about 84 - so white copy over the bottom-left text zone already measures
   5.2:1 unaided. This scrim is insurance against a future image, not a
   rescue: clear across the sky, gentle only behind the copy. */
.hero--home .hero-scrim {
  background: linear-gradient(180deg, rgba(18,17,15,0) 0%, rgba(18,17,15,.08) 40%, rgba(18,17,15,.52) 100%);
}
.hero--sub .hero-scrim {
  background: linear-gradient(180deg, rgba(18,17,15,.44), rgba(18,17,15,.82));
}
.hero--contact .hero-scrim {
  background: linear-gradient(180deg, rgba(18,17,15,.46), rgba(18,17,15,.84));
}

.hero-copy {
  position: relative;
  max-width: var(--page-max);
  width: 100%;
  /* The header is fixed, so it does not reserve any space of its own. Pad the
     top of the copy by its height and the hero grid has somewhere safe to put
     the kicker when the viewport is too short to hold the whole block. */
  padding: var(--header-h) var(--space-8) var(--space-8);
}
.hero--home .hero-copy { padding-bottom: calc(var(--space-8) * 1.4); }
.hero--sub .hero-copy,
.hero--contact .hero-copy { margin: 0 auto; }

.hero-kicker {
  font-size: .8rem; letter-spacing: .28em; text-transform: uppercase;
  color: var(--color-accent-300);
  margin: 0 0 var(--space-4);
  font-feature-settings: 'tnum';
  /* Small accent text over a bright photograph measures 2.3-3.4:1 unaided, and
     no tint in the ramp clears AA on that ground - even pure white reaches only
     3.9:1. The shadow alone was not enough once the hero began rotating through
     three images of differing brightness, so the kicker carries its own soft
     plate: dark enough behind the glyphs to clear AA on the brightest slide,
     narrow enough that it never reads as a filled box. */
  display: inline-block;
  padding: var(--space-2) calc(var(--space-8) * 1.2) var(--space-2) 0;
  /* A hard-edged panel would read as a UI chip and breaks the design system's
     stroke-not-fill rule. Fading the wash out to the right leaves no visible
     edge - it reads as shadow on the photograph, not as a box on top of it. */
  background: linear-gradient(90deg,
    rgba(18,17,15,.68) 0%,
    rgba(18,17,15,.62) 55%,
    rgba(18,17,15,0) 100%);
  text-shadow: 0 1px 3px rgba(18,17,15,.9);
  animation: fadeUp 1.8s cubic-bezier(.22,.61,.36,1) .5s both;
}
.hero--sub .hero-kicker,
.hero--contact .hero-kicker {
  font-size: .76rem; letter-spacing: .26em;
  margin-bottom: var(--space-3);
  animation: fadeUpSm 1.4s ease .2s both;
}

.hero-title {
  font-family: var(--font-heading); font-weight: 400;
  color: #f7f5f1; margin: 0;
}
.hero--home .hero-title {
  font-size: clamp(2.7rem, 7vw, 6rem);
  line-height: 1.03; letter-spacing: -.012em;
  text-wrap: balance;
  animation: fadeUp 2.2s cubic-bezier(.22,.61,.36,1) .9s both;
}
.hero--sub .hero-title,
.hero--contact .hero-title {
  font-size: clamp(2.2rem, 5vw, 4rem);
  line-height: 1.06;
  animation: fadeUpSm 1.8s cubic-bezier(.22,.61,.36,1) .45s both;
}

.hero-rule {
  height: 1px; background: var(--color-accent);
  margin: var(--space-6) 0;
  max-width: 420px; transform-origin: left;
  animation: lineGrow 2.6s cubic-bezier(.22,.61,.36,1) 1.8s both;
}
.hero-lede {
  max-width: 46ch; font-size: 1.05rem; line-height: 1.75;
  color: rgba(247,245,241,.82);
  margin: 0 0 calc(var(--space-8) * .9);
  /* Body-size copy now falls over plant structures rather than the flat dark
     ground the night photograph gave it. Same reasoning as the kicker. */
  text-shadow: 0 1px 3px rgba(18,17,15,.7);
  animation: fadeUp 2s cubic-bezier(.22,.61,.36,1) 2.1s both;
}
.hero-actions {
  display: flex; gap: var(--space-4); flex-wrap: wrap;
  animation: fadeUp 2s cubic-bezier(.22,.61,.36,1) 2.5s both;
}
.hero-scroll {
  position: absolute; right: var(--space-8); bottom: calc(var(--space-8) * 1.4);
  writing-mode: vertical-rl;
  font-size: .7rem; letter-spacing: .3em; text-transform: uppercase;
  color: rgba(247,245,241,.5);
  animation: fadeIn 2s ease 3s both;
}

/* Buttons on a dark ground — outlined, never filled (design-system rule). */
.btn-on-dark { border-color: var(--color-accent-300); color: #f7f5f1; }
.btn-on-dark:hover { color: #fff; }
.btn-ghost-on-dark { color: rgba(247,245,241,.82); }
.btn-ghost-on-dark:hover { color: #f7f5f1; }

/* ── sections ────────────────────────────────────────────────────────── */
.section {
  max-width: var(--page-max); margin: 0 auto;
  padding: var(--gap-page) var(--space-8);
}
.section--tight { padding-block: var(--gap-page-tight) var(--gap-page); }
.section--top-flush { padding-top: 0; }
.section-rule { border-top: 1px solid var(--color-divider); padding-top: var(--space-8); }

/* The two tinted bands. Full-bleed, divider-bordered, never a coloured fill. */
.band {
  background: var(--color-neutral-100);
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  padding: var(--gap-page-tight) var(--space-8);
}
.band--cta { padding-block: calc(var(--space-8) * 1.5); text-align: center; }
.band--wide { padding-block: calc(var(--space-8) * 1.8); }

.kicker {
  font-size: .76rem; letter-spacing: .24em; text-transform: uppercase;
  color: var(--color-accent-700);
  margin: 0 0 var(--space-4);
  font-feature-settings: 'tnum';
}
.kicker--loose { margin-bottom: calc(var(--space-8) * .9); }
.kicker--looser { margin-bottom: calc(var(--space-8) * 1.1); }
.kicker--wide { margin-bottom: var(--space-8); }

.meta {
  font-size: .74rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--color-neutral-600);
  margin: 0 0 var(--space-3);
}
.meta--fig { font-size: .72rem; font-feature-settings: 'tnum'; }

.h-section {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(1.9rem, 3.4vw, 3rem); line-height: 1.12;
  margin: 0;
}
.h-band {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(1.9rem, 4vw, 3.2rem); line-height: 1.08;
  color: #f7f5f1;
  margin: 0 0 var(--gap-block);
}
.h-lead {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(1.7rem, 3vw, 2.6rem); line-height: 1.14;
  margin: 0;
}
.h-mid {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(1.6rem, 2.8vw, 2.3rem); line-height: 1.16;
  margin: 0 0 var(--gap-block);
}
.h-project {
  font-family: var(--font-heading); font-weight: 400;
  font-size: 2rem; line-height: 1.12;
  margin: 0 0 var(--space-4);
}
.h-card {
  font-family: var(--font-heading); font-weight: 500;
  font-size: 1.45rem; line-height: 1.2;
  margin: 0 0 var(--space-3);
}
.h-plant {
  font-family: var(--font-heading); font-weight: 500;
  font-size: 1.5rem;
  margin: 0 0 var(--space-3);
}
.h-cta {
  font-family: var(--font-heading); font-weight: 400;
  font-size: 1.6rem;
  margin: 0 0 var(--gap-block);
}

.prose {
  line-height: 1.85; font-size: 1.02rem;
  text-align: justify;
  margin: 0 0 var(--gap-block);
}
.prose:last-child { margin-bottom: 0; }
.prose--lede { max-width: 62ch; margin-bottom: calc(var(--space-8) * 1.4); }

.rule-short { height: 1px; background: var(--color-accent); width: 64px; margin-top: var(--gap-block); }
.rule-tick  { height: 1px; background: var(--color-accent); width: 48px; margin-bottom: var(--space-4); }

.link-more {
  font-size: .84rem; letter-spacing: .14em; text-transform: uppercase;
  border-bottom: 1px solid var(--color-accent);
}

/* ── grids ───────────────────────────────────────────────────────────── */
.split { display: grid; gap: var(--gap-col); align-items: start; }
.split--firm     { grid-template-columns: minmax(0,1fr) minmax(0,1.35fr); }
.split--intro    { grid-template-columns: minmax(0,1fr) minmax(0,1.4fr); }
.split--even     { grid-template-columns: minmax(0,1fr) minmax(0,1fr); align-items: center; }
.split--quality  { grid-template-columns: minmax(0,1fr) minmax(0,1.2fr); align-items: center; }
.split--contact  { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-6); }
.cards--wide { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: calc(var(--space-8) * 1.1); }
.cols-3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: calc(var(--space-8) * 1.15); }

.stats {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6);
  border-top: 1px solid var(--color-divider);
  padding-top: var(--space-6);
  margin-top: calc(var(--space-8) * .9);
}
.stat-figure {
  font-family: var(--font-heading); font-size: 2.5rem; line-height: 1;
  color: var(--color-accent-700);
  font-feature-settings: 'tnum';
  margin: 0;
}
.stat-label {
  font-size: .78rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--color-neutral-600);
  margin: var(--space-2) 0 0;
}

.chips { display: flex; flex-wrap: wrap; gap: var(--space-3); }
/* The design system's .tag-outline uses --color-accent; body-size text in the
   accent needs the 700 step for contrast, and the border softens to 300. */
.chip {
  white-space: nowrap; padding: 5px 12px;
  color: var(--color-accent-700);
  border-color: var(--color-accent-300);
}

/* ── project spreads (Ongoing) ───────────────────────────────────────── */
.spreads { display: grid; gap: calc(var(--space-8) * 2); }
.spread {
  display: grid; gap: calc(var(--space-8) * 1.1);
  align-items: center;
  grid-template-columns: minmax(0,1.1fr) minmax(0,1fr);
}
.spread--flip { grid-template-columns: minmax(0,1fr) minmax(0,1.1fr); }

.plate { margin: 0; }
.plate img { width: 100%; display: block; object-fit: cover; }
.plate--43 img { aspect-ratio: 4/3; }

/* Awaiting a client photograph. Delete the modifier — not just the caption —
   once the real image lands; the dashed box must never ship as final. */
.plate--pending {
  display: grid; place-items: center;
  aspect-ratio: 4/3;
  border-style: dashed;
  background: var(--color-neutral-100);
}
.pending-note {
  margin: 0; padding: var(--space-6); text-align: center;
  font-size: .84rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--color-neutral-600);
}

/* ── project cards (Completed) ───────────────────────────────────────── */
.project-card { padding: 0; overflow: hidden; }
.project-card > img {
  width: 100%; display: block;
  aspect-ratio: 3/2; object-fit: cover;
}
.project-card-body { padding: var(--space-6); }
.project-card-body p:last-child { margin: 0; line-height: 1.8; font-size: .98rem; }
.project-card-pending {
  display: grid; place-items: center;
  aspect-ratio: 3/2;
  background: var(--color-neutral-100);
  border-bottom: 1px solid var(--color-divider);
}
.project-card-pending .pending-note { font-size: .8rem; }

.plant-list {
  margin: 0; padding-left: 1.1em;
  line-height: 2; color: var(--color-neutral-700);
}

/* ── full-bleed image band (Home) ────────────────────────────────────── */
.image-band { position: relative; height: 58vh; min-height: 400px; overflow: hidden; }
.image-band > img { width: 100%; height: 100%; object-fit: cover; }
.image-band .hero-scrim { background: linear-gradient(180deg, rgba(18,17,15,.24), rgba(18,17,15,.74)); }
.image-band-copy {
  position: absolute; left: 0; right: 0; bottom: var(--space-8);
  padding: 0 var(--space-8);
}

.quote {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2.3rem); line-height: 1.4;
  font-style: italic;
  margin: 0;
}
.quote-caption {
  font-size: .78rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--color-neutral-600);
  margin: var(--space-6) 0 0;
}

/* ── contact blocks ──────────────────────────────────────────────────── */
.contact-blocks { display: grid; gap: var(--space-6); }
.contact-block {
  border-top: 1px solid var(--color-divider);
  padding-top: var(--gap-block);
}
.contact-block .meta { font-size: .72rem; }
.contact-address { margin: 0; line-height: 1.75; font-size: 1.05rem; }
.contact-line {
  display: inline-flex; align-items: center; gap: var(--space-3);
  font-size: 1.15rem; font-feature-settings: 'tnum';
}
.contact-line--email { font-size: 1.05rem; word-break: break-all; }

/* ── footer ──────────────────────────────────────────────────────────── */
.site-footer {
  background: #1a1917; color: #f7f5f1;
  padding: var(--gap-page-tight) var(--space-8) var(--space-8);
}
.site-footer-grid {
  max-width: var(--page-max); margin: 0 auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: calc(var(--space-8) * 1.1);
}
.footer-brand { font-family: var(--font-heading); font-size: 1.4rem; margin: 0 0 var(--space-4); }
.footer-address { margin: 0; line-height: 1.7; color: rgba(247,245,241,.66); }
.footer-label {
  font-size: .72rem; letter-spacing: .2em; text-transform: uppercase;
  color: rgba(247,245,241,.5);
  margin: 0 0 var(--space-3);
}
.footer-links { display: grid; gap: var(--space-2); }
.footer-links a { color: rgba(247,245,241,.82); }
.footer-links a:hover { color: #f7f5f1; }
.footer-reach { display: grid; gap: var(--space-3); }
.footer-reach a {
  display: flex; align-items: center; gap: var(--space-3);
  color: rgba(247,245,241,.86);
}
.footer-reach a:hover { color: #f7f5f1; }
.footer-reach .tnum { font-feature-settings: 'tnum'; }
.footer-reach .brk { word-break: break-all; }
.site-footer-bar {
  max-width: var(--page-max);
  margin: calc(var(--space-8) * 1.2) auto 0;
  border-top: 1px solid rgba(247,245,241,.14);
  padding-top: var(--gap-block);
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  justify-content: space-between;
  font-size: .8rem; color: rgba(247,245,241,.5);
}

/* Image credit. Deliberately quiet - it is a licence obligation, not content. */
.site-footer-credit {
  max-width: var(--page-max);
  margin: var(--space-3) auto 0;
  font-size: .72rem;
  color: rgba(247,245,241,.38);
}
.site-footer-credit a { color: rgba(247,245,241,.55); }
.site-footer-credit a:hover { color: rgba(247,245,241,.8); }

/* ── floating contact widget ─────────────────────────────────────────── */
/* Offsets must resolve to a real token. The original used --space-5, which the
   Classical scale does not define; it fell back to `auto` and un-pinned the
   whole widget. Any token introduced here has to exist. */
.contact-dock {
  position: fixed;
  right: var(--gap-block); bottom: var(--gap-block);
  z-index: 50;
  display: grid; gap: var(--space-3); justify-items: end;
}
.dock-pill {
  display: flex; align-items: center; gap: var(--space-3);
  min-height: 44px;                        /* touch target */
  padding: 10px 16px 10px 12px;
  border-radius: 999px;
  font-size: .9rem;
}
.dock-pill svg { flex: none; }
.dock-pill--wa {
  background: #1a1917; color: #f7f5f1;
  border: 1px solid var(--color-accent-700);
  box-shadow: var(--shadow-md);
  font-feature-settings: 'tnum';
}
.dock-pill--wa:hover { background: var(--color-accent-700); color: #fff; }
.dock-pill--mail {
  background: var(--color-bg); color: var(--color-text);
  border: 1px solid var(--color-accent-300);
  box-shadow: var(--shadow-sm);
}
.dock-pill--mail:hover { border-color: var(--color-accent-700); color: var(--color-accent-700); }

/* ── responsive ──────────────────────────────────────────────────────── */

/* Six uppercase nav items stop fitting well before the layout breaks. */
@media (max-width: 900px) {
  .site-header { flex-wrap: wrap; align-items: center; padding-inline: var(--space-4); }
  .nav-toggle-label {
    display: inline-flex; align-items: center; justify-content: center;
    width: 44px; height: 44px; margin: calc(var(--space-2) * -1) 0;
    cursor: pointer; color: var(--color-neutral-700);
  }
  .nav-toggle-label:hover { color: var(--color-accent-700); }
  .nav-toggle:focus-visible + .nav-toggle-label { outline: 2px solid var(--color-accent); outline-offset: 2px; }
  .site-nav {
    display: none;
    flex-basis: 100%;
    flex-direction: column; align-items: flex-start;
    gap: var(--space-4);
    padding: var(--space-4) 0 var(--space-2);
  }
  .nav-toggle:checked ~ .site-nav { display: flex; }
  /* A bottom border on a stacked item reads as a stray rule, not as "current". */
  .site-nav a[aria-current="page"] { border-bottom: 0; }
}

/* The fixed two-column spreads stack, image first in each pair. */
@media (max-width: 860px) {
  .split--firm,
  .split--intro,
  .split--even,
  .split--quality { grid-template-columns: minmax(0, 1fr); }
  .split--firm, .split--intro { gap: var(--space-8); }

  .spread,
  .spread--flip { grid-template-columns: minmax(0, 1fr); }
  .spread > .plate,
  .spread--flip > .plate { order: -1; }
  .split--even > .plate,
  .split--quality > .plate { order: -1; }

  .section { padding-block: var(--gap-page-tight); }
  .spreads { gap: var(--gap-page); }
  /* A shorter hero on narrow screens means a less punishing side crop.
     min-height is inherited from the base rule. */
  .hero--home { height: 72svh; }
}

@media (max-width: 600px) {
  /* Justification at a narrow measure opens rivers of white space. */
  .prose,
  .project-card-body p { text-align: left; }

  .section, .band, .site-footer { padding-inline: var(--space-4); }
  .hero-copy, .image-band-copy { padding-inline: var(--space-4); }
  .stats { grid-template-columns: repeat(auto-fit, minmax(88px, 1fr)); gap: var(--space-4); }
  .stat-figure { font-size: 2rem; }
  .hero-scroll { display: none; }

  /* Full-width pills would span the viewport, so collapse to icon circles. */
  .contact-dock { gap: var(--space-2); }
  .dock-pill {
    width: 52px; height: 52px; min-height: 52px;
    padding: 0; justify-content: center;
    gap: 0;
  }
  .dock-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
