/* ==========================================================================
   Maguire Industries - design system.

   Brief (Jesse, Capsule note 490622255): "similar but not the same" as
   southerncrosshorticulture.co.nz - same industry, same region. So the same FAMILY (dark,
   cinematic, full-bleed orchard photography, a warm metallic accent) and none of its parts:
   different type (Montserrat, the face the Maguire wordmark is drawn in), different layout
   (left-set hero with a proof strip, a scroll-built orchard for the development stages,
   edge-bled service panels), and the palette is Maguire's own - the bronze-gold of the logo
   on charcoal. No text or image from that site is used.

   LOGO, 2026-10-19: the client's live-site logo (flat bronze MAGUIRE / INDUSTRIES, no arc),
   replacing the silver-and-gold arc version from the designer's pack - the client: "our
   branding is all wrong" (Capsule note 491799781). The gold accents below are the same hue as
   the logo's bronze (#826e3e), lightened so they pass AA on dark; the raw bronze is 3.7:1 on
   --ink, fine for a logo (WCAG exempts logotypes), not for text.

   SECOND PASS, 2026-10-14 (todo.txt, the client: "a little boxy and plain ... I'd love to see
   something that feels more modern, natural and engaging, with a bit more character and a
   smoother flow between sections"). What changed and why:
     - The header is fixed and TRANSPARENT over the top of every page and turns solid ink
       only once the page has scrolled, so the photograph runs under the navigation instead
       of being cut off by a bar.
     - Photographs bleed to the viewport edge (the .bleed grid below, which never overflows
       because it is built from fr tracks and a capped 12-column middle, not 100vw). No more
       rounded corners, no more drop shadows, no more cards: rules, space and type instead.
     - The light surfaces are one continuous cream page; only the dark sections break it, so
       there are fewer hard edges between sections.
     - Motion, all of it quick and all of it switched off under prefers-reduced-motion:
       a short line-rise on the hero copy at load, crisp scroll reveals, gentle parallax on
       the photographs (CSS scroll-driven animation, no script), sticky stage numerals, and
       the scroll-built orchard on the development stages (app.js, a canvas).
   Nothing in the copy changed; verify.mjs section 8 still proves the brief is on the site.

   COLOUR RULES, each measured (build/verify.mjs section "contrast" recomputes them):
     --gold   #c8a55b is a FILL. Dark ink on it is 7.8:1. Never white text on gold (2.3:1).
     --gold-2 #dcbf7e is gold TEXT on dark: 10.2:1 on --ink.
     --bronze #765d2c is gold TEXT on light: 6.2:1 on white, 5.6:1 on --paper. This is the
              logo's own bronze (#80683c) darkened one step; the raw logo colour is 4.9:1 on
              paper, too close to the line for small uppercase labels.
   The logo is bronze on transparent and the live site shows it on black, so the header scrim,
   the mobile menu and the footer are always --ink. The header's own text is measured from
   the rendered pixels by check-live.mjs, because at the top of the page it sits over the
   photograph.
   ========================================================================== */

@font-face {
  font-family: 'Montserrat';
  src: url('/assets/fonts/montserrat-latin.woff2') format('woff2');
  /* the file is the variable font, 100 to 900; the revised design uses the lighter weights */
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --ink: #12161a;
  --ink-2: #1a2026;
  --ink-3: #2b343c;
  --paper: #f6f3ed;
  --paper-2: #efeadf;
  --white: #fff;
  --text: #1c2227;
  --muted: #525c66;
  --line: #ddd6c6;
  --gold: #c8a55b;
  --gold-2: #dcbf7e;
  --bronze: #765d2c;
  --on-dark: #f3f1ec;
  --on-dark-2: #b9c0c6;
  --err: #a12318;
  --ok: #1d6b3a;

  --r: 2px;
  --r-lg: 4px;
  --pill: 999px;
  --wrap: 1240px;
  --gut: clamp(1.15rem, 4vw, 2.5rem);
  --hdr-h: 84px;
  --font: 'Montserrat', 'Segoe UI', system-ui, -apple-system, Roboto, 'Helvetica Neue', Arial, sans-serif;
  /* One easing for everything that moves: fast out of the gate, soft landing. Nothing bounces. */
  --ease: cubic-bezier(.2, .7, .2, 1);
}

/* ---- reset --------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; scroll-padding-top: calc(var(--hdr-h) + 16px); }
body { margin: 0; font-family: var(--font); font-size: 1.0625rem; line-height: 1.65; color: var(--text); background: var(--paper); -webkit-font-smoothing: antialiased; overflow-x: clip; }
img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
ul, ol { padding: 0; }
a { color: inherit; }
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; border-radius: 2px; }
.sec--dark :focus-visible, .hdr :focus-visible, .ftr :focus-visible, .hero :focus-visible, .phero :focus-visible, .cta :focus-visible, .fcta :focus-visible, .mnu :focus-visible, .flowband :focus-visible { outline-color: var(--gold-2); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

.skip { position: absolute; left: 12px; top: -80px; z-index: 300; background: var(--gold); color: var(--ink); padding: .7rem 1.1rem; font-weight: 700; border-radius: var(--r); text-decoration: none; }
.skip:focus { top: 12px; }
.vh { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }

/* ---- type ---------------------------------------------------------------- */
h1, h2, h3, h4 { font-weight: 700; line-height: 1.1; letter-spacing: -.02em; text-wrap: balance; }
h1 { font-size: clamp(2.5rem, 6.2vw, 5rem); line-height: 1.02; letter-spacing: -.03em; }
h1[data-len="long"] { font-size: clamp(2.2rem, 5vw, 4rem); }
h1[data-len="xlong"] { font-size: clamp(1.95rem, 4.1vw, 3.2rem); }
h2 { font-size: clamp(1.85rem, 3.8vw, 3.1rem); line-height: 1.06; letter-spacing: -.025em; }
h2[data-len="long"] { font-size: clamp(1.65rem, 3.1vw, 2.5rem); }
h2[data-len="xlong"] { font-size: clamp(1.45rem, 2.5vw, 2.05rem); line-height: 1.18; }
h3 { font-size: clamp(1.2rem, 1.7vw, 1.45rem); line-height: 1.22; }
h4 { font-size: 1.05rem; }
p + p { margin-top: 1em; }
strong { font-weight: 700; }
/* A highlighted line inside a heading (the home H1's second line). Colour only - the words are
   the brief's. */
.hl { color: var(--gold-2); }

.eyebrow { display: block; font-size: .78rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: var(--bronze); margin-bottom: 1.1rem; }
.eyebrow::after { content: ''; display: block; width: 74px; height: 9px; margin-top: .7rem;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 74 9'%3E%3Cpath d='M0 8.5C22 .5 52 .5 74 8.5 52 3.6 22 3.6 0 8.5z' fill='%23c8a55b'/%3E%3C/svg%3E") no-repeat left center / contain; }
.sec--dark .eyebrow, .hero .eyebrow, .phero .eyebrow, .cta .eyebrow, .flowband .eyebrow { color: var(--gold-2); }
.center .eyebrow::after { margin-inline: auto; background-position: center; }
.lead { font-size: clamp(1.1rem, 1.5vw, 1.3rem); line-height: 1.55; color: var(--muted); }
.sec--dark .lead { color: var(--on-dark-2); }

/* Body links. Scoped with :not(.btn) so a prose rule can never out-rank a button's own colour
   (playbook section 4: on one fleet site every CTA inside prose rendered 1.00:1). */
.prose a:not(.btn), .tlink { color: var(--bronze); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
.prose a:not(.btn):hover, .tlink:hover { color: var(--text); }
.sec--dark .prose a:not(.btn), .sec--dark .tlink, .cta .tlink { color: var(--gold-2); }
.sec--dark .prose a:not(.btn):hover, .sec--dark .tlink:hover, .cta .tlink:hover { color: var(--white); }

/* ---- layout -------------------------------------------------------------- */
.wrap { width: 100%; max-width: calc(var(--wrap) + var(--gut) * 2); margin-inline: auto; padding-inline: var(--gut); }
.wrap--narrow { max-width: calc(860px + var(--gut) * 2); }
.sec { padding-block: clamp(4rem, 9vw, 7.5rem); }
.sec--tight { padding-block: clamp(2.6rem, 5vw, 4rem); }
.sec--paper { background: transparent; }
.sec--dark { background-color: var(--ink); background-image: radial-gradient(120% 80% at 80% 0%, rgba(200,165,91,.07), transparent 60%); color: var(--on-dark); }
.sec--dark h2, .sec--dark h3 { color: var(--white); }
.sec__head { max-width: 800px; margin-bottom: clamp(2.2rem, 5vw, 4rem); }
.sec__head .lead { margin-top: 1.2rem; }
.center { text-align: center; margin-inline: auto; }
.stack > * + * { margin-top: 1em; }
.mt-2 { margin-top: 2rem; }
.mt-3 { margin-top: 3rem; }

/* THE BLEED GRID. A full-width row whose middle twelve columns never exceed --wrap and whose
   outer two tracks are the gutters, growing with the window. A child placed from line 1 or to
   line 15 reaches the viewport edge; one placed inside lines 2 to 14 stays in the column.
   It never produces sideways scroll, because nothing here is sized in 100vw. */
.bleed { display: grid; grid-template-columns: minmax(var(--gut), 1fr) repeat(12, minmax(0, calc(var(--wrap) / 12))) minmax(var(--gut), 1fr); }

/* ---- buttons -------------------------------------------------------------
   Gold is a fill behind dark ink. Hover goes LIGHTER (gold-2, 10.2:1), never to white text. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .6rem; min-height: 52px; padding: .85rem 1.7rem; border: 2px solid var(--gold); border-radius: var(--r); background: var(--gold); color: var(--ink); font-weight: 700; font-size: .95rem; letter-spacing: .02em; line-height: 1.2; text-decoration: none; cursor: pointer; transition: background .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease), transform .18s var(--ease); }
.btn::after { content: ''; width: 18px; height: 10px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 10'%3E%3Cpath d='M0 4.2h14.2L11.6 1.6 12.9.3l4.8 4.7-4.8 4.7-1.3-1.3 2.6-2.6H0z'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 10'%3E%3Cpath d='M0 4.2h14.2L11.6 1.6 12.9.3l4.8 4.7-4.8 4.7-1.3-1.3 2.6-2.6H0z'/%3E%3C/svg%3E") no-repeat center / contain;
  transition: transform .18s var(--ease); }
.btn:hover { background: var(--gold-2); border-color: var(--gold-2); color: var(--ink); }
.btn:hover::after { transform: translateX(5px); }
.btn--sm { min-height: 44px; padding: .55rem 1.05rem; font-size: .86rem; }
.btn--sm::after { display: none; }
.btn--line { background: transparent; color: var(--text); border-color: var(--text); }
.btn--line:hover { background: var(--text); border-color: var(--text); color: var(--white); }
/* Every dark surface a ghost button can sit on. The page hero was missing from this list at
   first and "Back to the home page" rendered dark on dark, 1.13:1 (caught by check-live.mjs). */
.sec--dark .btn--line, .mnu .btn--line, .cta .btn--line, .phero .btn--line, .hero .btn--line, .flowband .btn--line { color: var(--on-dark); border-color: rgba(243,241,236,.55); }
.sec--dark .btn--line:hover, .mnu .btn--line:hover, .cta .btn--line:hover, .phero .btn--line:hover, .hero .btn--line:hover, .flowband .btn--line:hover { background: var(--on-dark); border-color: var(--on-dark); color: var(--ink); }
.btn[disabled] { opacity: .65; cursor: progress; }
.btnrow { display: flex; flex-wrap: wrap; gap: .9rem; margin-top: 2rem; }

/* ---- header ---------------------------------------------------------------
   FIXED and transparent at the top of the page, so the hero photograph runs underneath the
   navigation. Its own scrim (::before) keeps the logo and links readable over a bright sky;
   check-live.mjs measures that from the rendered pixels. Once the page has scrolled it becomes
   solid ink with a blur (app.js toggles .scrolled). Height is fixed in CSS, so nothing shifts
   when the script arrives, and the heroes carry their own top padding. */
.hdr { position: fixed; top: 0; left: 0; right: 0; z-index: 100; color: var(--on-dark); background-color: rgba(18,22,26,0); transition: background-color .35s var(--ease), box-shadow .35s var(--ease); }
.hdr::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: calc(var(--hdr-h) + 70px); z-index: -1; pointer-events: none; opacity: 1; transition: opacity .35s var(--ease);
  background: linear-gradient(180deg, rgba(18,22,26,.82) 0%, rgba(18,22,26,.6) var(--hdr-h), rgba(18,22,26,0) 100%); }
.hdr.scrolled { background-color: rgba(18,22,26,.94); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); box-shadow: 0 1px 0 rgba(255,255,255,.06), 0 12px 32px rgba(0,0,0,.28); }
.hdr.scrolled::before { opacity: 0; }
.hdr__in { display: flex; align-items: center; gap: 1.5rem; min-height: var(--hdr-h); }
.hdr__logo { flex: none; display: block; }
/* The logo file (the live site's own, 600x150) has 29px of clear space on its left, so it is
   pulled left by that share of its height to line the M up with the content edge. */
