/* ============================================================
   V13 — APERTURE
   180 Degrees Consulting Delft–Rotterdam
   One stylesheet, no framework, no build step.

   The signature device: the home headline is a window. Real
   photography of Rotterdam appears only inside its letterforms,
   and scrolling opens the aperture until the photograph takes
   the whole frame.

   The whole hero choreography is expressed ONCE, as functions of
   a single custom property --ap-p (aperture progress, 0 → 1).
   That property is then driven three ways, in falling order of
   capability:
     1. native CSS scroll-driven animation  (no JS at all)
     2. a rAF scroll handler setting --ap-p  (Safari / Firefox)
     3. nothing — it keeps its initial value, which is a composed,
        fully legible state (no JS, or prefers-reduced-motion)
   There is only one set of visual rules, so the three paths can
   never drift apart.
   ============================================================ */

/* ---------- fonts (self-hosted latin subsets) ---------- */
@font-face { font-family: "Archivo"; src: url(fonts/Archivo-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Archivo"; src: url(fonts/Archivo-600.woff2) format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Archivo Black"; src: url(fonts/ArchivoBlack-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Space Mono"; src: url(fonts/SpaceMono-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Space Mono"; src: url(fonts/SpaceMono-700.woff2) format("woff2"); font-weight: 700; font-display: swap; }

/* ---------- tokens ---------- */
:root {
  /* verified 180DC brand greens — _brand/BRAND.md. No invented palette. */
  --green: #78B038;          /* exact brand mark — large/decorative only (2.60 on white) */
  --green-deep: #4A7322;     /* AA-safe for text on white (5.58) */
  --green-darkest: #3D6B1C;  /* extra safety for small text (6.33) */

  --ink: #101312;
  --ink-soft: #55605A;
  --paper: #FFFFFF;
  --paper-dim: #FAFBF9;
  --line: #E3E7E1;

  --dark: #0B0D0C;
  --dark-2: #141917;
  --on-dark: #F4F7F2;
  --on-dark-soft: #A9B4AC;

  --display: "Archivo Black", "Arial Black", system-ui, sans-serif;
  --sans: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Space Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  --wrap: 1240px;
  --gut: clamp(1.15rem, 4vw, 2.75rem);

  /* aperture progress. Declared plainly so the calc()s below always
     resolve even where @property is unsupported. 0.34 = the composed
     resting state used when nothing is driving it. */
  --ap-p: 0.34;
}

/* Registered so a CSS scroll-driven animation can interpolate it. */
@property --ap-p {
  syntax: "<number>";
  initial-value: 0.34;
  inherits: true;
}

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

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

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 1.02rem;
  line-height: 1.62;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: var(--green-deep); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--green-darkest); }

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

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gut); }
.narrow { max-width: 760px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--dark); color: var(--on-dark); padding: 0.75rem 1.1rem;
  font-family: var(--mono); font-size: 0.85rem;
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

/* ============================================================
   HEADER — dark glass on every page, so the cinematic register
   is continuous and the bar reads over both photo and white.
   ============================================================ */
.top {
  position: sticky; top: 0; z-index: 40;
  background: rgba(11, 13, 12, 0.74);
  backdrop-filter: blur(14px) saturate(1.15);
  -webkit-backdrop-filter: blur(14px) saturate(1.15);
  border-bottom: 1px solid rgba(255, 255, 255, 0.09);
}
.top-inner { display: flex; align-items: center; gap: 1.25rem; min-height: 66px; }

.brand { display: flex; align-items: center; gap: 0.6rem; color: var(--on-dark); text-decoration: none; margin-right: auto; }
.brand img { width: 30px; height: auto; }
.brand b { display: block; font-size: 0.9rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; }
.brand small {
  display: block; font-family: var(--mono); font-size: 0.62rem;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--green);
}

.top nav { display: flex; align-items: center; gap: 0.35rem; flex-wrap: wrap; }
.top nav a {
  font-size: 0.87rem; color: var(--on-dark-soft); text-decoration: none;
  padding: 0.42rem 0.6rem; border-radius: 3px; transition: color 140ms ease;
}
.top nav a:hover { color: var(--on-dark); }