.hdr__logo img, .ftr__logo img { --logo-h: 54px; width: auto; height: var(--logo-h); margin-left: calc(var(--logo-h) * -29 / 150); }
.nav { display: flex; align-items: center; gap: clamp(1.1rem, 2.2vw, 2.1rem); margin-left: auto; }
.nav a { font-size: .9rem; font-weight: 600; letter-spacing: .03em; text-decoration: none; color: var(--on-dark); padding: .6rem 0; position: relative; white-space: nowrap; }
.nav > a::after, .nav__trig::after { content: ''; position: absolute; left: 0; right: 0; bottom: .2rem; height: 2px; background: var(--gold); transform: scaleX(0); transform-origin: left; transition: transform .22s var(--ease); }
.nav > a:hover::after, .nav > a[aria-current]::after, .nav__grp[data-open] .nav__trig::after, .nav__trig[aria-current]::after { transform: scaleX(1); }
.nav > a:hover, .nav__trig:hover { color: var(--white); }
.hdr__cta { display: flex; align-items: center; gap: 1.1rem; margin-left: clamp(.5rem, 1.5vw, 1.5rem); }
.hdr__tel { display: inline-flex; align-items: center; gap: .5rem; font-weight: 700; font-size: .95rem; text-decoration: none; color: var(--gold-2); white-space: nowrap; min-height: 44px; }
.hdr__tel svg { width: 17px; height: 17px; }
.hdr__tel:hover { color: var(--white); }

/* "Our Services" dropdown.
   🔴 THE DEAD ZONE (F:\_Websites\_knowledge\hover-dropdown-dead-zone.md). The panel sits 12px
   below the trigger; that gap belongs to neither element, so a pointer travelling down leaves
   the group and the menu closes before it arrives. Two fixes, both needed: .nav__menu::before
   bridges the gap (a transparent descendant still hit-tests), and app.js delays the close by
   140ms. build/check-live.mjs drives a REAL mouse to the last item in ~3px steps to prove it. */
.nav__grp { position: relative; display: flex; align-items: center; }
.nav__trig { display: inline-flex; align-items: center; gap: .4rem; }
.nav__trig svg { width: 13px; height: 13px; transition: transform .22s var(--ease); }
.nav__grp[data-open] .nav__trig svg { transform: rotate(180deg); }
.nav__menu { position: absolute; top: calc(100% + 12px); left: -1.1rem; min-width: 300px; background: var(--ink-2); border-top: 3px solid var(--gold); border-radius: 0 0 var(--r-lg) var(--r-lg); box-shadow: 0 2px 6px rgba(18,22,26,.14), 0 18px 44px rgba(18,22,26,.32); padding: .55rem; opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(6px); transition: opacity .18s var(--ease), transform .18s var(--ease), visibility 0s linear .18s; }
.nav__menu::before { content: ''; position: absolute; left: 0; right: 0; top: -18px; height: 18px; }
.nav__grp[data-open] .nav__menu, .no-dropjs .nav__grp:hover .nav__menu, .no-dropjs .nav__grp:focus-within .nav__menu { opacity: 1; visibility: visible; pointer-events: auto; transform: none; transition-delay: 0s; }
.nav__menu ul { list-style: none; }
.nav__menu a { display: block; padding: .8rem .95rem; border-radius: var(--r); font-size: .92rem; }
.nav__menu a:hover, .nav__menu a:focus-visible { background: var(--ink-3); color: var(--white); }
.nav__menu a[aria-current] { color: var(--gold-2); }

.burger { display: none; width: 46px; height: 46px; border: 1px solid rgba(255,255,255,.28); border-radius: var(--r); position: relative; flex: none; }
.burger span, .burger span::before, .burger span::after { position: absolute; left: 11px; right: 11px; height: 2px; background: var(--on-dark); content: ''; }
.burger span { top: 21px; }
.burger span::before { top: -7px; left: 0; right: 0; }
.burger span::after { top: 7px; left: 0; right: 0; }

@media (max-width: 1100px) {
  .nav, .hdr__btn { display: none; }
  .burger { display: block; }
  .hdr__cta { margin-left: auto; }
  :root { --hdr-h: 72px; }
  .hdr__logo img { --logo-h: 46px; }
}
@media (max-width: 420px) { .hdr__tel span { display: none; } .hdr__tel { width: 46px; height: 46px; justify-content: center; border: 1px solid rgba(255,255,255,.28); border-radius: var(--r); } .hdr__tel svg { width: 20px; height: 20px; } }

/* Mobile menu. position:fixed, hidden in plain CSS at first paint, opened by [data-open]. It is
   never in the page flow, so the deferred script arriving cannot move <main> (CLS). */
.mnu { position: fixed; inset: 0; z-index: 200; background: var(--ink); color: var(--on-dark); overflow-y: auto; visibility: hidden; opacity: 0; transition: opacity .22s var(--ease), visibility 0s linear .22s; }
.mnu[data-open] { visibility: visible; opacity: 1; transition-delay: 0s; }
.mnu__in { padding: 0 var(--gut) 2.5rem; max-width: 640px; margin-inline: auto; }
.mnu__top { display: flex; align-items: center; justify-content: space-between; min-height: 72px; border-bottom: 1px solid rgba(255,255,255,.1); margin-bottom: 1.6rem; }
.mnu__close { width: 46px; height: 46px; border: 1px solid rgba(255,255,255,.28); border-radius: var(--r); background: transparent; color: var(--on-dark); font-size: 1.1rem; cursor: pointer; }
.mnu__k { font-size: .76rem; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--gold-2); margin-bottom: .5rem; }
.mnu ul { list-style: none; }
.mnu__sub { margin-bottom: 1.4rem; padding-bottom: 1.1rem; border-bottom: 1px solid rgba(255,255,255,.1); }
.mnu a:not(.btn):not(.hdr__logo) { display: block; padding: .8rem 0; font-size: 1.25rem; font-weight: 600; text-decoration: none; color: var(--on-dark); }
.mnu a:not(.btn)[aria-current] { color: var(--gold-2); }
.mnu__foot { display: grid; gap: .8rem; margin-top: 1.8rem; }
/* The links rise in one after another when the menu opens. */
.js .mnu li, .js .mnu__foot { opacity: 0; transform: translateY(10px); }
.js .mnu[data-open] li, .js .mnu[data-open] .mnu__foot { opacity: 1; transform: none; transition: opacity .4s var(--ease), transform .4s var(--ease); }
.js .mnu[data-open] li:nth-child(2) { transition-delay: .05s; } .js .mnu[data-open] li:nth-child(3) { transition-delay: .1s; } .js .mnu[data-open] li:nth-child(4) { transition-delay: .15s; } .js .mnu[data-open] li:nth-child(5) { transition-delay: .2s; }
.js .mnu[data-open] .mnu__foot { transition-delay: .25s; }

/* ---- hero (home) ----------------------------------------------------------
   The whole first screen: one full-bleed photograph (the film dissolves in over it), the copy
   set bottom-left, the proof strip along the bottom edge. The scrim carries the contrast -
   white on rgba(18,22,26,.88) over any photograph. The height is capped so a full-page
   capture cannot stretch it. */
.hero { position: relative; isolation: isolate; display: grid; min-height: min(100vh, 960px); min-height: min(100svh, 960px); padding-top: var(--hdr-h); background: var(--ink); color: var(--white); overflow: hidden; }
.hero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 50%; z-index: -3; }
/* The hero FILM sits between the photograph and the scrim and is invisible until it is actually
   playing, so the photograph is what paints first (the LCP), what no-JS, reduced-motion and
   data-saver visitors get, and what the film dissolves in over - its poster is the same frame
   (build/prepare-video.py). It shares the photograph's box at every width. app.js starts it;
   there is no autoplay attribute. The button is the WCAG 2.2.2 pause control. */
.hero__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 50%; z-index: -2; opacity: 0; pointer-events: none; }
.hero.is-playing .hero__video { opacity: 1; transition: opacity 1.2s ease; }
.hero__vbtn { position: absolute; top: calc(var(--hdr-h) + 1rem); right: var(--gut); z-index: 2; display: none; width: 44px; height: 44px; padding: 0; border: 1px solid rgba(255,255,255,.6); border-radius: 50%; background: rgba(18,22,26,.72); color: var(--white); cursor: pointer; align-items: center; justify-content: center; }
.hero.has-video .hero__vbtn { display: inline-flex; }
.hero__vbtn:hover { background: rgba(18,22,26,.92); }
.hero__vbtn svg { width: 18px; height: 18px; }
.hero__vbtn .i-play { display: none; }
.hero.is-paused .hero__vbtn .i-play { display: block; }
.hero.is-paused .hero__vbtn .i-pause { display: none; }
@media (prefers-reduced-motion: reduce) { .hero__video, .hero__vbtn { display: none !important; } }
.hero::before { content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(18,22,26,.93) 0%, rgba(18,22,26,.84) 34%, rgba(18,22,26,.38) 66%, rgba(18,22,26,.12) 100%),
              linear-gradient(0deg, rgba(18,22,26,.97) 0%, rgba(18,22,26,.6) 24%, rgba(18,22,26,0) 50%); }
.hero__in { align-self: end; display: grid; gap: clamp(2.4rem, 7vh, 4.5rem); padding-top: clamp(3rem, 9vh, 6rem); }
.hero__copy { max-width: 720px; }
.hero h1 { color: var(--white); }
.hero__lead { margin-top: 1.5rem; max-width: 540px; font-size: clamp(1.15rem, 1.9vw, 1.5rem); font-weight: 600; line-height: 1.35; color: var(--white); }
.hero__sub { margin-top: .8rem; font-size: clamp(1.02rem, 1.3vw, 1.15rem); color: var(--on-dark); max-width: 560px; }
.hero__pair { margin-top: 1.5rem; font-size: .8rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--gold-2); }
.hero .btnrow { margin-top: 1.7rem; }
/* The copy rises line by line when the page opens - quick, once, and never for a reduced-motion
   visitor. Ends at full opacity, so nothing the contrast check reads is mid-animation. */
@keyframes rise { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
.js .hero__copy > * { animation: rise .8s var(--ease) both; }
.js .hero__copy > :nth-child(2) { animation-delay: .1s; }
.js .hero__copy > :nth-child(3) { animation-delay: .18s; }
.js .hero__copy > :nth-child(4) { animation-delay: .26s; }
.js .hero__copy > :nth-child(5) { animation-delay: .34s; }

.proof { position: relative; list-style: none; display: grid; grid-template-columns: repeat(4, 1fr); }
.proof::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: linear-gradient(90deg, var(--gold), rgba(200,165,91,.25)); transform-origin: left; }
.js .proof::before { transform: scaleX(0); animation: drawx 1.4s var(--ease) .5s forwards; }
@keyframes drawx { to { transform: scaleX(1); } }
.proof li { padding: 1.5rem 1.4rem 1.7rem 0; }
.proof li + li { padding-left: 1.4rem; border-left: 1px solid rgba(255,255,255,.14); }
.proof strong { display: block; font-size: clamp(.95rem, 1.35vw, 1.15rem); font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--gold-2); }
.proof span { display: block; margin-top: .3rem; font-size: .92rem; line-height: 1.4; color: var(--on-dark); }
.js .proof li { animation: rise .7s var(--ease) both; animation-delay: calc(.45s + var(--i, 0) * .08s); }
.proof li:nth-child(2) { --i: 1; } .proof li:nth-child(3) { --i: 2; } .proof li:nth-child(4) { --i: 3; }
@media (max-width: 900px) {
  .hero { min-height: 0; padding-top: 0; }
  .hero::before { background: linear-gradient(0deg, rgba(18,22,26,.97) 0%, rgba(18,22,26,.9) 58%, rgba(18,22,26,.62) 76%, rgba(18,22,26,.18) 100%); }
  .hero__img, .hero__video { object-position: 50% 0; height: 62%; }
  .hero__in { padding-top: clamp(11rem, 52vw, 17rem); }
  .proof { grid-template-columns: 1fr 1fr; }
  .proof li { padding: 1.05rem 1rem 1.05rem 0; }
  .proof li + li { border-left: 0; padding-left: 0; }
  .proof li:nth-child(even) { padding-left: 1rem; border-left: 1px solid rgba(255,255,255,.14); }
  .proof li:nth-child(n+3) { border-top: 1px solid rgba(255,255,255,.14); }
}
@media (max-width: 400px) {
  .proof { grid-template-columns: 1fr; }
  .proof li:nth-child(even) { padding-left: 0; border-left: 0; }
  .proof li + li { border-top: 1px solid rgba(255,255,255,.14); }
}

/* ---- page hero (inner pages) ----------------------------------------------
   Every page opens the same way: the photograph under the navigation, the copy set low. The
   photograph settles from a slight zoom as the page opens (CSS only, once). */
.phero { position: relative; isolation: isolate; background: var(--ink); color: var(--white); padding-top: var(--hdr-h); overflow: hidden; }
.phero__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
@keyframes settle { from { transform: scale(1.06); } to { transform: none; } }
.js .phero__img { animation: settle 1.8s var(--ease) both; }
.phero--img::before { content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg, rgba(18,22,26,.95) 0%, rgba(18,22,26,.88) 44%, rgba(18,22,26,.48) 80%, rgba(18,22,26,.22) 100%),
              linear-gradient(0deg, rgba(18,22,26,.92) 0%, rgba(18,22,26,.35) 36%, rgba(18,22,26,0) 70%); }
.phero__in { padding-block: clamp(3rem, 8vw, 6.5rem) clamp(3rem, 7vw, 5.5rem); max-width: 820px; }
.phero--img .phero__in { min-height: min(68vh, 720px); min-height: min(68svh, 720px); display: flex; flex-direction: column; justify-content: flex-end; }
.phero h1 { color: var(--white); }
.phero__lead { margin-top: 1.3rem; font-size: clamp(1.08rem, 1.5vw, 1.25rem); line-height: 1.55; color: var(--on-dark); max-width: 640px; }
.phero__lead + .phero__lead { margin-top: .8rem; }
.js .phero__in > * { animation: rise .75s var(--ease) both; }
.js .phero__in > :nth-child(2) { animation-delay: .08s; } .js .phero__in > :nth-child(3) { animation-delay: .16s; } .js .phero__in > :nth-child(4) { animation-delay: .24s; } .js .phero__in > :nth-child(5) { animation-delay: .32s; }
/* On a phone the copy fills the hero from the breadcrumb down, so the scrim has to be strong all
   the way up: at .6 the breadcrumb measured 3.7:1 over the aerial photograph (check-live.mjs
   reads the real pixels behind the text). */
@media (max-width: 900px) { .phero--img::before { background: linear-gradient(0deg, rgba(18,22,26,.96) 0%, rgba(18,22,26,.9) 60%, rgba(18,22,26,.84) 100%); } }

.crumb { margin-bottom: 1.4rem; }
.crumb ol { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; font-size: .8rem; font-weight: 600; letter-spacing: .04em; color: var(--on-dark-2); }
.crumb li + li::before { content: '/'; margin-right: .5rem; opacity: .6; }
.crumb a { color: var(--on-dark-2); text-decoration: none; }
.crumb a:hover { color: var(--white); text-decoration: underline; }

/* ---- photographs: parallax boxes and clip reveals --------------------------
   .plx is a box that crops a photograph slightly taller than itself; the image drifts a few
   percent as the box crosses the viewport. A CSS scroll-driven animation, so it runs on the
   compositor with no script and no jank - and only where the browser supports it; elsewhere the
   image simply sits still. Never for a reduced-motion visitor. */
.plx { position: relative; overflow: hidden; background: var(--ink-2); }
.plx > img { position: absolute; left: 0; top: -8%; width: 100%; height: 116%; object-fit: cover; }
@supports (animation-timeline: view()) {
  .js .plx > img { animation: plx linear both; animation-timeline: view(); }
  @keyframes plx { from { transform: translateY(-5%); } to { transform: translateY(5%); } }
}
@media (prefers-reduced-motion: reduce) { .js .plx > img { animation: none; } }
/* A photograph that is revealed with a wipe from the bottom as it comes into view. */
.js [data-rv="clip"] { clip-path: inset(0 0 18% 0); }
.js [data-rv="clip"].is-in { clip-path: inset(0 0 0 0); transition: opacity .7s var(--ease), transform .7s var(--ease), clip-path .9s var(--ease); }

/* ---- service panels (home) -------------------------------------------------
   Three bleed rows: the photograph runs from the viewport edge to just past the middle, the copy
   sits in the column beside it, and the panels alternate sides. A large outlined numeral behind
   the copy gives each panel its own weight. On a phone the photograph is edge to edge. */
.svcs { display: grid; gap: clamp(3.5rem, 8vw, 7rem); }
.svc { align-items: center; }
.svc__img { grid-column: 1 / 9; aspect-ratio: 4 / 3; }
.svc__body { grid-column: 9 / 14; position: relative; padding-left: clamp(1.6rem, 4vw, 4.5rem); max-width: 560px; }
.svc--flip .svc__img { grid-column: 7 / 15; }
.svc--flip .svc__body { grid-column: 2 / 7; padding-left: 0; padding-right: clamp(1.6rem, 4vw, 4.5rem); }
.svc__n { font-size: clamp(3.4rem, 7vw, 6.5rem); font-weight: 800; line-height: .9; letter-spacing: -.03em; color: var(--paper); -webkit-text-stroke: 2px var(--gold); paint-order: stroke fill; margin-bottom: 1.1rem; }
.svc h3 { font-size: clamp(.95rem, 1.2vw, 1.05rem); letter-spacing: .16em; text-transform: uppercase; color: var(--bronze); }
.svc h3 a { text-decoration: none; }
.svc h3 a:hover { color: var(--text); }
.svc__tag { margin-top: .8rem; font-size: clamp(1.7rem, 3vw, 2.5rem); font-weight: 700; line-height: 1.08; letter-spacing: -.025em; color: var(--text); text-wrap: balance; }
.svc__body p:not(.svc__tag):not(.svc__n) { color: var(--muted); }
.svc__tag + p { margin-top: 1.2rem; }
@media (max-width: 860px) {
  .svcs { gap: 3.5rem; }
  .svc__img, .svc--flip .svc__img { grid-column: 1 / 15; aspect-ratio: 3 / 2; }
  .svc__body, .svc--flip .svc__body { grid-column: 2 / 14; padding: 1.8rem 0 0; max-width: none; }
}

/* ---- the journey: ten stages and the orchard that builds itself ---------------
   Left, a sticky canvas on which app.js draws a line-art orchard block - layout, pegs, posts,
   beams, wires, strings, shelters, cover, vines - adding each stage as the reader scrolls
   through the list on the right. The canvas is decoration (aria-hidden); the list is the
   content and reads exactly the same with no script or no canvas. A gold line down the list
   fills to the reader's position (--p from app.js). On a phone the canvas sits at the top of the
   screen and the list scrolls under it. */
.journey__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 5.5rem); align-items: start; }
.journey__vis { position: sticky; top: calc(var(--hdr-h) + 1.5rem); aspect-ratio: 4 / 3; background: var(--ink); display: none; }
.js .journey__vis { display: block; }
.journey__vis canvas { width: 100%; height: 100%; }
.steps { list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 2.6rem 1.6rem; }
.steps li { position: relative; padding-top: 1.35rem; border-top: 1px solid rgba(255,255,255,.2); }
.steps li::before { content: ''; position: absolute; top: -5px; left: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--gold); }
.steps__n { display: block; font-size: .8rem; font-weight: 700; letter-spacing: .16em; color: var(--gold-2); }
.steps__t { display: block; margin-top: .45rem; font-size: .96rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; line-height: 1.3; color: var(--white); }
.steps__t a { text-decoration: none; }
.steps__t a:hover { color: var(--gold-2); text-decoration: underline; text-underline-offset: 4px; }
.steps__d { display: block; margin-top: .5rem; font-size: .94rem; line-height: 1.5; color: var(--on-dark-2); }
.steps--journey { position: relative; grid-template-columns: 1fr; gap: 0; padding-left: 2rem; }
.steps--journey::before, .steps--journey::after { content: ''; position: absolute; left: 4px; top: 0; bottom: 0; width: 1px; background: rgba(255,255,255,.14); }
.steps--journey::after { background: var(--gold); transform-origin: top; transform: scaleY(var(--p, 0)); }
.steps--journey li { padding: 1.35rem 0 1.4rem; border-top: 1px solid rgba(255,255,255,.1); transition: opacity .4s var(--ease); }
.steps--journey li:first-child { border-top: 0; padding-top: .4rem; }
.steps--journey li::before { top: 1.75rem; left: -2rem; background: rgba(255,255,255,.22); transition: background .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease); }
.steps--journey li:first-child::before { top: .8rem; }
.steps--journey li.is-done::before { background: var(--gold); }
.steps--journey li.is-active::before { background: var(--gold-2); box-shadow: 0 0 0 4px rgba(220,191,126,.22); transform: scale(1.25); }
/* .72 alpha, not .6: at .6 the gold numerals measured 4.40:1 on ink (check-live, run 38499635560) */
.steps--journey .steps__n { display: inline-block; margin-right: .8rem; color: rgba(220,191,126,.72); }
.steps--journey .steps__t { display: inline; margin: 0; font-size: 1.05rem; color: var(--on-dark-2); transition: color .3s var(--ease); }
.steps--journey .steps__d { margin-top: .45rem; }
.steps--journey li.is-active .steps__t, .steps--journey li.is-done .steps__t { color: var(--white); }
.steps--journey li.is-active .steps__n { color: var(--gold-2); }
/* Dimmed by COLOUR alpha, never by element opacity: the contrast check composites the colour and
   does not see an opacity, and at opacity .62 this text would really have been 4.5:1. */
.js .steps--journey li:not(.is-active):not(.is-done) .steps__d { color: rgba(185,192,198,.74); }
@media (max-width: 1000px) { .steps:not(.steps--journey) { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 900px) {
  .journey__grid { grid-template-columns: 1fr; gap: 1.5rem; }
  .journey__vis { top: var(--hdr-h); aspect-ratio: 16 / 10; z-index: 2; }
  .journey__vis::after { content: ''; position: absolute; left: 0; right: 0; bottom: -28px; height: 28px; background: linear-gradient(180deg, var(--ink), rgba(18,22,26,0)); pointer-events: none; }
}
@media (max-width: 560px) {
  .steps:not(.steps--journey) { grid-template-columns: 1fr; gap: 0; border-left: 1px solid rgba(255,255,255,.2); margin-left: 4px; }
  .steps:not(.steps--journey) li { border-top: 0; padding: 0 0 1.5rem 1.4rem; }
  .steps:not(.steps--journey) li::before { top: .45rem; left: -5px; }
}
.outro { margin-top: clamp(2.6rem, 6vw, 4.5rem); padding-top: clamp(2rem, 4vw, 3rem); border-top: 1px solid rgba(255,255,255,.14); display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.5rem 3rem; align-items: center; }
.outro h3 { font-size: clamp(1.6rem, 3vw, 2.4rem); }
.outro p { margin-top: .6rem; color: var(--on-dark-2); max-width: 620px; }
@media (max-width: 760px) { .outro { grid-template-columns: 1fr; } }

/* ---- full-bleed photograph between sections --------------------------------- */
.band { height: clamp(300px, 56vh, 640px); }
.band > img { top: -12%; height: 124%; }
@supports (animation-timeline: view()) { .js .band > img { animation-name: plxband; } @keyframes plxband { from { transform: translateY(-9%); } to { transform: translateY(9%); } } }

/* ---- stages (development page) ----------------------------------------------
   One bleed row per stage: the outlined numeral in the first column stays put while its stage
   scrolls past (position: sticky inside the row), the copy in the middle, and the photograph
   out to the right-hand edge of the window. */
.stages { display: grid; }
.stage { padding-block: clamp(2.4rem, 5.5vw, 4.5rem); border-top: 1px solid var(--line); align-items: start; }
.stage:first-child { border-top: 0; padding-top: 0; }
/* Outlined numerals. paint-order puts the fill ON TOP of the stroke: Montserrat's variable
   outlines overlap inside each glyph, and a plain transparent-fill stroke shows every overlap. */
.stage__n { grid-column: 2 / 3; position: sticky; top: calc(var(--hdr-h) + 1.4rem); font-size: clamp(2.4rem, 5vw, 4.2rem); font-weight: 800; line-height: .9; letter-spacing: -.04em; color: var(--paper); -webkit-text-stroke: 2.5px var(--bronze); paint-order: stroke fill; }
.stage__body { grid-column: 3 / 9; max-width: 640px; padding: .35rem clamp(1rem, 3vw, 3rem) 0 clamp(.5rem, 1.5vw, 1.25rem); }
.stage:not(.stage--img) .stage__body { grid-column: 3 / 11; }
.stage__img { grid-column: 9 / 15; aspect-ratio: 4 / 3; align-self: start; position: sticky; top: calc(var(--hdr-h) + 1.4rem); }
.stage h2 { font-size: clamp(.95rem, 1.2vw, 1.05rem); letter-spacing: .18em; text-transform: uppercase; color: var(--bronze); line-height: 1.3; }
.stage h3 { margin-top: .6rem; font-size: clamp(1.6rem, 2.9vw, 2.35rem); line-height: 1.1; letter-spacing: -.022em; }
.stage h3 + p, .stage h3 + ul { margin-top: 1.1rem; }
.stage__body p, .stage__body li { color: var(--muted); }
@media (max-width: 820px) {
  .stage { row-gap: 1.2rem; }
  .stage__n { grid-column: 2 / 14; position: static; font-size: 2.6rem; }
  .stage__body, .stage:not(.stage--img) .stage__body { grid-column: 2 / 14; padding: 0; }
  /* relative, NOT static: .plx places its photograph absolutely inside this box, and static
     would send it to the top of the page (found by the 390px capture, 2026-10-14) */
  .stage__img { grid-column: 1 / 15; position: relative; top: auto; aspect-ratio: 3 / 2; margin-top: .6rem; }
}

/* ---- lists ---------------------------------------------------------------- */
.ticks { list-style: none; display: grid; gap: .6rem; margin-top: 1rem; }
.ticks li { position: relative; padding-left: 1.7rem; }
.ticks li::before { content: ''; position: absolute; left: 0; top: .62em; width: 12px; height: 7px; background: var(--gold);
  clip-path: path('M0 7C3.6 1.4 8.4 1.4 12 7 8.4 3.4 3.6 3.4 0 7z'); }
p + .ticks { margin-top: 1rem; }
.ticks + p { margin-top: 1.2rem; }
.ticks--cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem 2rem; }
@media (max-width: 600px) { .ticks--cols { grid-template-columns: 1fr; } }