/* Own-page links are marked differently from in-page scroll anchors:
   a hairline pill plus a green dot. Consistent on all five pages. */
.top nav a.nav-page {
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 999px; padding: 0.36rem 0.78rem 0.36rem 0.66rem;
  display: inline-flex; align-items: center; gap: 0.4rem;
}
.top nav a.nav-page::before {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: var(--green); flex: none;
}
.top nav a.nav-page:hover { border-color: var(--green); }
.top nav a.nav-page[aria-current="page"] { border-color: var(--green); color: var(--on-dark); }

.top nav a.cta {
  background: var(--green); color: #0A0F05; font-weight: 600;
  border-radius: 999px; padding: 0.46rem 1rem; margin-left: 0.3rem;
}
.top nav a.cta:hover { background: #8CC544; color: #0A0F05; }

/* Below the point where all seven links stop fitting, drop the three
   in-page scroll anchors — they are duplicated in the footer — and keep
   the own-page links, which are the ones that go somewhere. No JS drawer:
   the bar must work with scripting off. */
@media (max-width: 1000px) {
  .top nav a:not(.nav-page):not(.cta) { display: none; }
}
/* On phones the bar becomes a single non-wrapping strip that scrolls
   horizontally, so every destination stays reachable without a JS drawer. */
@media (max-width: 620px) {
  .top-inner { gap: 0.6rem; flex-wrap: nowrap; }
  .brand { flex: none; }
  .brand b { font-size: 0.74rem; white-space: nowrap; }
  .brand small { display: none; }
  .top nav {
    flex-wrap: nowrap; overflow-x: auto; gap: 0.25rem;
    scrollbar-width: none; -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .top nav::-webkit-scrollbar { display: none; }
  .top nav a { font-size: 0.78rem; padding: 0.3rem 0.4rem; flex: none; }
  .top nav a.nav-page { padding: 0.3rem 0.6rem 0.3rem 0.5rem; }
  .top nav a.cta { padding: 0.4rem 0.75rem; margin-left: 0.1rem; }
}

/* ============================================================
   THE APERTURE HERO (home only)
   240vh tall; a sticky 100vh stage inside it.
   ============================================================ */
.aperture { position: relative; height: 240vh; background: var(--dark); }

.ap-stage {
  position: sticky; top: 0; height: 100vh;
  display: grid; align-content: center;
  overflow: hidden;
  padding-bottom: clamp(3.2rem, 8vh, 5rem); /* room for hint + credit */
}

/* full-bleed photograph — the frame the aperture opens onto */
.ap-photo {
  position: absolute; inset: 0; z-index: 0;
  background-image: url(img/hero-rotterdam-sm.webp);
  background-size: cover; background-position: 50% 58%;
  transform-origin: 50% 55%;
  /* fades in over the first half of the range, and settles from a
     slight over-scale so the frame "lands" as the aperture opens */
  opacity: clamp(0, calc(var(--ap-p) / 0.5), 1);
  transform: scale(calc(1.14 - 0.14 * clamp(0, var(--ap-p), 1)));
}
@media (min-width: 880px) { .ap-photo { background-image: url(img/hero-rotterdam.webp); } }

/* the dark frame. Deep at rest so the masked type reads as a lit
   window; lifts as the aperture opens. */
/* The floor matters: the type is filled with the SAME photograph, so if the
   frame behind it ever gets as bright as the fill, the headline camouflages
   itself into invisibility. The scrim never opens past 0.62. */
.ap-scrim {
  position: absolute; inset: 0; z-index: 1;
  background:
    linear-gradient(180deg, rgba(11,13,12,0.9) 0%, rgba(11,13,12,0.62) 45%, rgba(11,13,12,0.92) 100%),
    var(--dark);
  opacity: calc(0.96 - 0.34 * clamp(0, var(--ap-p), 1));
}

.ap-inner { position: relative; z-index: 2; width: 100%; }

.ap-eyebrow {
  font-family: var(--mono); font-size: clamp(0.62rem, 1.5vw, 0.74rem);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--green);
  margin: 0 0 clamp(0.9rem, 2.5vw, 1.5rem);
}

/* ---- the window itself ---- */
.ap-type {
  margin: 0;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.3rem, 8.4vw, 7.4rem);
  line-height: 0.88;
  letter-spacing: -0.035em;
  text-transform: uppercase;
  max-width: 12ch; /* in ch, so the measure holds at every clamp step */

  /* fallback for engines without background-clip:text — solid brand
     green on the dark frame, which passes contrast at this size */
  color: var(--green);

  /* the photograph, retreating inside the letterforms as you scroll.
     Positioned on the dense city band, not the hazy sky, so there is
     always structure to see inside the glyphs. */
  background-image: url(img/hero-rotterdam.webp);
  background-repeat: no-repeat;
  background-position: 50% 58%;
  background-size: calc(200% - 88% * clamp(0, var(--ap-p), 1)) auto;

  /* The headline never fades out. It is the window, and it is the h1 —
     animating it to opacity 0 would both break the concept and hide the
     page's only top-level heading. */
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ap-type {
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* hairline + shadow keep the glyph edges readable against a busy frame.
       --ap-bright lifts the photograph inside the glyphs where the type is
       small enough that it samples only a dark patch of the frame. */
    -webkit-text-stroke: 0.6px rgba(255, 255, 255, 0.2);
    filter: brightness(var(--ap-bright, 1)) drop-shadow(0 3px 24px rgba(0, 0, 0, 0.6));
  }
}