/* ---- splits: contained (.split) and bled to one edge (.splitb) ---------------- */
.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.split--top { align-items: start; }
.split__img { aspect-ratio: 4 / 3; }
.split__img--tall { aspect-ratio: 4 / 5; }
.split__body h2 + p, .split__body h2 + .kicker, .split__body h2 + ul { margin-top: 1.2rem; }
.split__body p { color: var(--muted); }
.sec--dark .split__body p { color: var(--on-dark-2); }
.kicker { font-size: clamp(1.15rem, 1.7vw, 1.4rem); font-weight: 700; line-height: 1.3; color: var(--text) !important; }
.sec--dark .kicker { color: var(--white) !important; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; } .split--imgfirst .split__img { order: -1; } }

.splitb { align-items: center; }
.splitb .split__body { grid-column: 2 / 8; padding-right: clamp(1.5rem, 4vw, 4.5rem); }
.splitb .split__img { grid-column: 8 / 15; aspect-ratio: 5 / 4; }
.splitb--left .split__img { grid-column: 1 / 8; }
.splitb--left .split__body { grid-column: 8 / 14; padding-right: 0; padding-left: clamp(1.5rem, 4vw, 4.5rem); }
@media (max-width: 860px) {
  .splitb .split__img, .splitb--left .split__img { grid-column: 1 / 15; aspect-ratio: 3 / 2; order: -1; }
  .splitb .split__body, .splitb--left .split__body { grid-column: 2 / 14; padding: 1.8rem 0 0; }
}

/* ---- flow (FIND > RECORD > ... and MAP > DESIGN > SET-OUT > BUILD) -----------
   Nodes on a line, not a row of boxes. The line draws in as the list comes into view. */
.flow { list-style: none; position: relative; display: grid; grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr)); gap: 1.6rem; padding-top: 1.6rem; }
.flow::before { content: ''; position: absolute; left: 0; right: 0; top: 6px; height: 1px; background: rgba(255,255,255,.18); }
.flow::after { content: ''; position: absolute; left: 0; right: 0; top: 6px; height: 1px; background: var(--gold); transform-origin: left; transform: scaleX(0); transition: transform 1.3s var(--ease) .15s; }
.flow.is-in::after { transform: scaleX(1); }
.flow li { position: relative; }
.flow li::before { content: ''; position: absolute; top: -1.6rem; left: 0; width: 13px; height: 13px; border-radius: 50%; background: var(--ink); border: 2px solid var(--gold); transform: translateY(0); }
.flow strong { display: block; font-size: 1rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--gold-2); }
.flow span { display: block; margin-top: .55rem; font-size: .95rem; line-height: 1.5; color: var(--on-dark); max-width: 230px; }
.flow--words strong { font-size: clamp(1.1rem, 1.6vw, 1.35rem); }
@media (max-width: 900px) {
  .flow { grid-template-columns: 1fr; gap: 1.2rem; padding-top: 0; padding-left: 1.6rem; }
  .flow::before, .flow::after { left: 6px; right: auto; top: 0; bottom: 0; width: 1px; height: auto; }
  .flow::after { transform-origin: top; transform: scaleY(0); }
  .flow.is-in::after { transform: scaleY(1); }
  .flow li::before { top: .3rem; left: -1.6rem; }
}
.flowband { background-color: var(--ink); color: var(--on-dark); padding-block: clamp(3rem, 6vw, 4.5rem); }
.flowband .btnrow { margin-top: clamp(1.8rem, 3vw, 2.4rem); }

/* ---- numbered process ----------------------------------------------------- */
.proc { list-style: none; display: grid; gap: 0; counter-reset: proc; }
.proc li { counter-increment: proc; display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: 1.2rem; padding-block: 1.6rem; border-top: 1px solid var(--line); }
.proc li:last-child { border-bottom: 1px solid var(--line); }
.proc li::before { content: counter(proc); width: 52px; height: 52px; display: grid; place-items: center; border: 2px solid var(--gold); border-radius: 50%; font-weight: 700; font-size: 1.15rem; color: var(--bronze); }
.proc h3 { font-size: 1.22rem; }
.proc h3 + p { margin-top: .5rem; }
.proc p { color: var(--muted); }
.note { margin-top: 1.8rem; padding: 1.1rem 1.3rem; border-left: 3px solid var(--gold); background: var(--paper-2); font-size: .98rem; color: var(--text); }
.sec--dark .note { background: var(--ink-2); color: var(--on-dark); }

/* ---- capabilities (mapping) ----------------------------------------------- */
.caps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2.4rem clamp(1.5rem, 3vw, 3rem); }
.cap { padding-top: 1.4rem; border-top: 1px solid var(--line); position: relative; }
.cap::before { content: ''; position: absolute; left: 0; top: -1px; width: 48px; height: 2px; background: var(--gold); }
.cap h2 { font-size: 1.02rem; letter-spacing: .14em; text-transform: uppercase; line-height: 1.3; }
.cap p { margin-top: .7rem; color: var(--muted); }
@media (max-width: 900px) { .caps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .caps { grid-template-columns: 1fr; } }

/* ---- promises + people (company) ------------------------------------------ */
.promises { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1.6rem, 3vw, 2.8rem) clamp(2rem, 5vw, 5rem); }
.promise { padding-top: 1.4rem; border-top: 1px solid rgba(255,255,255,.18); position: relative; }
.promise::before { content: ''; position: absolute; left: 0; top: -1px; width: 48px; height: 2px; background: var(--gold); }
.promise h3 { color: var(--white); }
.promise p { color: var(--on-dark-2); }
.promise h3 + p { margin-top: .8rem; }
.promise--lead { grid-column: 1 / -1; max-width: 820px; }
.promise--lead h3 { font-size: clamp(1.6rem, 2.8vw, 2.3rem); }
@media (max-width: 760px) { .promises { grid-template-columns: 1fr; } }

.people { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2.4rem clamp(2rem, 5vw, 5rem); }
.person { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: 1.4rem; padding-top: 1.6rem; border-top: 1px solid var(--line); }
.person__mono { width: 64px; height: 64px; display: grid; place-items: center; border-radius: 50%; background: var(--ink); color: var(--gold-2); font-weight: 700; font-size: 1.15rem; letter-spacing: .04em; }
.person h3 { font-size: 1.3rem; }
.person__role { margin-top: .25rem; font-size: .78rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--bronze); }
.person__role + p { margin-top: .9rem; }
.person p:not(.person__role) { color: var(--muted); font-size: 1rem; }
@media (max-width: 860px) { .people { grid-template-columns: 1fr; gap: 1.6rem; } }
@media (max-width: 480px) { .person { grid-template-columns: 1fr; gap: .8rem; } }

.twobiz { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2rem; margin-top: 2rem; }
.twobiz div { padding-top: 1.3rem; border-top: 2px solid var(--gold); }
.twobiz strong { display: block; font-size: .8rem; letter-spacing: .18em; text-transform: uppercase; color: var(--bronze); margin-bottom: .5rem; }
@media (max-width: 640px) { .twobiz { grid-template-columns: 1fr; } }

/* ---- project cards + filters ----------------------------------------------
   No box: the photograph, a line, the words. The photograph lifts and zooms a little on hover. */