/* The line that arrives as the aperture opens. Kept in normal flow directly
   under the headline: absolutely positioning it invited a collision with the
   display type at every viewport where the headline ran long. */
.ap-after {
  margin-top: clamp(1.1rem, 3vh, 2rem);
  opacity: clamp(0, calc((clamp(0, var(--ap-p), 1) - 0.5) / 0.34), 1);
  transform: translateY(calc(26px - 26px * clamp(0, calc((clamp(0, var(--ap-p), 1) - 0.5) / 0.34), 1)));
}

.ap-lede {
  margin: 0;
  max-width: 38ch;
  font-size: clamp(1rem, 2.1vw, 1.55rem);
  font-weight: 600; line-height: 1.26; letter-spacing: -0.02em;
  color: var(--on-dark);
  text-wrap: balance;
}
.ap-lede em { font-style: normal; color: var(--green); }

/* photo credit — always visible, always horizontal, never decorative */
.ap-credit {
  position: absolute; right: var(--gut); bottom: clamp(1.1rem, 3vh, 2rem); z-index: 3;
  max-width: 46vw; text-align: right; margin: 0;
  font-family: var(--mono); font-size: 0.58rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: rgba(255, 255, 255, 0.55);
}
@media (max-width: 700px) {
  /* in flow under the headline, and inside the gutter — and the scroll
     affordance goes away, because touch users do not need to be told */
  .ap-credit { position: static; text-align: left; max-width: none; margin-top: 1.5rem; padding-inline: var(--gut); }
  .ap-hint { display: none; }
}

/* ---------- scroll hint ---------- */
.ap-hint {
  position: absolute; left: var(--gut); bottom: clamp(1.6rem, 4vh, 3rem); z-index: 3;
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: rgba(255,255,255,0.55);
  display: flex; align-items: center; gap: 0.6rem;
  opacity: clamp(0, calc((0.3 - clamp(0, var(--ap-p), 1)) / 0.3), 1);
}
.ap-hint span { display: block; width: 34px; height: 1px; background: var(--green); }

/* ============================================================
   DRIVER 1 — native CSS scroll-driven animation, zero JS.
   ============================================================ */
@keyframes ap-drive { from { --ap-p: 0; } to { --ap-p: 1; } }

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    body:has(.aperture) {
      animation: ap-drive 1s linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 150vh;
    }
  }
}

/* ============================================================
   GLASS PANEL — the engagement cycle carousel
   ============================================================ */
.panel-hold { position: relative; margin-top: -18vh; z-index: 5; padding-bottom: clamp(3rem, 8vw, 6rem); background: var(--paper); }
.panel-hold::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 18vh; background: linear-gradient(180deg, transparent, var(--paper)); }

.panel {
  position: relative;
  background: rgba(16, 20, 18, 0.58);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 14px;
  padding: clamp(1.2rem, 3vw, 2rem);
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, 0.6);
  color: var(--on-dark);
}
/* Where backdrop-filter is unavailable the panel must still be solid
   enough to carry white text. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .panel { background: rgba(11, 13, 12, 0.94); }
}

.panel-head { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.15rem; }
.panel-head .eyebrow { margin: 0; color: var(--green); }
.panel-head p { margin: 0; color: var(--on-dark-soft); font-size: 0.9rem; }

.panel-track {
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(255px, 1fr);
  gap: clamp(0.9rem, 2vw, 1.4rem);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: thin;
  padding-bottom: 0.5rem;
}
@media (min-width: 1000px) { .panel-track { grid-auto-columns: 1fr; overflow-x: visible; } }

.pslide {
  scroll-snap-align: start;
  border-top: 2px solid var(--green);
  padding-top: 0.85rem;
  min-width: 0;
}
.pstep { font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.16em; color: var(--green); }
.pslide h3 { margin: 0.5rem 0 0.15rem; font-size: 1.06rem; font-weight: 600; letter-spacing: -0.015em; color: var(--on-dark); }
.pwhen { margin: 0 0 0.55rem; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--on-dark-soft); }
.pslide p:last-child { margin: 0; font-size: 0.9rem; line-height: 1.55; color: #CFD8CF; }

/* controls only exist when JS can operate them */
.panel-nav, .panel-dots { display: none; }
.js .panel-nav { display: flex; gap: 0.4rem; margin-left: auto; }
.js .panel-dots { display: flex; gap: 0.4rem; margin-top: 1rem; }
@media (min-width: 1000px) { .js .panel-nav, .js .panel-dots { display: none; } }

.pbtn {
  width: 34px; height: 34px; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--on-dark);
  border: 1px solid rgba(255,255,255,0.28);
  font-size: 0.95rem; line-height: 1; display: grid; place-items: center;
  transition: background-color 140ms ease, border-color 140ms ease;
}
.pbtn:hover:not(:disabled) { background: rgba(255,255,255,0.12); border-color: var(--green); }
.pbtn:disabled { opacity: 0.32; cursor: default; }

.dot {
  width: 26px; height: 3px; border-radius: 2px; cursor: pointer; padding: 0;
  border: 0; background: rgba(255,255,255,0.26); transition: background-color 160ms ease;
}
.dot.on { background: var(--green); }

/* ============================================================
   SHARED SECTION FURNITURE
   ============================================================ */
section { position: relative; }
.plain { padding: clamp(3.4rem, 9vw, 7rem) 0; }
.band { padding: clamp(3.4rem, 9vw, 7rem) 0; background: var(--paper-dim); border-block: 1px solid var(--line); }
.dark-band { padding: clamp(3.4rem, 9vw, 7rem) 0; background: var(--dark); color: var(--on-dark); }
.dark-band h2 { color: var(--on-dark); }
.dark-band p { color: var(--on-dark-soft); }
.dark-band a { color: var(--green); }

.eyebrow {
  display: block; font-family: var(--mono); font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--green-deep);
  margin: 0 0 0.85rem;
}
.dark-band .eyebrow, .panel .eyebrow { color: var(--green); }

h2 {
  margin: 0 0 0.7rem;
  font-size: clamp(1.6rem, 4.1vw, 2.85rem);
  font-weight: 600; line-height: 1.08; letter-spacing: -0.03em;
  text-wrap: balance;
}
h3 { letter-spacing: -0.015em; }
.lede { font-size: clamp(1.02rem, 2.1vw, 1.2rem); color: var(--ink-soft); max-width: 62ch; margin: 0; }
.dark-band .lede { color: var(--on-dark-soft); }

.sec-head { margin-bottom: clamp(1.8rem, 4vw, 3rem); }

/* The one recurrence of the aperture at display scale, on the home page only.
   It is filled with the HERO photograph — deliberately, for two reasons: it
   reads as a callback to the headline rather than an unrelated new image, and
   the file is already in cache, so the recurrence costs nothing.
   The fill is aimed at the dense city band. An earlier version sampled a
   sky-heavy frame and rendered the heading as a large blue word, which is
   effectively inventing a brand colour — the palette is greens only. */