.pcards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2.2rem clamp(1.2rem, 2.5vw, 2rem); }
.pcard { position: relative; display: flex; flex-direction: column; }
.pcard__img { aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-2); }
.pcard__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .7s var(--ease); }
.pcard:hover .pcard__img img { transform: scale(1.05); }
.pcard__body { display: flex; flex-direction: column; flex: 1; padding: 1.2rem 0 0; border-top: 1px solid var(--line); margin-top: 1rem; position: relative; }
.pcard__body::before { content: ''; position: absolute; left: 0; top: -1px; height: 2px; width: 40px; background: var(--gold); transition: width .5s var(--ease); }
.pcard:hover .pcard__body::before { width: 100%; }
.pcard__meta { font-size: .76rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--bronze); }
.pcard h3 { margin-top: .5rem; font-size: 1.3rem; }
.pcard h3 a { text-decoration: none; color: var(--text); }
.pcard h3 a::after { content: ''; position: absolute; inset: 0; }
.pcard p.pcard__sum { margin-top: .65rem; font-size: .98rem; color: var(--muted); }
.pcard__go { margin-top: auto; padding-top: 1.1rem; font-size: .88rem; font-weight: 700; letter-spacing: .04em; color: var(--text); text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; text-underline-offset: 5px; }
.pcard__draft { position: absolute; top: .8rem; left: .8rem; z-index: 1; padding: .3rem .6rem; border-radius: var(--r); background: var(--ink); color: var(--gold-2); font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.pcard[hidden] { display: none; }
@media (max-width: 980px) { .pcards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .pcards { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .pcard__img img, .pcard__body::before { transition: none; } .pcard:hover .pcard__img img { transform: none; } }

.pfilter { list-style: none; display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 2.4rem; }
.pfilter a { display: inline-flex; align-items: center; min-height: 44px; padding: .5rem 1.1rem; border: 1.5px solid var(--text); border-radius: var(--pill); font-size: .88rem; font-weight: 600; text-decoration: none; color: var(--text); background: transparent; transition: background .18s var(--ease), color .18s var(--ease); }
.pfilter a:hover { background: var(--paper-2); }
.pfilter a[aria-current="true"] { background: var(--ink); border-color: var(--ink); color: var(--white); }
.pempty { padding: 1.6rem 1.4rem; border: 1px dashed var(--muted); color: var(--muted); }
.pempty[hidden] { display: none; }

/* ---- project page ---------------------------------------------------------- */
.draftnote { background: var(--gold); color: var(--ink); font-size: .92rem; font-weight: 600; }
.draftnote .wrap { padding-block: .8rem; }
.proj { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 340px); gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
.proj__body h2 { font-size: clamp(1.35rem, 2.2vw, 1.75rem); margin-top: 2.4rem; }
.proj__body h2:first-child { margin-top: 0; }
.proj__body h2 + p, .proj__body h2 + ul { margin-top: .9rem; }
.proj__body p, .proj__body li { color: var(--muted); }
.todo { padding: .9rem 1.1rem; border: 1px dashed var(--bronze); background: var(--paper-2); color: var(--text) !important; font-size: .96rem; }
.todo strong { color: var(--bronze); }
.pdetails { position: sticky; top: calc(var(--hdr-h) + 24px); padding: 1.6rem 1.5rem 1.7rem; background: var(--paper-2); border-top: 2px solid var(--gold); }
.pdetails h2 { font-size: .82rem; letter-spacing: .18em; text-transform: uppercase; color: var(--bronze); }
.pdetails dl { margin-top: 1rem; display: grid; gap: .9rem; }
.pdetails dt { font-size: .74rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.pdetails dd { font-weight: 600; }
.pdetails ul { list-style: none; margin-top: .3rem; display: grid; gap: .35rem; }
@media (max-width: 900px) { .proj { grid-template-columns: 1fr; } .pdetails { position: static; } }

/* ---- gallery + lightbox ---------------------------------------------------- */
.gal { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .8rem; }
.gal__b { padding: 0; border: 0; background: var(--ink-2); overflow: hidden; cursor: zoom-in; aspect-ratio: 3 / 2; }
.gal__b img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease), opacity .2s ease; }
.gal__b:hover img { transform: scale(1.05); opacity: .92; }
@media (max-width: 760px) { .gal { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (prefers-reduced-motion: reduce) { .gal__b img { transition: none; } }

.lb { position: fixed; inset: 0; z-index: 220; display: none; place-items: center; padding: 3.5rem 1rem 1.5rem; background: rgba(12,15,18,.95); }
.lb[data-open] { display: grid; }
body.lb-open { overflow: hidden; }
.lb__fig { max-width: min(1500px, 100%); max-height: 100%; display: grid; gap: .7rem; justify-items: center; }
.lb__fig img { max-width: 100%; max-height: calc(100vh - 7.5rem); width: auto; height: auto; }
.lb__n { margin: 0; color: var(--on-dark-2); font-size: .8rem; }
.lb__x, .lb__btn { position: absolute; width: 48px; height: 48px; border: 1px solid rgba(255,255,255,.4); border-radius: 50%; background: rgba(18,22,26,.75); color: var(--white); font-size: 1.3rem; line-height: 1; cursor: pointer; }
.lb__x:hover, .lb__btn:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.lb__x { top: .8rem; right: .8rem; }
.lb__prev { left: .8rem; top: 50%; transform: translateY(-50%); }
.lb__next { right: .8rem; top: 50%; transform: translateY(-50%); }

/* ---- form ----------------------------------------------------------------- */
.contact { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
@media (max-width: 900px) { .contact { grid-template-columns: 1fr; } }
.formcard { background: var(--white); border-top: 3px solid var(--gold); padding: clamp(1.4rem, 3.5vw, 2.6rem); }
.formcard__title { font-size: .82rem; letter-spacing: .18em; text-transform: uppercase; color: var(--bronze); }
.f-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.1rem 1.2rem; margin-top: 1.3rem; }
.f-row--full { grid-column: 1 / -1; }
@media (max-width: 600px) { .f-grid { grid-template-columns: 1fr; } }
.f-label { display: block; font-size: .9rem; font-weight: 600; margin-bottom: .4rem; color: var(--text); }
.f-opt { font-weight: 500; color: var(--muted); }
.f-req { color: var(--err); }
.f-input, .f-select, .f-textarea { width: 100%; min-height: 50px; padding: .7rem .9rem; border: 1.5px solid #8b939a; border-radius: var(--r); background: var(--white); color: var(--text); font-size: 1rem; }
.f-textarea { min-height: 150px; resize: vertical; line-height: 1.5; }
.f-input:focus, .f-select:focus, .f-textarea:focus { outline: 3px solid var(--gold); outline-offset: 1px; border-color: var(--text); }
.f-file { width: 100%; padding: .9rem; border: 1.5px dashed #8b939a; border-radius: var(--r); background: var(--paper); font-size: .95rem; color: var(--text); }
.f-file::file-selector-button { margin-right: .9rem; min-height: 40px; padding: .45rem .9rem; border: 1.5px solid var(--text); border-radius: var(--r); background: var(--white); color: var(--text); font: inherit; font-weight: 600; font-size: .88rem; cursor: pointer; }
.f-help { margin-top: .4rem; font-size: .84rem; color: var(--muted); }
.f-hp { position: absolute !important; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.f-submit { margin-top: 1.5rem; width: 100%; }
.f-note { margin-top: 1rem; font-size: .9rem; color: var(--muted); }
.f-msg { margin-top: 1rem; padding: .85rem 1rem; border-radius: var(--r); font-weight: 600; font-size: .95rem; }
.f-msg--err { background: #fbeceb; color: var(--err); border: 1px solid #e8b9b4; }
.f-msg--ok { background: #e9f5ee; color: var(--ok); border: 1px solid #b5dcc4; }
/* The no-JavaScript failure message. The Function redirects a failed native post to
   /contact/#send-failed, and :target is what shows it - no script involved. */
.f-target { display: none; margin: 1rem 0 0; }
.f-target:target { display: block; }
.cinfo { display: grid; gap: 1.6rem; }
.cinfo__block { padding-top: 1.3rem; border-top: 1px solid var(--line); }
.cinfo__k { font-size: .76rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--bronze); margin-bottom: .45rem; }
.cinfo__big { font-size: clamp(1.5rem, 2.6vw, 2rem); font-weight: 700; letter-spacing: -.02em; text-decoration: none; color: var(--text); }
.cinfo__big:hover { color: var(--bronze); }
.cinfo a.cinfo__mail { font-weight: 600; color: var(--text); text-decoration: underline; text-decoration-color: var(--gold); text-decoration-thickness: 2px; text-underline-offset: 4px; overflow-wrap: anywhere; }
.cinfo__img { aspect-ratio: 4 / 3; }

/* ---- prose (privacy) ------------------------------------------------------- */
.prose { max-width: 780px; }
.prose h2 { font-size: clamp(1.3rem, 2vw, 1.6rem); margin-top: 2.4rem; }
.prose h2 + p, .prose h2 + ul { margin-top: .9rem; }
.prose ul { margin-top: .9rem; padding-left: 1.2rem; display: grid; gap: .45rem; }
.prose p, .prose li { color: var(--text); }
.prose .meta { color: var(--muted); font-size: .92rem; }

/* ---- CTA band (each page's own final call to action) ----------------------- */
.cta { position: relative; isolation: isolate; background-color: var(--ink-2); background-image: radial-gradient(90% 70% at 20% 100%, rgba(200,165,91,.1), transparent 60%); color: var(--on-dark); overflow: hidden; }
/* The arc of the Maguire mark (it is on their favicon), rising just clear of the bottom edge -
   never behind the copy. It widens into place as the band comes into view. */
.cta::before { content: ''; position: absolute; z-index: -1; left: 50%; top: calc(100% - 52px); width: min(1700px, 170vw); aspect-ratio: 5 / 2; transform: translateX(-50%); border-radius: 50%; border-top: 3px solid rgba(200,165,91,.6); transition: transform 1.4s var(--ease), opacity 1s var(--ease); }
.js .cta:not(.is-in)::before { transform: translateX(-50%) scaleX(.3); opacity: 0; }
.cta__in { padding-block: clamp(3.8rem, 8vw, 6.5rem) clamp(4.8rem, 9vw, 7.5rem); }
.cta__in > * { max-width: 820px; }
.cta h2 { color: var(--white); }
.cta p { margin-top: 1.1rem; font-size: clamp(1.05rem, 1.4vw, 1.2rem); color: var(--on-dark); max-width: 640px; }
.cta p + p { margin-top: .6rem; }
.cta .btnrow { margin-top: 2rem; }

/* ---- site-wide final CTA (the brief: "near the bottom of all major pages") -- */
.fcta { background: var(--gold); color: var(--ink); }
.fcta__in { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.2rem 3rem; align-items: center; padding-block: clamp(2rem, 4vw, 3rem); }
.fcta h2 { font-size: clamp(1.4rem, 2.4vw, 2rem); color: var(--ink); }
.fcta p { margin-top: .45rem; color: var(--ink); max-width: 720px; font-weight: 500; }
.fcta .btn { background: var(--ink); border-color: var(--ink); color: var(--white); }
.fcta .btn:hover { background: var(--ink-3); border-color: var(--ink-3); color: var(--white); }
@media (max-width: 760px) { .fcta__in { grid-template-columns: 1fr; } }

/* ---- footer ---------------------------------------------------------------- */
.ftr { position: relative; background: var(--ink); color: var(--on-dark-2); padding-block: clamp(3rem, 6vw, 5rem) 1.6rem; font-size: .96rem; }
.ftr::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: linear-gradient(90deg, rgba(200,165,91,0), rgba(200,165,91,.7) 30%, rgba(200,165,91,.7) 70%, rgba(200,165,91,0)); }
.ftr a { color: var(--on-dark); text-decoration: none; }
.ftr a:hover { color: var(--gold-2); text-decoration: underline; text-underline-offset: 4px; }
.ftr ul { list-style: none; }
.ftr__top { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, .8fr) minmax(0, 1fr); gap: 2.4rem clamp(2rem, 5vw, 5rem); }
.ftr__logo img { --logo-h: 56px; }
.ftr__pair { margin-top: 1.4rem; font-weight: 700; color: var(--white); }
.ftr__svc { display: flex; flex-wrap: wrap; gap: .3rem 0; margin-top: .5rem; }
.ftr__svc li + li::before { content: '\00b7'; margin-inline: .6rem; color: var(--gold); }
.ftr__svc a, .ftr__nav a, .ftr__legal a { display: inline-block; padding-block: .32rem; }
.ftr__base { margin-top: 1rem; max-width: 420px; }
.ftr__nav ul { display: grid; gap: .1rem; }
.ftr__nav a { font-weight: 600; }
.ftr__contact { display: grid; gap: .4rem; align-content: start; justify-items: start; }
.ftr__phone { font-size: 1.5rem; font-weight: 700; letter-spacing: -.01em; color: var(--gold-2) !important; }
.ftr__contact > a { padding-block: .2rem; overflow-wrap: anywhere; }
.ftr__legal { display: flex; flex-wrap: wrap; gap: 0 1.4rem; margin-top: .9rem; }
.ftr__bottom { display: flex; flex-wrap: wrap; justify-content: space-between; gap: .6rem 2rem; margin-top: clamp(2.2rem, 5vw, 3.5rem); padding-top: 1.3rem; border-top: 1px solid rgba(255,255,255,.12); font-size: .86rem; }
.ftr__credit { color: var(--on-dark-2) !important; display: inline-block; padding-block: .3rem; }
.ftr__credit:hover { color: var(--gold-2) !important; }
@media (max-width: 860px) { .ftr__top { grid-template-columns: 1fr 1fr; } .ftr__brand { grid-column: 1 / -1; } }
@media (max-width: 520px) { .ftr__top { grid-template-columns: 1fr; } }

/* ---- floating contact bar --------------------------------------------------
   Re-themed for this palette, not pasted: dark ink icons on the gold fill (7.8:1), inverting
   to gold-2 on ink on hover (10.2:1). Collapsed buttons are visibility:hidden AND
   pointer-events:none so they leave the tab order. */
.floatbar { position: fixed; right: 16px; bottom: 16px; z-index: 110; display: grid; gap: 10px; justify-items: center; }
.floatbar__btn, .floatbar__toggle { width: 52px; height: 52px; border-radius: var(--pill); display: grid; place-items: center; background: var(--gold); color: var(--ink); border: 2px solid var(--ink); cursor: pointer; text-decoration: none; box-shadow: 0 2px 6px rgba(18,22,26,.14), 0 18px 44px rgba(18,22,26,.22); transition: transform .18s var(--ease), background .18s var(--ease), color .18s var(--ease); }
.floatbar__btn svg, .floatbar__toggle svg { width: 23px; height: 23px; fill: currentColor; }
.floatbar__btn { opacity: 0; visibility: hidden; pointer-events: none; transform: translateY(8px) scale(.85); }
.floatbar[data-open] .floatbar__btn { opacity: 1; visibility: visible; pointer-events: auto; transform: none; }
/* Restated AFTER the [data-open] rule: an equally specific transform:none written later
   silently cancels a hover scale. That bug survived weeks in the fleet reference. */
.floatbar[data-open] .floatbar__btn:hover { transform: scale(1.08); background: var(--ink); color: var(--gold-2); border-color: var(--gold-2); }
.floatbar__toggle:hover { background: var(--ink); color: var(--gold-2); border-color: var(--gold-2); }
.floatbar[data-open] .floatbar__toggle { background: var(--ink); color: var(--gold-2); border-color: var(--gold-2); }
@media (max-width: 560px) { .floatbar { right: 12px; bottom: 12px; } }

.fbpop { position: fixed; inset: 0; z-index: 230; display: none; place-items: center; padding: 1.5rem; background: rgba(12,15,18,.72); }
.fbpop[data-open] { display: grid; }
.fbpop__card { background: var(--white); border-radius: var(--r-lg); border-top: 5px solid var(--gold); padding: 2rem 2.25rem; text-align: center; position: relative; box-shadow: 0 2px 6px rgba(18,22,26,.14), 0 18px 44px rgba(18,22,26,.22); max-width: 400px; width: 100%; }
.fbpop__card .fbpop__t { font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-bottom: .6rem; }
.fbpop__card .fbpop__num { font-size: 2rem; font-weight: 700; letter-spacing: -.02em; color: var(--text); text-decoration: none; }
.fbpop__card .fbpop__num:hover { text-decoration: underline; text-decoration-color: var(--gold); }
.fbpop__x { position: absolute; top: .6rem; right: .6rem; width: 40px; height: 40px; border-radius: var(--r); border: 0; background: var(--paper); color: var(--text); cursor: pointer; }

/* ---- scroll reveal ----------------------------------------------------------
   threshold 0 with rootMargin only (app.js), scoped to .js so no-JS visitors and crawlers see
   everything. Opacity and transform only - never display - so nothing can shift layout. Quick:
   the eye should never wait for a section. */
.js [data-rv] { opacity: 0; transform: translateY(26px); }
.js [data-rv].is-in { opacity: 1; transform: none; transition: opacity .7s var(--ease), transform .7s var(--ease); }
@media (prefers-reduced-motion: reduce) {
  .js [data-rv], .js [data-rv="clip"] { opacity: 1; transform: none; clip-path: none; }
  .js [data-rv].is-in { transition: none; }
  .js .hero__copy > *, .js .proof li, .js .proof::before, .js .phero__img, .js .phero__in > * { animation: none; }
  .js .cta:not(.is-in)::before { transform: translateX(-50%); opacity: 1; }
  .flow::after { transition: none; }
}

/* ---- print ------------------------------------------------------------------ */
@media print {
  .hdr, .mnu, .floatbar, .lb, .cta, .fcta, .formcard, .burger, .draftnote, .journey__vis { display: none !important; }
  body { background: #fff; color: #000; }
}

/* ==========================================================================
   3D VARIANT (2026-10-27) - the three.js world. Everything above this line is the classic
   preview's stylesheet, forked unchanged from build/app.css, so every component the shared page
   files use looks the same here; what follows places the scenes and the panels over them.

   CONTRAST over a live render cannot be measured once and trusted, so text never sits on the
   bare scene: the home hero has a scrim sized to the copy, every chapter's words are on a panel
   of rgba(18,22,26,.86) (white on it stays above 10:1 over the brightest sky in the scene),
   labels are dark chips, and the inner-page heroes keep the classic gradient over the canvas.
   With no WebGL 2 every canvas is hidden and the photographs underneath are the page.
   ========================================================================== */

/* ---- the world behind the home page ---------------------------------------- */
.world { position: fixed; inset: 0; z-index: 0; background: var(--ink); overflow: hidden; }
.world__still { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 60% 50%; }
.world__gl { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity .7s var(--ease); }
.world.is-live .world__gl { opacity: 1; }
.world__shade { position: fixed; inset: 0; z-index: 0; pointer-events: none; background: radial-gradient(130% 95% at 55% 42%, rgba(18,22,26,0) 58%, rgba(18,22,26,.42) 100%); }
.w-labels { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.w-label { position: absolute; left: 0; top: 0; margin-top: -12px; padding: .34rem .62rem .36rem; border-radius: 2px; background: rgba(18,22,26,.88); border: 1px solid rgba(220,191,126,.55); color: var(--white); font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; transition: opacity .3s var(--ease); will-change: transform; }
.w-label::after { content: ''; position: absolute; left: 50%; top: 100%; width: 1px; height: 12px; background: rgba(220,191,126,.75); }
.w-label--fault { border-color: var(--gold-2); }

.story { position: relative; z-index: 1; }
.chap { position: relative; display: flex; align-items: center; min-height: 118vh; min-height: 118svh; padding-block: calc(var(--hdr-h) + 2rem) 4rem; color: var(--on-dark); }
.chap__in { width: 100%; }

/* the opening view: the classic hero's copy and proof strip, over the live scene */
.chap--hero { align-items: flex-end; min-height: 100vh; min-height: 100svh; padding-bottom: 0; color: var(--white); }
.chap--hero::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(18,22,26,.88) 0, rgba(18,22,26,.7) calc(max(1.15rem, 50vw - 620px) + 520px), rgba(18,22,26,.16) calc(max(1.15rem, 50vw - 620px) + 900px), rgba(18,22,26,0) calc(max(1.15rem, 50vw - 620px) + 1200px)),
              linear-gradient(0deg, rgba(18,22,26,.96) 0%, rgba(18,22,26,.55) 24%, rgba(18,22,26,0) 48%); }
.chap--hero .chap__in { display: grid; gap: clamp(2.4rem, 7vh, 4.5rem); }
.chap--hero h1 { color: var(--white); }
.chap--hero .btnrow { margin-top: 1.7rem; }
.scroll-cue { position: absolute; left: 50%; bottom: 1.1rem; transform: translateX(-50%); font-size: .66rem; font-weight: 700; letter-spacing: .24em; text-transform: uppercase; color: rgba(243,241,236,.7); padding-bottom: 26px; }
.scroll-cue::after { content: ''; position: absolute; left: 50%; bottom: 0; width: 1px; height: 20px; background: var(--gold); transform-origin: top; animation: cue 1.8s var(--ease) infinite; }
@keyframes cue { 0% { transform: scaleY(0); } 50% { transform: scaleY(1); } 100% { transform: scaleY(1); opacity: 0; } }
@media (max-width: 900px) { .scroll-cue { display: none; } }

/* panels: the chapters' words, on dark glass over the scene */
.panel { position: relative; max-width: 470px; padding: clamp(1.45rem, 2.4vw, 2.1rem); background: rgba(18,22,26,.86); border-top: 2px solid var(--gold); color: var(--on-dark); }
@media (min-width: 901px) { .panel { -webkit-backdrop-filter: blur(14px) saturate(1.15); backdrop-filter: blur(14px) saturate(1.15); } }
.panel--wide { max-width: 660px; }
.chap--r .panel { margin-left: auto; }
.panel h2, .panel h3 { color: var(--white); }
.panel h3 { font-size: clamp(1.5rem, 2.4vw, 2rem); line-height: 1.1; }
.panel h3 a { color: inherit; text-decoration: none; }
.panel h3 a:hover { text-decoration: underline; text-decoration-color: var(--gold); text-underline-offset: 6px; }
.panel .eyebrow { color: var(--gold-2); }
.panel .lead { margin-top: 1rem; color: var(--on-dark-2); }
.panel p { color: var(--on-dark); }
.panel .tlink { color: var(--gold-2); }
.panel .tlink:hover { color: var(--white); }
.panel .svc__tag { margin-top: .6rem; font-size: clamp(1.1rem, 1.6vw, 1.32rem); font-weight: 600; line-height: 1.3; letter-spacing: -.01em; color: var(--gold-2); }
.panel .svc__tag + p { margin-top: 1rem; }
.panel .btnrow { margin-top: 1.5rem; }
.panel__n { display: block; margin: 0 0 .55rem; font-size: clamp(2.4rem, 3.4vw, 3.1rem); font-weight: 800; line-height: .9; letter-spacing: -.03em; color: rgba(18,22,26,.86); -webkit-text-stroke: 1.5px var(--gold); paint-order: stroke fill; }
.panel__img { position: relative; margin: calc(-1 * clamp(1.45rem, 2.4vw, 2.1rem)) calc(-1 * clamp(1.45rem, 2.4vw, 2.1rem)) 1.4rem; aspect-ratio: 16 / 8; overflow: hidden; background: var(--ink-2); }
.panel__img img { width: 100%; height: 100%; object-fit: cover; }

/* the ten stages: one short panel per stage, the build follows the reader down the list */
.chap--stages { display: block; min-height: 0; padding-bottom: 0; }
.chap__in--head { min-height: 64vh; display: flex; align-items: center; }
.bsteps { list-style: none; margin: 0; padding: 0 0 18vh; }
.bstep { display: flex; align-items: center; min-height: 72vh; }
.bstep > .wrap { width: 100%; }
.panel--step { max-width: 430px; display: grid; gap: .25rem; padding: 1.3rem 1.6rem 1.45rem; transition: opacity .45s var(--ease), border-color .45s var(--ease); }
.js .bstep:not(.is-active) .panel--step { opacity: .62; }
.bstep.is-done .panel--step { border-top-color: rgba(200,165,91,.55); }
.panel--step .steps__n { display: block; font-size: 2.8rem; font-weight: 800; line-height: 1; letter-spacing: -.03em; color: rgba(18,22,26,.86); -webkit-text-stroke: 1.5px var(--gold); paint-order: stroke fill; }
.panel--step .steps__t { margin-top: .55rem; font-size: 1.15rem; }
.panel--step .steps__d { font-size: 1rem; color: var(--on-dark); }
.brail { position: fixed; right: clamp(.8rem, 2vw, 1.6rem); top: 50%; transform: translateY(-50%); z-index: 5; list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; opacity: 0; pointer-events: none; transition: opacity .4s var(--ease); }
.in-stages .brail { opacity: 1; }
.brail li { display: flex; align-items: center; gap: .5rem; padding: .2rem .5rem; background: rgba(18,22,26,.72); font-size: .68rem; font-weight: 700; letter-spacing: .1em; color: rgba(243,241,236,.62); }
.brail li::before { content: ''; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid rgba(220,191,126,.75); transition: background .3s var(--ease), box-shadow .3s var(--ease); }
.brail li.is-done { color: var(--gold-2); }
.brail li.is-done::before { background: var(--gold); border-color: var(--gold); }
.brail li.is-active { color: var(--white); }
.brail li.is-active::before { background: var(--gold-2); border-color: var(--gold-2); box-shadow: 0 0 0 3px rgba(220,191,126,.3); }
.chap--outro .outro { margin-top: 0; padding-top: clamp(1.45rem, 2.4vw, 2.1rem); border-top: 2px solid var(--gold); }
.chap--outro .outro p { color: var(--on-dark-2); }

/* what the scene is showing, bottom left */
.readout { position: fixed; left: var(--gut); bottom: 1.1rem; z-index: 5; display: flex; flex-wrap: wrap; gap: .45rem; pointer-events: none; transition: opacity .4s var(--ease); }
.readout span { padding: .36rem .62rem; background: rgba(18,22,26,.8); color: var(--on-dark); font-size: .66rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; }
.readout__live { display: inline-flex; align-items: center; gap: .45rem; color: var(--gold-2) !important; }
.readout__live::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--gold-2); animation: livedot 1.6s ease-in-out infinite; }
@keyframes livedot { 50% { opacity: .25; } }
.readout__now:empty { display: none; }
.at-top .readout, .world-off .readout, .world-off .brail { opacity: 0; }
@media (max-width: 900px) { .readout, .brail { display: none; } }

/* Our Work and Our Company are solid; Let's talk is a last window onto the world, at dusk */
.solid { position: relative; z-index: 1; background: var(--paper); }
.cta--world { z-index: 1; display: flex; align-items: center; min-height: 92vh; min-height: 92svh; background-color: transparent;
  background-image: linear-gradient(90deg, rgba(18,22,26,.9) 0, rgba(18,22,26,.74) calc(max(1.15rem, 50vw - 620px) + 560px), rgba(18,22,26,.15) calc(max(1.15rem, 50vw - 620px) + 980px), rgba(18,22,26,0) 100%),
                    linear-gradient(0deg, rgba(18,22,26,.6) 0%, rgba(18,22,26,0) 30%); }
.cta--world .cta__in { width: 100%; }
.ftr { position: relative; z-index: 1; }

@media (max-width: 900px) {
  .chap { align-items: flex-end; min-height: 108vh; min-height: 108svh; padding-bottom: 1.4rem; }
  /* the scene keeps the top of a phone's screen; the copy starts below it */
  .chap--hero { min-height: 100vh; min-height: 100svh; padding-top: 40vh; padding-top: 40svh; padding-bottom: 0; }
  .panel { background: rgba(18,22,26,.93); }
  .chap--hero::before { background: linear-gradient(0deg, rgba(18,22,26,.97) 0%, rgba(18,22,26,.9) 52%, rgba(18,22,26,.35) 74%, rgba(18,22,26,0) 90%); }
  .panel, .panel--wide { max-width: none; }
  .chap--r .panel { margin-left: 0; }
  .panel__img { aspect-ratio: 2 / 1; }
}
@media (max-width: 600px) {
  /* on a phone the panel would cover the scene; the photographs are on the service pages */
  .panel__img { display: none; }
  .bstep { min-height: 64vh; align-items: flex-end; }
  .chap__in--head { min-height: 74vh; align-items: flex-end; }
  .cta--world { align-items: flex-end; background-image: linear-gradient(0deg, rgba(18,22,26,.96) 0%, rgba(18,22,26,.88) 55%, rgba(18,22,26,.2) 82%, rgba(18,22,26,0) 100%); }
}

/* ---- the inner-page heroes: a scene in place of the photograph ------------------ */
.phero__gl { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -2; opacity: 0; transition: opacity .7s var(--ease); }
.phero--gl .phero__img { z-index: -3; }
.phero--gl.is-live .phero__gl { opacity: 1; }
.phero--gl::before { content: ''; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, rgba(18,22,26,.94) 0, rgba(18,22,26,.84) calc(max(1.15rem, 50vw - 620px) + 520px), rgba(18,22,26,.3) calc(max(1.15rem, 50vw - 620px) + 920px), rgba(18,22,26,.06) 100%),
              linear-gradient(0deg, rgba(18,22,26,.9) 0%, rgba(18,22,26,.3) 34%, rgba(18,22,26,0) 66%); }
.phero--gl .phero__in { min-height: min(74vh, 780px); min-height: min(74svh, 780px); display: flex; flex-direction: column; justify-content: flex-end; }
.gl-tag { position: absolute; z-index: 2; top: calc(var(--hdr-h) + .9rem); right: var(--gut); padding: .34rem .62rem; background: rgba(18,22,26,.8); border: 1px solid rgba(220,191,126,.42); color: var(--gold-2); font-size: .64rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; pointer-events: none; }
@media (max-width: 900px) {
  .phero--gl::before { background: linear-gradient(0deg, rgba(18,22,26,.97) 0%, rgba(18,22,26,.93) 56%, rgba(18,22,26,.3) 80%, rgba(18,22,26,0) 96%); }
  .phero--gl .phero__in { min-height: 0; padding-top: 38vh; padding-top: 38svh; }
}

/* ---- the development journey, the asset-care and mapping viewers ---------------- */
.journey__vis--gl canvas { cursor: grab; opacity: 0; transition: opacity 1s var(--ease); }
.journey__vis--gl .gl-tag, .viewer .gl-tag { top: .8rem; right: .8rem; }
.viewer { position: relative; aspect-ratio: 16 / 8; margin-bottom: clamp(2.2rem, 4vw, 3.2rem); background: var(--ink); overflow: hidden; border-top: 2px solid var(--gold); }
.viewer canvas { width: 100%; height: 100%; cursor: grab; opacity: 0; transition: opacity 1s var(--ease); }
.viewer.is-live canvas, .journey__vis--gl.is-live canvas { opacity: 1; }
@media (max-width: 760px) { .viewer { aspect-ratio: 1 / 0.9; margin-inline: calc(-1 * var(--gut)); } }
.flow__btn { display: block; width: 100%; padding: 0 0 .25rem; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.flow__btn:hover strong { color: var(--white); }
.flow--steps.is-live li::before { transition: background .3s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease); }
.flow--steps.is-live li.is-past::before { background: var(--gold); }
.flow--steps.is-live li.is-on::before { background: var(--gold-2); border-color: var(--gold-2); box-shadow: 0 0 0 5px rgba(220,191,126,.24); transform: scale(1.15); }
.flow--steps.is-live li.is-on strong { color: var(--white); }

/* ---- the photograph under a hero scene is ONLY the no-WebGL / no-script picture -------
   It is never the first paint: a photograph that is then swapped for the scene reads as the
   wrong image loading first (Richard, 2026-10-30). With script the hero opens on charcoal with
   its words and the scene fades up; the photograph is display:none and lazy, so it is not even
   downloaded unless app.js finds no WebGL 2 or the scene fails (it adds .no-webgl). */
.js .world__still, .js .phero--gl .phero__img { display: none; }
.js.no-webgl .world__still, .js.no-webgl .phero--gl .phero__img { display: block; }

/* ---- no WebGL 2: the photographs are the page ------------------------------------ */
.no-webgl .world__gl, .no-webgl .phero__gl, .no-webgl .gl-tag, .no-webgl .readout, .no-webgl .brail, .no-webgl .viewer, .no-webgl .journey__vis--gl { display: none !important; }
.no-webgl .journey__grid { grid-template-columns: 1fr; }

/* ==========================================================================
   THE REVISED BRIEF (2026-10-29) - the look the client asked for in Capsule note 492710478
   (_source/brief/brief-2026-10-26.txt, sections 1 and 2): "Charcoal backgrounds and subtle gold
   details. More refined typography. Large photographs ... Short, clear headings. Less text and
   fewer repetitive layouts. Some lighter sections are fine, but the cream background currently
   dominates too much", with Maguire Aerial Mapping as the visual reference - and a simpler
   phone: a lower header, no heading taking over the first screen, crops that work for people,
   smaller gaps, a chat button that does not sit on text.

   Everything below overrides what is above it. The page is charcoal now: the old LIGHT tokens
   are redefined as dark ones, so every component that read --paper, --text, --muted, --bronze
   or --line follows without being rewritten. One lighter surface remains (.sec--stone), which
   puts the light values back for whatever is inside it.
   ========================================================================== */
:root {
  --paper: #12161a;          /* the page: charcoal (was cream) */
  --paper-2: #1a2026;
  --text: #f3f1ec;
  --muted: #b9c0c6;
  --line: #2f373e;
  --bronze: #dcbf7e;         /* "gold text": on charcoal it is gold-2 */
  --err: #ff9a8a;            /* form errors, on the dark form */
  --deep: #0c0f12;           /* the darker band: footer, the sister-company strip, the process */
  /* the one light surface */
  --stone: #ebe8e1;
  --stone-text: #1c2227;
  --stone-muted: #4f5962;
  --stone-bronze: #765d2c;
  --stone-line: #cfc9bc;
  --hdr-h: 76px;
}
body { background: var(--paper); color: var(--text); }

/* ---- type: lighter, uppercase, tracked headings (the Aerial Mapping site's way) ---- */
h1, h2 { font-weight: 400; text-transform: uppercase; letter-spacing: .035em; line-height: 1.08; }
h1 { font-size: clamp(2rem, 4.6vw, 4.1rem); line-height: 1.04; }
h1[data-len="long"] { font-size: clamp(1.8rem, 3.8vw, 3.3rem); }
h1[data-len="xlong"] { font-size: clamp(1.6rem, 3.1vw, 2.6rem); }
h2 { font-size: clamp(1.45rem, 2.6vw, 2.35rem); letter-spacing: .04em; }
h2[data-len="long"] { font-size: clamp(1.35rem, 2.3vw, 2rem); }
h2[data-len="xlong"] { font-size: clamp(1.25rem, 2vw, 1.7rem); line-height: 1.16; }
h3 { font-weight: 600; letter-spacing: .005em; }
.lead--big { font-size: clamp(1.2rem, 2vw, 1.6rem); line-height: 1.5; color: var(--text); font-weight: 300; }

/* eyebrows: a short gold rule, then small tracked capitals */
.eyebrow, .eyebrow[data-len] { display: flex; align-items: center; gap: .85rem; font-size: .72rem; font-weight: 600; letter-spacing: .24em; line-height: 1.4; text-transform: uppercase; color: var(--gold-2); margin-bottom: 1.1rem; }
.eyebrow::before { content: ''; flex: none; width: 30px; height: 1px; background: var(--gold); }
.eyebrow::after { display: none; }

/* a quieter link for "All projects" */
.tlink--quiet { font-size: .74rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; text-decoration: none; padding-bottom: .25rem; border-bottom: 1px solid var(--gold); color: var(--gold-2); }
.tlink--quiet:hover { color: var(--white); }

/* ---- buttons: small tracked capitals, a fine border ---- */
.btn { min-height: 50px; padding: .8rem 1.45rem; border-width: 1px; font-size: .76rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.btn--sm { min-height: 42px; padding: .5rem 1rem; font-size: .7rem; }
.btn--line { background: transparent; color: var(--text); border-color: rgba(220,191,126,.62); }
.btn--line:hover, .sec--dark .btn--line:hover, .cta .btn--line:hover, .phero .btn--line:hover, .mnu .btn--line:hover { background: var(--gold-2); border-color: var(--gold-2); color: var(--ink); }

/* ---- sections: less air between them, a darker band for rhythm ---- */
.sec { padding-block: clamp(3.2rem, 7vw, 6.5rem); }
.sec--flush { padding-top: clamp(1.4rem, 3vw, 2.4rem); }
.sec--intro { padding-block: clamp(2.6rem, 5vw, 4.5rem) clamp(1.2rem, 2.4vw, 2rem); }
.sec--dark { background-color: var(--deep); }
.sec__head--row { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem 2rem; max-width: none; }
.note--quiet { margin-top: 1.6rem; padding: .15rem 0 .15rem 1rem; border-left: 2px solid var(--gold); background: none; color: var(--on-dark-2); font-size: .95rem; }
.solid { background: var(--paper); }

/* the one light section */
.sec--stone { --text: var(--stone-text); --muted: var(--stone-muted); --bronze: var(--stone-bronze); --line: var(--stone-line); background: var(--stone); color: var(--text); }
.sec--stone :focus-visible { outline-color: var(--stone-bronze); }
.sec--stone .eyebrow { color: var(--stone-bronze); }
.sec--stone .btn--line { color: var(--stone-text); border-color: var(--stone-text); }

/* ---- header: lower, quieter ---- */
.nav a { font-size: .74rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; }
.nav__menu a { font-size: .9rem; letter-spacing: .02em; text-transform: none; }
.hdr__logo img { --logo-h: 46px; }
.hdr__tel { font-size: .84rem; letter-spacing: .05em; }
.mnu__top { min-height: var(--hdr-h); }
.mnu a:not(.btn):not(.hdr__logo) { font-size: 1.05rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; }
@media (max-width: 1100px) { :root { --hdr-h: 64px; } .hdr__logo img { --logo-h: 38px; } }
@media (max-width: 760px) {
  :root { --hdr-h: 58px; }
  .hdr__logo img { --logo-h: 33px; }
  .hdr__cta { gap: .55rem; }
  .burger { width: 42px; height: 42px; }
  .burger span { top: 19px; left: 10px; right: 10px; }
  .hdr::before { height: calc(var(--hdr-h) + 36px); }
  .mnu__close { width: 42px; height: 42px; }
}
@media (max-width: 420px) { .hdr__tel { width: 42px; height: 42px; } .hdr__tel svg { width: 18px; height: 18px; } }

/* ---- home: the opening - one visual, one headline, one line, one button ---- */
/* Each window is its own stacking context above the fixed world (z-index 0). Without it a
   chapter's scrim (::before, z-index -1) is painted UNDER the world and the headline sits on the
   bare render - which is what happened when the chapters stopped living inside .story. */
.chap { z-index: 1; }
.chap--hero .hero__copy { max-width: 780px; }
.chap--hero .hero__lead { margin-top: 1.2rem; font-size: clamp(1.02rem, 1.6vw, 1.3rem); font-weight: 500; letter-spacing: .06em; text-transform: uppercase; color: var(--on-dark); }
.chap--hero .chap__in { padding-bottom: clamp(3rem, 9vh, 6rem); }
@media (max-width: 900px) {
  /* the scene keeps most of a phone's first screen; the words sit low, clear of the chat button */
  .chap--hero { padding-top: 56vh; padding-top: 56svh; }
  .chap--hero .chap__in { padding-bottom: 4.6rem; }
  .chap--hero h1 { font-size: clamp(1.6rem, 7vw, 2.3rem); }
  .chap--hero::before { background: linear-gradient(0deg, rgba(18,22,26,.95) 0%, rgba(18,22,26,.82) 30%, rgba(18,22,26,.3) 48%, rgba(18,22,26,0) 60%); }
  .chap--svc { min-height: 96vh; min-height: 96svh; }
}
.panel h2 { font-size: clamp(1.35rem, 2.2vw, 1.85rem); color: var(--white); }
.panel h2 a { color: inherit; text-decoration: none; }
.panel h2 a:hover { text-decoration: underline; text-decoration-color: var(--gold); text-underline-offset: 6px; }
.panel h2 + p { margin-top: .9rem; }
@media (max-width: 600px) { .chap--svc .panel__img { display: block; aspect-ratio: 16 / 9; } }

/* project cards (Our Work, related projects): photographs first, words under them */
.wcards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(2.2rem, 4vw, 3.2rem) clamp(1.2rem, 2.5vw, 2rem); }
.wcard { position: relative; }
.wcard[hidden] { display: none; }
.wcard__img { aspect-ratio: 3 / 2; overflow: hidden; background: var(--ink-2); }
.wcard__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .8s var(--ease); }
.wcard:hover .wcard__img img { transform: scale(1.035); }
.wcard__body { padding-top: 1.1rem; }
.wcard__meta { font-size: .7rem; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: var(--gold-2); }
.wcard h3 { margin-top: .45rem; font-size: clamp(1.1rem, 1.5vw, 1.35rem); font-weight: 500; letter-spacing: .05em; text-transform: uppercase; }
.wcard h3 a { color: var(--text); text-decoration: none; }
.wcard h3 a::after { content: ''; position: absolute; inset: 0; }
.wcard:hover h3 a { color: var(--gold-2); }
.wcard__sum { margin-top: .45rem; max-width: 62ch; font-size: .96rem; color: var(--muted); }
@media (max-width: 760px) {
  .wcards { grid-template-columns: 1fr; }
  .wcard__img { aspect-ratio: 4 / 3; }
}
@media (prefers-reduced-motion: reduce) { .wcard__img img { transition: none; } .wcard:hover .wcard__img img { transform: none; } }

/* the family: the team photograph full width, the words beneath it - over nobody's face */
.family__img { height: clamp(300px, 44vw, 78vh); overflow: hidden; background: var(--ink-2); }
.family__img img { width: 100%; height: 100%; object-fit: cover; }
.family__in { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.2rem 4rem; align-items: start; padding-block: clamp(2.2rem, 4.5vw, 3.6rem) clamp(3rem, 6vw, 5rem); }
.family__in .lead { color: var(--on-dark-2); }
.family__in .btnrow { margin-top: 1.4rem; }
@media (max-width: 760px) { .family__img { height: auto; aspect-ratio: 3 / 2; } .family__in { grid-template-columns: 1fr; } }

/* the sister company: a slim strip, not a section */
.sister { background: var(--deep); border-block: 1px solid rgba(220,191,126,.2); }
.sister__in { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.2rem 3rem; align-items: center; padding-block: clamp(1.8rem, 3.6vw, 2.6rem); }
.sister h2 { font-size: clamp(1.1rem, 1.7vw, 1.45rem); }
.sister p { margin-top: .45rem; max-width: 660px; color: var(--on-dark-2); }
@media (max-width: 760px) { .sister__in { grid-template-columns: 1fr; } }

/* each page's one closing section */
.cta .cta__small { margin-top: 1.5rem; font-size: .95rem; color: var(--on-dark-2); }
@media (max-width: 760px) { .cta__in { padding-block: 3rem 3.8rem; } .cta--world { min-height: 80vh; min-height: 80svh; } }

/* ---- inner-page heroes ---------------------------------------------------------------
   A photograph hero keeps the photograph visible: a lighter scrim on the copy's side only. On a
   phone the words go UNDER the photograph instead of over it, and the photograph starts below
   the header, so heads are never under the bar. */
.phero--img:not(.phero--gl)::before {
  background: linear-gradient(90deg, rgba(12,15,18,.84) 0%, rgba(12,15,18,.6) 34%, rgba(12,15,18,0) 62%),
              linear-gradient(0deg, rgba(12,15,18,.88) 0%, rgba(12,15,18,.4) 30%, rgba(12,15,18,0) 56%); }
.phero--img:not(.phero--gl) .phero__in { min-height: min(76vh, 800px); min-height: min(76svh, 800px); }
@media (max-width: 760px) {
  .phero--img:not(.phero--gl) { padding-top: var(--hdr-h); }
  .phero--img:not(.phero--gl)::before { display: none; }
  .phero--img:not(.phero--gl) .phero__img { position: relative; inset: auto; z-index: 0; height: auto; aspect-ratio: 4 / 3; }
  .phero--img:not(.phero--gl) .phero__in { min-height: 0; padding-block: 1.6rem 2.2rem; }
  img[style*="--mpos"] { object-position: var(--mpos) !important; }
}

/* a team photograph hero: the photograph across the top, the heading below it */
.phero--photo { padding-top: var(--hdr-h); }
.phero__media { position: relative; height: clamp(260px, 44vw, calc(100vh - var(--hdr-h) - 13rem)); overflow: hidden; background: var(--ink-2); }
.phero--photo .phero__img { z-index: 0; }
.phero--photo .phero__in { max-width: 920px; padding-block: clamp(1.6rem, 3.6vw, 2.8rem) clamp(2.2rem, 4.5vw, 3.6rem); }
@media (max-width: 760px) { .phero__media { height: auto; aspect-ratio: 3 / 2; } }

/* the 3D heroes on a phone: a little less of the screen before the words */
@media (max-width: 900px) { .phero--gl .phero__in { padding-top: 34vh; padding-top: 34svh; } }

/* ---- development: the ten stages -------------------------------------------------------
   All ten at once, each with its own photograph and nothing to click (the client, 2026-11-02,
   Capsule 493278350: "The 10 stages should have the correct images, and they should not be
   clickable"). Five across on a desktop, two on a tablet, and on a phone one row each: the
   photograph on the left, the number, name and line beside it. */
.stages { list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(2rem, 3vw, 2.6rem) clamp(1rem, 1.6vw, 1.5rem); margin-top: 1.4rem; }
.stg__img { margin: 0 0 1rem; aspect-ratio: 4 / 3; overflow: hidden; background: var(--ink-2); }
.stg__img img { width: 100%; height: 100%; object-fit: cover; }
.stg__h { display: flex; align-items: baseline; gap: .65rem; margin: 0; font-size: .92rem; font-weight: 500; letter-spacing: .08em; line-height: 1.35; text-transform: uppercase; color: var(--text); }
.stg__n { flex: none; font-size: .74rem; font-weight: 600; letter-spacing: .14em; color: var(--gold-2); }
.stg p { margin-top: .5rem; font-size: .92rem; line-height: 1.55; color: var(--muted); }
@media (max-width: 1100px) { .stages { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 600px) {
  .stages { grid-template-columns: 1fr; gap: 1.3rem; }
  .stg { display: grid; grid-template-columns: minmax(0, 40%) minmax(0, 1fr); column-gap: 1rem; align-items: start; }
  .stg__img { grid-row: 1 / span 2; margin: 0; }
  .stg p { margin-top: .35rem; font-size: .9rem; }
}

/* "From our work" (development) and "Repair work" (asset care): two photographs and a button to
   Our Work, no words (the client, 2026-11-02). build.mjs workPics. */
.wpics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(.8rem, 1.6vw, 1.4rem); margin-top: 1.2rem; }
.wpics__img { margin: 0; aspect-ratio: 3 / 2; overflow: hidden; background: var(--ink-2); }
.wpics__img img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 600px) { .wpics { grid-template-columns: 1fr; } }

/* ---- asset care ------------------------------------------------------------------------ */
/* what we look after: four tall photographs in a row on a desktop, two on a tablet, one on a phone */
.looks { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(2rem, 3.5vw, 3rem) clamp(1rem, 2vw, 1.6rem); }
.look__img { aspect-ratio: 3 / 4; overflow: hidden; margin-bottom: 1.1rem; background: var(--ink-2); }
.look__img img { width: 100%; height: 100%; object-fit: cover; }
.look h3 { font-size: 1rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; }
.look p { margin-top: .5rem; font-size: .96rem; color: var(--muted); }
@media (max-width: 1000px) { .looks { grid-template-columns: repeat(2, minmax(0, 1fr)); } .look__img { aspect-ratio: 4 / 3; } }
@media (max-width: 600px) { .looks { grid-template-columns: 1fr; } .look__img { aspect-ratio: 3 / 2; } }
.process__notes { display: grid; gap: .8rem; max-width: 780px; margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.6rem; border-top: 1px solid rgba(255,255,255,.12); }
.process__notes p { margin: 0; color: var(--on-dark-2); }
.sec--dark .process__notes .kicker { color: var(--white) !important; font-size: clamp(1.05rem, 1.5vw, 1.25rem); font-weight: 500; }
/* ongoing maintenance: a full-width photograph with the words on a panel over its lower edge */
.ongoing { position: relative; padding-bottom: clamp(3rem, 6vw, 5rem); }
.ongoing__img { height: clamp(320px, 62vh, 680px); }
.ongoing .wrap { position: relative; margin-top: clamp(-11rem, -12vw, -5rem); }
.ongoing__card { max-width: 640px; margin-left: auto; padding: clamp(1.6rem, 3vw, 2.6rem); background: var(--ink-2); border-top: 2px solid var(--gold); }
.ongoing__card h2 + p { margin-top: 1rem; }
.ongoing__card p { color: var(--on-dark-2); }
@media (max-width: 760px) { .ongoing__img { height: 260px; } .ongoing .wrap { margin-top: -2.5rem; } }