.mask-head {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2rem, 7.5vw, 5.4rem);
  line-height: 0.92; letter-spacing: -0.035em; text-transform: uppercase;
  margin: 0 0 0.9rem;
  color: var(--green-deep);
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .mask-head {
    background-image: url(img/hero-rotterdam.webp);
    background-repeat: no-repeat;
    background-size: 240% auto; background-position: 48% 72%;
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
    /* on a light band, photographic fill needs a contrast floor */
    -webkit-text-stroke: 0.5px rgba(16, 19, 18, 0.42);
    filter: brightness(0.82) saturate(0.72) contrast(1.08);
  }
}

.btn {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: inherit; font-size: 0.95rem; font-weight: 600;
  text-decoration: none; padding: 0.82rem 1.5rem; border-radius: 999px;
  border: 1.5px solid transparent; cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, transform 140ms ease;
}
.btn--primary { background: var(--green); color: #0A0F05; }
.btn--primary:hover { background: #8CC544; color: #0A0F05; transform: translateY(-1px); }
.btn--ghost { border-color: var(--line); color: var(--ink); }
.btn--ghost:hover { border-color: var(--green); color: var(--green-darkest); }
.dark-band .btn--ghost, .duo .btn--ghost { border-color: rgba(255,255,255,0.3); color: var(--on-dark); }
.dark-band .btn--ghost:hover, .duo .btn--ghost:hover { border-color: var(--green); color: var(--green); }
.btn-row { display: flex; gap: 0.7rem; flex-wrap: wrap; margin-top: 1.5rem; }

/* ============================================================
   THE MOSAIC — six real service areas over six real places.
   Deliberately irregular: the retrospective in DIRECTIONS-6-10.md
   records that a symmetric six-card service wall was called out
   in every variant that reached for one.
   ============================================================ */
.mosaic {
  display: grid; gap: clamp(0.6rem, 1.4vw, 1rem);
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 760px) {
  .mosaic {
    grid-template-columns: repeat(6, 1fr);
    grid-auto-rows: minmax(0, auto);
  }
  .tile:nth-child(1) { grid-column: span 4; }
  .tile:nth-child(2) { grid-column: span 2; }
  .tile:nth-child(3) { grid-column: span 2; }
  .tile:nth-child(4) { grid-column: span 4; }
  .tile:nth-child(5) { grid-column: span 3; }
  .tile:nth-child(6) { grid-column: span 3; }
}

.tile { position: relative; margin: 0; overflow: hidden; border-radius: 10px; background: var(--dark); }
.tile-media { position: relative; overflow: hidden; }
.tile img {
  width: 100%; height: 100%; object-fit: cover;
  aspect-ratio: 4 / 3;
  /* the aperture gesture, recurring at small scale: each frame
     opens from a tight crop as it enters view */
  clip-path: inset(0);
  transform: scale(1);
}
@media (min-width: 760px) {
  .tile:nth-child(1) img, .tile:nth-child(4) img { aspect-ratio: 16 / 9; }
}

.tile figcaption {
  position: absolute; inset: auto 0 0 0;
  padding: clamp(0.8rem, 2vw, 1.15rem);
  background: linear-gradient(180deg, transparent, rgba(9, 11, 10, 0.9) 55%);
  color: var(--on-dark);
}
.tile-tag {
  display: block; font-family: var(--mono); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--green);
  margin-bottom: 0.3rem;
}
.tile-say { display: block; font-size: 0.86rem; line-height: 1.45; color: #E4EAE2; max-width: 46ch; }
.tile-where {
  display: block; margin-top: 0.5rem;
  font-family: var(--mono); font-size: 0.55rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: rgba(255,255,255,0.52);
}

/* Motion for the tiles: native scroll-driven where available, else an
   IntersectionObserver class. Base state is fully open, so with no JS
   and no support nothing is hidden. */
@keyframes tile-open {
  from { clip-path: inset(9% 11% 9% 11%); transform: scale(1.06); }
  to   { clip-path: inset(0); transform: scale(1); }
}
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .tile img { animation: tile-open linear both; animation-timeline: view(); animation-range: entry 8% cover 34%; }
  }
  @supports not (animation-timeline: view()) {
    .js .tile img { clip-path: inset(9% 11% 9% 11%); transform: scale(1.06); transition: clip-path 900ms cubic-bezier(.16,.84,.24,1), transform 900ms cubic-bezier(.16,.84,.24,1); }
    .js .tile.in img { clip-path: inset(0); transform: scale(1); }
  }
}

/* ---------- generic reveal (interior pages) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js .reveal { opacity: 0; transform: translateY(18px); transition: opacity 620ms ease, transform 620ms cubic-bezier(.16,.84,.24,1); }
  .js .reveal.in { opacity: 1; transform: none; }
}

/* ============================================================
   SECOND HERO REGISTER — interior pages.
   Full-bleed dark, one large headline, minimal chrome, no mask:
   the aperture belongs to the home page only.
   ============================================================ */
.duo {
  background: var(--dark); color: var(--on-dark);
  padding: clamp(3.4rem, 11vw, 8rem) 0 clamp(2.6rem, 7vw, 5rem);
  border-bottom: 1px solid rgba(255,255,255,0.1);
}
.duo h1 {
  margin: 0 0 1rem;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(2.1rem, 8vw, 5.6rem);
  line-height: 0.9; letter-spacing: -0.035em; text-transform: uppercase;
  color: var(--on-dark);
  text-wrap: balance;
}
.duo h1 em { font-style: normal; color: var(--green); }
.duo .lede { color: var(--on-dark-soft); font-size: clamp(1.02rem, 2.2vw, 1.3rem); }
.duo .crumb {
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--on-dark-soft); margin: 0 0 1.3rem;
}
.duo .crumb a { color: var(--green); text-decoration: none; }
.duo .crumb span { opacity: 0.4; margin: 0 0.5rem; }

/* ============================================================
   CARDS, LISTS, PLACEHOLDERS
   ============================================================ */
.grid { display: grid; gap: clamp(0.9rem, 2vw, 1.4rem); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }

.card { background: var(--paper); border: 1px solid var(--line); border-radius: 10px; padding: clamp(1.1rem, 2.4vw, 1.6rem); }
.band .card { background: var(--paper); }
.card h3 { margin: 0.15rem 0 0.4rem; font-size: 1.08rem; }
.card p { margin: 0; color: var(--ink-soft); font-size: 0.95rem; }
.card--tint { background: #F4F8EE; border-color: #DCE8C8; }

.num { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; color: var(--green-deep); text-transform: uppercase; }

/* the one honesty register used site-wide: a hairline reserved slot */
.placeholder {
  display: inline-block;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.06em;
  color: var(--ink-soft);
  border: 1px dashed #C6CFC0; border-radius: 4px;
  padding: 0.3rem 0.55rem; background: repeating-linear-gradient(135deg, transparent 0 6px, rgba(120,176,56,0.06) 6px 12px);
}
.dark-band .placeholder { color: var(--on-dark-soft); border-color: rgba(255,255,255,0.22); }

.work-steps { margin-top: 0.9rem; display: grid; gap: 0.35rem; }
.work-steps > div {
  display: flex; justify-content: space-between; gap: 1rem;
  border-top: 1px solid var(--line); padding-top: 0.35rem;
  font-size: 0.82rem; color: var(--ink-soft);
}
.work-steps em { font-style: normal; font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink); }

.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 1.3rem; }
.chip {
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.05em;
  border: 1px solid var(--line); border-radius: 999px; padding: 0.36rem 0.75rem;
  color: var(--ink-soft);
}
.chip b { color: var(--ink); font-weight: 700; }
.dark-band .chip { border-color: rgba(255,255,255,0.2); color: var(--on-dark-soft); }
.dark-band .chip b { color: var(--on-dark); }