/* ---- our company ------------------------------------------------------------------------- */
.story { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: 1.4rem 4rem; align-items: start; }
.story .lead { margin: 0; color: var(--text); }
@media (max-width: 760px) { .story { grid-template-columns: 1fr; } }
.team { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(2rem, 3.5vw, 3rem) clamp(1.1rem, 2.2vw, 1.8rem); }
.mate__img { aspect-ratio: 4 / 5; overflow: hidden; background: var(--ink-2); }
.mate__img img { width: 100%; height: 100%; object-fit: cover; }
.mate__body { padding-top: 1rem; }
.mate h3 { font-size: 1.05rem; font-weight: 500; letter-spacing: .07em; text-transform: uppercase; }
.mate__role { margin-top: .3rem; font-size: .68rem; font-weight: 600; letter-spacing: .18em; line-height: 1.5; text-transform: uppercase; color: var(--gold-2); }
.mate__role + p { margin-top: .8rem; }
.mate p:not(.mate__role) { font-size: .94rem; line-height: 1.6; color: var(--muted); }
@media (max-width: 1000px) { .team { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* phones: everyone stacked, a headshot beside each name - nothing to swipe */
@media (max-width: 640px) {
  .team { grid-template-columns: 1fr; gap: 1.6rem; }
  .mate { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: 1rem; align-items: start; }
  .mate__body { padding-top: .2rem; }
}
.ways { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem clamp(1.6rem, 3vw, 3rem); }
.way { padding-top: 1.2rem; border-top: 1px solid rgba(220,191,126,.35); }
.way h3 { font-size: 1rem; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--white); }
.way p { margin-top: .6rem; color: var(--on-dark-2); }
@media (max-width: 760px) { .ways { grid-template-columns: 1fr; gap: 1.4rem; } }

/* ---- a project page (build.mjs projectMain3d) ----------------------------------------------- */
.phero--proj .phero__in { min-height: min(84vh, 880px); min-height: min(84svh, 880px); }
.pintro__grid { align-items: center; }
.pintro__body { grid-column: 2 / 7; padding-right: clamp(1rem, 3vw, 3.5rem); }
.pintro__body p:not(.todo) { color: var(--on-dark-2); }
.pintro__img { grid-column: 7 / 15; aspect-ratio: 5 / 4; overflow: hidden; background: var(--ink-2); }
.pintro__img img { width: 100%; height: 100%; object-fit: cover; }
.psum { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem 1.4rem; margin-top: 1.8rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
.psum dt { font-size: .66rem; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--gold-2); }
.psum dd { margin: .35rem 0 0; font-size: .95rem; color: var(--text); }
.todo { background: var(--ink-2); }
@media (max-width: 860px) {
  .pintro__body { grid-column: 2 / 14; padding: 0; }
  .pintro__img { grid-column: 1 / 15; margin-top: 1.8rem; aspect-ratio: 3 / 2; }
  .psum { grid-template-columns: 1fr 1fr; }
}
/* the gallery: full width, a pair, then a tall one beside a wide one, and again */
.pgal { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: clamp(.5rem, 1vw, .9rem); }
.pgal .gal__b { display: block; aspect-ratio: 4 / 3; }
.pgal .gal__b img { width: 100%; height: 100%; object-fit: cover; }
.pgal .gal__b--w { grid-column: span 6; aspect-ratio: 21 / 9; }
.pgal .gal__b--p { grid-column: span 3; }
.pgal .gal__b--t { grid-column: span 2; aspect-ratio: 4 / 5; }
.pgal .gal__b--l { grid-column: span 4; aspect-ratio: 8 / 5; }
@media (max-width: 760px) {
  .pgal { grid-template-columns: 1fr; gap: .7rem; }
  .pgal .gal__b--w, .pgal .gal__b--p, .pgal .gal__b--l { grid-column: auto; aspect-ratio: 3 / 2; }
  .pgal .gal__b--t { grid-column: auto; aspect-ratio: 4 / 5; }
}

/* ---- Our Work filters ---- */
.pfilter a { border: 1px solid rgba(220,191,126,.45); font-size: .72rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--text); }
.pfilter a:hover { background: var(--ink-2); }
.pfilter a[aria-current="true"] { background: var(--gold); border-color: var(--gold); color: var(--ink); }