/* committee */
.committee { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.member {
  display: flex; align-items: center; gap: 0.9rem;
  padding: 0.8rem 0; border-top: 1px solid var(--line);
}
.member:last-child { border-bottom: 1px solid var(--line); }
.avatar {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: #EDF3E3; color: var(--green-darkest);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
}
.m-body { flex: 1 1 auto; min-width: 0; }
.m-body b { display: block; font-size: 0.96rem; font-weight: 600; }
.m-role { display: block; font-size: 0.82rem; color: var(--ink-soft); }
.m-mail { font-family: var(--mono); font-size: 0.74rem; word-break: break-all; }

/* two-column prose + figure */
.cols { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: start; }
@media (min-width: 900px) { .cols { grid-template-columns: 1.15fr 0.85fr; } }
.photo-card { margin: 0; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.photo-card img { width: 100%; height: auto; }
.photo-card figcaption {
  font-family: var(--mono); font-size: 0.62rem; letter-spacing: 0.06em;
  padding: 0.6rem 0.8rem; color: var(--ink-soft); background: var(--paper-dim);
}

/* steps (for-clients timeline) */
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; counter-reset: s; }
.step {
  counter-increment: s;
  display: grid; gap: 0.2rem 1.2rem; padding: 1.2rem 0;
  border-top: 1px solid var(--line);
}
@media (min-width: 720px) { .step { grid-template-columns: 4rem 12rem 1fr; align-items: baseline; } }
.step:last-child { border-bottom: 1px solid var(--line); }
.step::before {
  content: counter(s, decimal-leading-zero);
  font-family: var(--mono); font-size: 0.8rem; color: var(--green);
}
.step h3 { margin: 0; font-size: 1.05rem; }
.step .when { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft); }
.step p { margin: 0.3rem 0 0; color: var(--ink-soft); font-size: 0.95rem; }

/* form */
form.intake { display: grid; gap: 0.9rem; max-width: 560px; }
label { display: grid; gap: 0.3rem; font-size: 0.88rem; font-weight: 600; }
input, textarea, select {
  width: 100%; padding: 0.75rem 0.85rem; font-family: inherit; font-size: 0.98rem;
  color: var(--ink); background: var(--paper);
  border: 1.5px solid var(--line); border-radius: 7px;
}
input:focus, textarea:focus { border-color: var(--green); }
textarea { min-height: 118px; resize: vertical; }

/* guide page tables */
.spec { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.spec th, .spec td { text-align: left; vertical-align: top; padding: 0.7rem 0.8rem; border-top: 1px solid var(--line); }
.spec th[scope="row"] { width: 12rem; font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-soft); font-weight: 400; }
.scroll-x { overflow-x: auto; }

/* ============================================================
   FOOTER
   ============================================================ */
footer { background: var(--dark); color: var(--on-dark-soft); padding: clamp(2.6rem, 6vw, 4.5rem) 0 1.5rem; }
.foot-grid { display: grid; gap: 2rem; }
@media (min-width: 780px) { .foot-grid { grid-template-columns: 1.4fr 0.8fr 0.8fr; } }
footer h3 { margin: 0 0 0.7rem; font-size: 0.72rem; font-family: var(--mono); letter-spacing: 0.16em; text-transform: uppercase; color: var(--green); font-weight: 700; }
footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.4rem; }
footer a { color: var(--on-dark-soft); text-decoration: none; font-size: 0.92rem; }
footer a:hover { color: var(--green); text-decoration: underline; }
footer p { margin: 0; font-size: 0.9rem; }
.lockup-white { width: 200px; height: auto; margin-bottom: 1rem; }
.foot-legal {
  margin-top: 2.4rem; padding-top: 1.1rem; border-top: 1px solid rgba(255,255,255,0.12);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.06em; text-transform: uppercase;
}

/* ============================================================
   REDUCED MOTION — nothing animates; the aperture rests in its
   composed state (--ap-p keeps its 0.34 initial value).
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
  .aperture { height: auto; }
  .ap-stage { position: static; height: auto; min-height: 82vh; padding: clamp(3rem, 8vw, 6rem) 0; }
}

/* Narrow screens: the sticky 240vh hero is expensive and the tall
   masked headline is the whole point, so keep it but shorten. */
@media (max-width: 620px) {
  .aperture { height: 200vh; }
  .ap-type {
    max-width: none;
    /* Small glyphs sample a small area of the frame, so a deep zoom lands
       them all on one dark patch of buildings and the headline turns muddy.
       Pull the zoom back and aim at the bridge, where there is light. */
    background-size: calc(152% - 46% * clamp(0, var(--ap-p), 1)) auto;
    background-position: 46% 62%;
    --ap-bright: 1.34;
  }
  .panel-hold { margin-top: -10vh; }
  .panel-hold::before { height: 10vh; }
}