/* ---- the form, on charcoal ---- */
.formcard { background: var(--ink-2); }
.f-input, .f-select, .f-textarea, .f-file { background: var(--deep); color: var(--on-dark); border-color: #6b757e; }
.f-select option { background: var(--ink); color: var(--on-dark); }
.f-file::file-selector-button { background: var(--ink-3); color: var(--on-dark); border-color: var(--on-dark-2); }
.f-input:focus, .f-select:focus, .f-textarea:focus { border-color: var(--gold-2); }
.f-msg--err { background: rgba(255,154,138,.1); color: var(--err); border-color: rgba(255,154,138,.4); }
.f-msg--ok { background: rgba(120,210,150,.1); color: #9fe0b4; border-color: rgba(120,210,150,.35); }

/* ---- footer ---- */
.ftr { background: var(--deep); }
.ftr__sister { margin-top: .9rem; font-size: .9rem; }
.ftr .ftr__sister a { color: var(--gold-2); }

/* ---- the floating contact button: smaller, dark glass, a fine gold ring (the Aerial Mapping
   site's), and on a phone it steps aside while the reader scrolls down (app.js) ---- */
.floatbar { right: 18px; bottom: 18px; gap: 8px; transition: transform .35s var(--ease), opacity .3s var(--ease); }
.floatbar__btn, .floatbar__toggle { width: 46px; height: 46px; background: rgba(12,15,18,.9); color: var(--gold-2); border: 1px solid rgba(220,191,126,.72); box-shadow: 0 6px 22px rgba(0,0,0,.35); }
.floatbar__btn svg, .floatbar__toggle svg { width: 19px; height: 19px; }
.floatbar__toggle:hover, .floatbar[data-open] .floatbar__toggle, .floatbar[data-open] .floatbar__btn:hover { background: var(--gold); color: var(--ink); border-color: var(--gold); }
.floatbar.is-away { transform: translateY(calc(100% + 30px)); opacity: 0; visibility: hidden; transition: transform .35s var(--ease), opacity .3s var(--ease), visibility 0s linear .35s; }
@media (max-width: 560px) { .floatbar { right: 12px; bottom: 12px; } .floatbar__btn, .floatbar__toggle { width: 44px; height: 44px; } }
@media (prefers-reduced-motion: reduce) { .floatbar, .floatbar.is-away { transition: none; } }
.fbpop__card { background: var(--ink-2); }
.fbpop__x { background: var(--ink-3); color: var(--on-dark); }

/* ---- the Gallery (2026-11-11) ------------------------------------------------------------------
   The client, Capsule 493991374: Our Work becomes "Gallery", "a crisp gallery" with the three
   filters and no words. Justified rows: each tile grows in proportion to its photograph's aspect
   ratio (--r, written by build.mjs galleryGrid), so every row is one height from edge to edge and
   no photograph is cropped. The empty ::after takes the last row's spare width, so that row keeps
   its natural height instead of being stretched to fill. A hidden tile (a filter) simply drops
   out and the rows close up. */
.wrap--gal { max-width: calc(1560px + var(--gut) * 2); }
.ghead { padding-top: calc(var(--hdr-h) + clamp(1.8rem, 4.5vw, 3.6rem)); padding-bottom: clamp(1.2rem, 2.4vw, 2rem); }
.ghead h1 { margin-bottom: clamp(1.1rem, 2.4vw, 1.7rem); }
.ghead .pfilter { margin-bottom: 0; }
.gsec { padding-bottom: clamp(3.2rem, 7vw, 6.5rem); }
.jgal { --h: clamp(160px, calc((min(100vw, 1640px) - 80px) / 5.4), 290px); display: flex; flex-wrap: wrap; align-items: flex-start; gap: clamp(4px, .55vw, 8px); }
.jgal::after { content: ''; flex: 1000000 1 0px; }
.jgal__b { position: relative; display: block; min-width: 0; flex: calc(var(--r) * 100) 1 calc(var(--r) * var(--h)); aspect-ratio: var(--r); }
.jgal__b[hidden] { display: none; }
.jgal__b img { display: block; width: 100%; height: 100%; object-fit: cover; }
.jgal__b:focus-visible { outline-offset: -3px; }
/* about three and a half landscape photographs to a row on a desktop or tablet (the row height
   follows the content width), about two on a phone */
@media (max-width: 600px) { .jgal { --h: calc((100vw - 2 * var(--gut)) / 3.2); gap: 4px; } }
